OSDN Git Service

drm_hwcomposer: Disable unused planes
[android-x86/external-drm_hwcomposer.git] / drmdisplaycomposition.cpp
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #define LOG_TAG "hwc-drm-display-composition"
18
19 #include "drmdisplaycomposition.h"
20 #include "drmcrtc.h"
21 #include "drmplane.h"
22 #include "drmresources.h"
23
24 #include <stdlib.h>
25
26 #include <cutils/log.h>
27 #include <sw_sync.h>
28 #include <sync/sync.h>
29 #include <xf86drmMode.h>
30
31 namespace android {
32
33 DrmCompositionLayer::DrmCompositionLayer() : crtc(NULL), plane(NULL) {
34   memset(&layer, 0, sizeof(layer));
35   layer.acquireFenceFd = -1;
36   memset(&bo, 0, sizeof(bo));
37 }
38
39 DrmCompositionLayer::~DrmCompositionLayer() {
40 }
41
42 DrmDisplayComposition::DrmDisplayComposition()
43     : drm_(NULL),
44       importer_(NULL),
45       type_(DRM_COMPOSITION_TYPE_EMPTY),
46       timeline_fd_(-1),
47       timeline_(0),
48       dpms_mode_(DRM_MODE_DPMS_ON) {
49 }
50
51 DrmDisplayComposition::~DrmDisplayComposition() {
52   for (DrmCompositionLayerVector_t::iterator iter = layers_.begin();
53        iter != layers_.end(); ++iter) {
54     if (importer_ && iter->bo.fb_id)
55       importer_->ReleaseBuffer(&iter->bo);
56
57     if (iter->layer.acquireFenceFd >= 0)
58       close(iter->layer.acquireFenceFd);
59   }
60
61   if (timeline_fd_ >= 0)
62     close(timeline_fd_);
63 }
64
65 int DrmDisplayComposition::Init(DrmResources *drm, Importer *importer) {
66   drm_ = drm;
67   importer_ = importer;
68
69   int ret = sw_sync_timeline_create();
70   if (ret < 0) {
71     ALOGE("Failed to create sw sync timeline %d", ret);
72     return ret;
73   }
74   timeline_fd_ = ret;
75   return 0;
76 }
77
78 DrmCompositionType DrmDisplayComposition::type() const {
79   return type_;
80 }
81
82 bool DrmDisplayComposition::validate_composition_type(DrmCompositionType des) {
83   return type_ == DRM_COMPOSITION_TYPE_EMPTY || type_ == des;
84 }
85
86 int DrmDisplayComposition::AddLayer(hwc_layer_1_t *layer, hwc_drm_bo_t *bo,
87                                     DrmCrtc *crtc, DrmPlane *plane) {
88   if (layer->transform != 0)
89     return -EINVAL;
90
91   if (!validate_composition_type(DRM_COMPOSITION_TYPE_FRAME))
92     return -EINVAL;
93
94   ++timeline_;
95   layer->releaseFenceFd =
96       sw_sync_fence_create(timeline_fd_, "drm_fence", timeline_);
97   if (layer->releaseFenceFd < 0) {
98     ALOGE("Could not create release fence %d", layer->releaseFenceFd);
99     return layer->releaseFenceFd;
100   }
101
102   DrmCompositionLayer_t c_layer;
103   c_layer.layer = *layer;
104   c_layer.bo = *bo;
105   c_layer.crtc = crtc;
106   c_layer.plane = plane;
107
108   layer->acquireFenceFd = -1;  // We own this now
109   layers_.push_back(c_layer);
110   type_ = DRM_COMPOSITION_TYPE_FRAME;
111   return 0;
112 }
113
114 int DrmDisplayComposition::AddDpmsMode(uint32_t dpms_mode) {
115   if (!validate_composition_type(DRM_COMPOSITION_TYPE_DPMS))
116     return -EINVAL;
117   dpms_mode_ = dpms_mode;
118   type_ = DRM_COMPOSITION_TYPE_DPMS;
119   return 0;
120 }
121
122 int DrmDisplayComposition::AddPlaneDisable(DrmPlane *plane) {
123   DrmCompositionLayer_t c_layer;
124   c_layer.crtc = NULL;
125   c_layer.plane = plane;
126   layers_.push_back(c_layer);
127   return 0;
128 }
129
130 int DrmDisplayComposition::FinishComposition() {
131   int ret = sw_sync_timeline_inc(timeline_fd_, timeline_);
132   if (ret)
133     ALOGE("Failed to increment sync timeline %d", ret);
134
135   return ret;
136 }
137
138 DrmCompositionLayerVector_t *DrmDisplayComposition::GetCompositionLayers() {
139   return &layers_;
140 }
141
142 uint32_t DrmDisplayComposition::dpms_mode() const {
143   return dpms_mode_;
144 }
145 }