blob: 00915757469ee60aa4788c381d658486d5d50f26 [file] [log] [blame]
Sean Paul80b1a5d2016-03-10 15:35:13 -05001/*
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 <cutils/log.h>
24
25namespace android {
26
27const 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
36void DrmHwcBuffer::Clear() {
37 if (importer_ != NULL) {
38 importer_->ReleaseBuffer(&bo_);
39 importer_ = NULL;
40 }
41}
42
43int 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
61static 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
79static 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
88int 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
111DrmHwcNativeHandle::~DrmHwcNativeHandle() {
112 Clear();
113}
114
115void 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
124int 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
152int 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 ret = gralloc->perform(gralloc, GRALLOC_MODULE_PERFORM_GET_USAGE,
163 handle.get(), &gralloc_buffer_usage);
164 if (ret) {
165 ALOGE("Failed to get usage for buffer %p (%d)", handle.get(), ret);
166 return ret;
167 }
168 return 0;
169}
170
171void DrmHwcLayer::SetSourceCrop(hwc_frect_t const &crop) {
172 source_crop = DrmHwcRect<float>(crop.left, crop.top, crop.right, crop.bottom);
173}
174
175void DrmHwcLayer::SetDisplayFrame(hwc_rect_t const &frame) {
176 display_frame =
177 DrmHwcRect<int>(frame.left, frame.top, frame.right, frame.bottom);
178}
179
180void DrmHwcLayer::SetTransform(int32_t sf_transform) {
181 transform = 0;
182 // 270* and 180* cannot be combined with flips. More specifically, they
183 // already contain both horizontal and vertical flips, so those fields are
184 // redundant in this case. 90* rotation can be combined with either horizontal
185 // flip or vertical flip, so treat it differently
186 if (sf_transform == HWC_TRANSFORM_ROT_270) {
187 transform = DrmHwcTransform::kRotate270;
188 } else if (sf_transform == HWC_TRANSFORM_ROT_180) {
189 transform = DrmHwcTransform::kRotate180;
190 } else {
191 if (sf_transform & HWC_TRANSFORM_FLIP_H)
192 transform |= DrmHwcTransform::kFlipH;
193 if (sf_transform & HWC_TRANSFORM_FLIP_V)
194 transform |= DrmHwcTransform::kFlipV;
195 if (sf_transform & HWC_TRANSFORM_ROT_90)
196 transform |= DrmHwcTransform::kRotate90;
197 }
198}
199}