OSDN Git Service

d8dc886d6c9559b3a41178ce15472d654816a02d
[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 (!validate_composition_type(DRM_COMPOSITION_TYPE_FRAME))
89     return -EINVAL;
90
91   ++timeline_;
92   layer->releaseFenceFd =
93       sw_sync_fence_create(timeline_fd_, "drm_fence", timeline_);
94   if (layer->releaseFenceFd < 0) {
95     ALOGE("Could not create release fence %d", layer->releaseFenceFd);
96     return layer->releaseFenceFd;
97   }
98
99   DrmCompositionLayer_t c_layer;
100   c_layer.layer = *layer;
101   c_layer.bo = *bo;
102   c_layer.crtc = crtc;
103   c_layer.plane = plane;
104
105   layer->acquireFenceFd = -1;  // We own this now
106   layers_.push_back(c_layer);
107   type_ = DRM_COMPOSITION_TYPE_FRAME;
108   return 0;
109 }
110
111 int DrmDisplayComposition::AddDpmsMode(uint32_t dpms_mode) {
112   if (!validate_composition_type(DRM_COMPOSITION_TYPE_DPMS))
113     return -EINVAL;
114   dpms_mode_ = dpms_mode;
115   type_ = DRM_COMPOSITION_TYPE_DPMS;
116   return 0;
117 }
118
119 int DrmDisplayComposition::AddPlaneDisable(DrmPlane *plane) {
120   DrmCompositionLayer_t c_layer;
121   c_layer.crtc = NULL;
122   c_layer.plane = plane;
123   layers_.push_back(c_layer);
124   return 0;
125 }
126
127 int DrmDisplayComposition::FinishComposition() {
128   int ret = sw_sync_timeline_inc(timeline_fd_, timeline_);
129   if (ret)
130     ALOGE("Failed to increment sync timeline %d", ret);
131
132   return ret;
133 }
134
135 DrmCompositionLayerVector_t *DrmDisplayComposition::GetCompositionLayers() {
136   return &layers_;
137 }
138
139 uint32_t DrmDisplayComposition::dpms_mode() const {
140   return dpms_mode_;
141 }
142 }