OSDN Git Service

drm_hwcomposer: Add platform backend for minigbm
[android-x86/external-drm_hwcomposer.git] / hwcutils.cpp
1 /*
2  * Copyright (C) 2016 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 ATRACE_TAG ATRACE_TAG_GRAPHICS
18 #define LOG_TAG "hwc-drm-utils"
19
20 #include "drmhwcomposer.h"
21 #include "platform.h"
22
23 #include <log/log.h>
24
25 namespace android {
26
27 const hwc_drm_bo *DrmHwcBuffer::operator->() const {
28   if (importer_ == NULL) {
29     ALOGE("Access of non-existent BO");
30     exit(1);
31     return NULL;
32   }
33   return &bo_;
34 }
35
36 void DrmHwcBuffer::Clear() {
37   if (importer_ != NULL) {
38     importer_->ReleaseBuffer(&bo_);
39     importer_ = NULL;
40   }
41 }
42
43 int DrmHwcBuffer::ImportBuffer(buffer_handle_t handle, Importer *importer) {
44   hwc_drm_bo tmp_bo;
45
46   int ret = importer->ImportBuffer(handle, &tmp_bo);
47   if (ret)
48     return ret;
49
50   if (importer_ != NULL) {
51     importer_->ReleaseBuffer(&bo_);
52   }
53
54   importer_ = importer;
55
56   bo_ = tmp_bo;
57
58   return 0;
59 }
60
61 static native_handle_t *dup_buffer_handle(buffer_handle_t handle) {
62   native_handle_t *new_handle =
63       native_handle_create(handle->numFds, handle->numInts);
64   if (new_handle == NULL)
65     return NULL;
66
67   const int *old_data = handle->data;
68   int *new_data = new_handle->data;
69   for (int i = 0; i < handle->numFds; i++) {
70     *new_data = dup(*old_data);
71     old_data++;
72     new_data++;
73   }
74   memcpy(new_data, old_data, sizeof(int) * handle->numInts);
75
76   return new_handle;
77 }
78
79 static void free_buffer_handle(native_handle_t *handle) {
80   int ret = native_handle_close(handle);
81   if (ret)
82     ALOGE("Failed to close native handle %d", ret);
83   ret = native_handle_delete(handle);
84   if (ret)
85     ALOGE("Failed to delete native handle %d", ret);
86 }
87
88 int DrmHwcNativeHandle::CopyBufferHandle(buffer_handle_t handle,
89                                          const gralloc_module_t *gralloc) {
90   native_handle_t *handle_copy = dup_buffer_handle(handle);
91   if (handle_copy == NULL) {
92     ALOGE("Failed to duplicate handle");
93     return -ENOMEM;
94   }
95
96   int ret = gralloc->registerBuffer(gralloc, handle_copy);
97   if (ret) {
98     ALOGE("Failed to register buffer handle %d", ret);
99     free_buffer_handle(handle_copy);
100     return ret;
101   }
102
103   Clear();
104
105   gralloc_ = gralloc;
106   handle_ = handle_copy;
107
108   return 0;
109 }
110
111 DrmHwcNativeHandle::~DrmHwcNativeHandle() {
112   Clear();
113 }
114
115 void DrmHwcNativeHandle::Clear() {
116   if (gralloc_ != NULL && handle_ != NULL) {
117     gralloc_->unregisterBuffer(gralloc_, handle_);
118     free_buffer_handle(handle_);
119     gralloc_ = NULL;
120     handle_ = NULL;
121   }
122 }
123
124 int DrmHwcLayer::InitFromHwcLayer(hwc_layer_1_t *sf_layer, Importer *importer,
125                                   const gralloc_module_t *gralloc) {
126   alpha = sf_layer->planeAlpha;
127
128   SetSourceCrop(sf_layer->sourceCropf);
129   SetDisplayFrame(sf_layer->displayFrame);
130   SetTransform(sf_layer->transform);
131
132   switch (sf_layer->blending) {
133     case HWC_BLENDING_NONE:
134       blending = DrmHwcBlending::kNone;
135       break;
136     case HWC_BLENDING_PREMULT:
137       blending = DrmHwcBlending::kPreMult;
138       break;
139     case HWC_BLENDING_COVERAGE:
140       blending = DrmHwcBlending::kCoverage;
141       break;
142     default:
143       ALOGE("Invalid blending in hwc_layer_1_t %d", sf_layer->blending);
144       return -EINVAL;
145   }
146
147   sf_handle = sf_layer->handle;
148
149   return ImportBuffer(importer, gralloc);
150 }
151
152 int DrmHwcLayer::ImportBuffer(Importer *importer,
153                               const gralloc_module_t *gralloc) {
154   int ret = buffer.ImportBuffer(sf_handle, importer);
155   if (ret)
156     return ret;
157
158   ret = handle.CopyBufferHandle(sf_handle, gralloc);
159   if (ret)
160     return ret;
161
162   gralloc_buffer_usage = buffer.operator->()->usage;
163
164   return 0;
165 }
166
167 void DrmHwcLayer::SetSourceCrop(hwc_frect_t const &crop) {
168   source_crop = DrmHwcRect<float>(crop.left, crop.top, crop.right, crop.bottom);
169 }
170
171 void DrmHwcLayer::SetDisplayFrame(hwc_rect_t const &frame) {
172   display_frame =
173       DrmHwcRect<int>(frame.left, frame.top, frame.right, frame.bottom);
174 }
175
176 void DrmHwcLayer::SetTransform(int32_t sf_transform) {
177   transform = 0;
178   // 270* and 180* cannot be combined with flips. More specifically, they
179   // already contain both horizontal and vertical flips, so those fields are
180   // redundant in this case. 90* rotation can be combined with either horizontal
181   // flip or vertical flip, so treat it differently
182   if (sf_transform == HWC_TRANSFORM_ROT_270) {
183     transform = DrmHwcTransform::kRotate270;
184   } else if (sf_transform == HWC_TRANSFORM_ROT_180) {
185     transform = DrmHwcTransform::kRotate180;
186   } else {
187     if (sf_transform & HWC_TRANSFORM_FLIP_H)
188       transform |= DrmHwcTransform::kFlipH;
189     if (sf_transform & HWC_TRANSFORM_FLIP_V)
190       transform |= DrmHwcTransform::kFlipV;
191     if (sf_transform & HWC_TRANSFORM_ROT_90)
192       transform |= DrmHwcTransform::kRotate90;
193   }
194 }
195 }