1 /*
2 * Copyright (c) 2019 The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above
10 * copyright notice, this list of conditions and the following
11 * disclaimer in the documentation and/or other materials provided
12 * with the distribution.
13 * * Neither the name of The Linux Foundation nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
31 #define DEBUG 0
32 #include "QtiMapperExtensions.h"
33 #include <cutils/trace.h>
34 #include <qdMetaData.h>
35 #include <sync/sync.h>
36 #include "gr_utils.h"
37
38 namespace vendor {
39 namespace qti {
40 namespace hardware {
41 namespace display {
42 namespace mapperextensions {
43 namespace V1_1 {
44 namespace implementation {
45
46 using gralloc::BufferInfo;
47
QtiMapperExtensions()48 QtiMapperExtensions::QtiMapperExtensions() {}
49
getMapSecureBufferFlag(void * buffer,getMapSecureBufferFlag_cb hidl_cb)50 Return<void> QtiMapperExtensions::getMapSecureBufferFlag(void *buffer,
51 getMapSecureBufferFlag_cb hidl_cb) {
52 auto err = Error::BAD_BUFFER;
53 auto hnd = static_cast<private_handle_t *>(buffer);
54 int map_secure_buffer = 0;
55 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
56 if (getMetaData(hnd, GET_MAP_SECURE_BUFFER, &map_secure_buffer) != 0) {
57 map_secure_buffer = 0;
58 } else {
59 err = Error::NONE;
60 }
61 }
62 hidl_cb(err, map_secure_buffer != 0);
63 return Void();
64 }
65
getInterlacedFlag(void * buffer,getInterlacedFlag_cb hidl_cb)66 Return<void> QtiMapperExtensions::getInterlacedFlag(void *buffer, getInterlacedFlag_cb hidl_cb) {
67 auto err = Error::BAD_BUFFER;
68 auto hnd = static_cast<private_handle_t *>(buffer);
69 int interlaced_flag = 0;
70 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
71 if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, &interlaced_flag) != 0) {
72 interlaced_flag = 0;
73 } else {
74 err = Error::NONE;
75 }
76 }
77 hidl_cb(err, interlaced_flag != 0);
78 return Void();
79 }
80
getCustomDimensions(void * buffer,getCustomDimensions_cb hidl_cb)81 Return<void> QtiMapperExtensions::getCustomDimensions(void *buffer,
82 getCustomDimensions_cb hidl_cb) {
83 auto err = Error::BAD_BUFFER;
84 auto hnd = static_cast<private_handle_t *>(buffer);
85 int stride = 0;
86 int height = 0;
87 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
88 stride = hnd->width;
89 height = hnd->height;
90 gralloc::GetCustomDimensions(hnd, &stride, &height);
91 err = Error::NONE;
92 }
93 hidl_cb(err, stride, height);
94 return Void();
95 }
96
getRgbDataAddress(void * buffer,getRgbDataAddress_cb hidl_cb)97 Return<void> QtiMapperExtensions::getRgbDataAddress(void *buffer, getRgbDataAddress_cb hidl_cb) {
98 auto err = Error::BAD_BUFFER;
99 auto hnd = static_cast<private_handle_t *>(buffer);
100 void *rgb_data = nullptr;
101 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
102 if (gralloc::GetRgbDataAddress(hnd, &rgb_data) == 0) {
103 err = Error::NONE;
104 }
105 }
106 hidl_cb(err, rgb_data);
107 return Void();
108 }
109
calculateBufferAttributes(int32_t width,int32_t height,int32_t format,uint64_t usage,calculateBufferAttributes_cb hidl_cb)110 Return<void> QtiMapperExtensions::calculateBufferAttributes(int32_t width, int32_t height,
111 int32_t format, uint64_t usage,
112 calculateBufferAttributes_cb hidl_cb) {
113 unsigned int alignedw, alignedh;
114 BufferInfo info(width, height, format, usage);
115 gralloc::GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
116 bool ubwc_enabled = gralloc::IsUBwcEnabled(format, usage);
117 hidl_cb(Error::NONE, alignedw, alignedh, ubwc_enabled);
118 return Void();
119 }
120
getCustomFormatFlags(int32_t format,uint64_t usage,getCustomFormatFlags_cb hidl_cb)121 Return<void> QtiMapperExtensions::getCustomFormatFlags(int32_t format, uint64_t usage,
122 getCustomFormatFlags_cb hidl_cb) {
123 uint64_t priv_flags = 0;
124 auto err = Error::NONE;
125 int32_t custom_format = format;
126 if (gralloc::GetCustomFormatFlags(format, usage, &custom_format, &priv_flags) != 0) {
127 err = Error::UNSUPPORTED;
128 }
129 hidl_cb(err, custom_format, priv_flags);
130 return Void();
131 }
132
getColorSpace(void * buffer,getColorSpace_cb hidl_cb)133 Return<void> QtiMapperExtensions::getColorSpace(void *buffer, getColorSpace_cb hidl_cb) {
134 auto err = Error::BAD_BUFFER;
135 auto hnd = static_cast<private_handle_t *>(buffer);
136 int color_space = 0;
137 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
138 gralloc::GetColorSpaceFromMetadata(hnd, &color_space);
139 err = Error::NONE;
140 }
141 hidl_cb(err, color_space);
142 return Void();
143 }
144
getYuvPlaneInfo(void * buffer,getYuvPlaneInfo_cb hidl_cb)145 Return<void> QtiMapperExtensions::getYuvPlaneInfo(void *buffer, getYuvPlaneInfo_cb hidl_cb) {
146 auto err = Error::BAD_BUFFER;
147 auto hnd = static_cast<private_handle_t *>(buffer);
148 hidl_vec<YCbCrLayout> layout;
149 layout.resize(2);
150 android_ycbcr yuv_plane_info[2];
151 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
152 if (gralloc::GetYUVPlaneInfo(hnd, yuv_plane_info) == 0) {
153 err = Error::NONE;
154 for (int i = 0; i < 2; i++) {
155 layout[i].y = yuv_plane_info[i].y;
156 layout[i].cr = yuv_plane_info[i].cr;
157 layout[i].cb = yuv_plane_info[i].cb;
158 layout[i].yStride = static_cast<uint32_t>(yuv_plane_info[i].ystride);
159 layout[i].cStride = static_cast<uint32_t>(yuv_plane_info[i].cstride);
160 layout[i].chromaStep = static_cast<uint32_t>(yuv_plane_info[i].chroma_step);
161 }
162 }
163 }
164 hidl_cb(err, layout);
165 return Void();
166 }
167
setSingleBufferMode(void * buffer,bool enable)168 Return<Error> QtiMapperExtensions::setSingleBufferMode(void *buffer, bool enable) {
169 auto err = Error::BAD_BUFFER;
170 auto hnd = static_cast<private_handle_t *>(buffer);
171 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
172 if (setMetaData(hnd, SET_SINGLE_BUFFER_MODE, &enable) != 0) {
173 err = Error::UNSUPPORTED;
174 } else {
175 err = Error::NONE;
176 }
177 }
178 return err;
179 }
180
getFd(void * buffer,getFd_cb hidl_cb)181 Return<void> QtiMapperExtensions::getFd(void *buffer, getFd_cb hidl_cb) {
182 auto err = Error::BAD_BUFFER;
183 int fd = 0;
184 auto hnd = static_cast<private_handle_t *>(buffer);
185 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
186 err = Error::NONE;
187 fd = hnd->fd;
188 }
189 hidl_cb(err, fd);
190 return Void();
191 }
192
getWidth(void * buffer,getWidth_cb hidl_cb)193 Return<void> QtiMapperExtensions::getWidth(void *buffer, getWidth_cb hidl_cb) {
194 auto err = Error::BAD_BUFFER;
195 int width = 0;
196 auto hnd = static_cast<private_handle_t *>(buffer);
197 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
198 err = Error::NONE;
199 width = hnd->width;
200 }
201 hidl_cb(err, width);
202 return Void();
203 }
204
getHeight(void * buffer,getHeight_cb hidl_cb)205 Return<void> QtiMapperExtensions::getHeight(void *buffer, getHeight_cb hidl_cb) {
206 auto err = Error::BAD_BUFFER;
207 int height = 0;
208 auto hnd = static_cast<private_handle_t *>(buffer);
209 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
210 err = Error::NONE;
211 height = hnd->height;
212 }
213 hidl_cb(err, height);
214 return Void();
215 }
216
getFormat(void * buffer,getFormat_cb hidl_cb)217 Return<void> QtiMapperExtensions::getFormat(void *buffer, getFormat_cb hidl_cb) {
218 auto err = Error::BAD_BUFFER;
219 int format = 0;
220 auto hnd = static_cast<private_handle_t *>(buffer);
221 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
222 err = Error::NONE;
223 format = hnd->format;
224 }
225 hidl_cb(err, format);
226 return Void();
227 }
228
getPrivateFlags(void * buffer,getPrivateFlags_cb hidl_cb)229 Return<void> QtiMapperExtensions::getPrivateFlags(void *buffer, getPrivateFlags_cb hidl_cb) {
230 auto err = Error::BAD_BUFFER;
231 int flags = 0;
232 auto hnd = static_cast<private_handle_t *>(buffer);
233 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
234 err = Error::NONE;
235 flags = hnd->flags;
236 }
237 hidl_cb(err, flags);
238 return Void();
239 }
240
getUnalignedWidth(void * buffer,getUnalignedWidth_cb hidl_cb)241 Return<void> QtiMapperExtensions::getUnalignedWidth(void *buffer, getUnalignedWidth_cb hidl_cb) {
242 auto err = Error::BAD_BUFFER;
243 int unaligned_width = 0;
244 auto hnd = static_cast<private_handle_t *>(buffer);
245 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
246 err = Error::NONE;
247 unaligned_width = hnd->unaligned_width;
248 }
249 hidl_cb(err, unaligned_width);
250 return Void();
251 }
252
getUnalignedHeight(void * buffer,getUnalignedHeight_cb hidl_cb)253 Return<void> QtiMapperExtensions::getUnalignedHeight(void *buffer, getUnalignedHeight_cb hidl_cb) {
254 auto err = Error::BAD_BUFFER;
255 int unaligned_height = 0;
256 auto hnd = static_cast<private_handle_t *>(buffer);
257 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
258 err = Error::NONE;
259 unaligned_height = hnd->unaligned_height;
260 }
261 hidl_cb(err, unaligned_height);
262 return Void();
263 }
264
getLayerCount(void * buffer,getLayerCount_cb hidl_cb)265 Return<void> QtiMapperExtensions::getLayerCount(void *buffer, getLayerCount_cb hidl_cb) {
266 auto err = Error::BAD_BUFFER;
267 unsigned int layer_count = 0;
268 auto hnd = static_cast<private_handle_t *>(buffer);
269 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
270 err = Error::NONE;
271 layer_count = hnd->layer_count;
272 }
273 hidl_cb(err, layer_count);
274 return Void();
275 }
276
getId(void * buffer,getId_cb hidl_cb)277 Return<void> QtiMapperExtensions::getId(void *buffer, getId_cb hidl_cb) {
278 auto err = Error::BAD_BUFFER;
279 uint64_t id = 0;
280 auto hnd = static_cast<private_handle_t *>(buffer);
281 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
282 err = Error::NONE;
283 id = hnd->id;
284 }
285 hidl_cb(err, id);
286 return Void();
287 }
288
getUsageFlags(void * buffer,getUsageFlags_cb hidl_cb)289 Return<void> QtiMapperExtensions::getUsageFlags(void *buffer, getUsageFlags_cb hidl_cb) {
290 auto err = Error::BAD_BUFFER;
291 uint64_t usage = 0;
292 auto hnd = static_cast<private_handle_t *>(buffer);
293 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
294 err = Error::NONE;
295 usage = hnd->usage;
296 }
297 hidl_cb(err, usage);
298 return Void();
299 }
300
getSize(void * buffer,getSize_cb hidl_cb)301 Return<void> QtiMapperExtensions::getSize(void *buffer, getSize_cb hidl_cb) {
302 auto err = Error::BAD_BUFFER;
303 unsigned int size = 0;
304 auto hnd = static_cast<private_handle_t *>(buffer);
305 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
306 err = Error::NONE;
307 size = hnd->size;
308 }
309 hidl_cb(err, size);
310 return Void();
311 }
312
getOffset(void * buffer,getOffset_cb hidl_cb)313 Return<void> QtiMapperExtensions::getOffset(void *buffer, getOffset_cb hidl_cb) {
314 auto err = Error::BAD_BUFFER;
315 unsigned int offset = 0;
316 auto hnd = static_cast<private_handle_t *>(buffer);
317 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
318 err = Error::NONE;
319 offset = hnd->offset;
320 }
321 hidl_cb(err, offset);
322 return Void();
323 }
324
getSurfaceMetadata(void * buffer,getSurfaceMetadata_cb hidl_cb)325 Return<void> QtiMapperExtensions::getSurfaceMetadata(void *buffer, getSurfaceMetadata_cb hidl_cb) {
326 auto err = Error::BAD_BUFFER;
327 auto hnd = static_cast<private_handle_t *>(buffer);
328 GraphicsMetadata surface_metadata;
329 if (buffer != nullptr && private_handle_t::validate(hnd) == 0) {
330 if (getMetaData(hnd, GET_GRAPHICS_METADATA, &surface_metadata) == 0) {
331 err = Error::NONE;
332 }
333 }
334 if (err != Error::NONE) {
335 hidl_cb(err, nullptr);
336 } else {
337 hidl_cb(err, &surface_metadata);
338 }
339 return Void();
340 }
341
342 // It will return size for single layer only i.e. layer count is always 1.
getFormatLayout(int32_t format,uint64_t usage,int32_t flags,int32_t width,int32_t height,getFormatLayout_cb hidl_cb)343 Return<void> QtiMapperExtensions::getFormatLayout(int32_t format, uint64_t usage, int32_t flags,
344 int32_t width, int32_t height,
345 getFormatLayout_cb hidl_cb) {
346 ALOGD_IF(DEBUG, "%s: Input parameters - wxh: %dx%d usage: 0x%" PRIu64 " format: %d", __FUNCTION__,
347 width, height, usage, format);
348 auto err = Error::NONE;
349 hidl_vec<PlaneLayout> plane_info;
350 unsigned int alignedw = 0, alignedh = 0;
351 int plane_count = 0;
352 uint32_t size = 0;
353 int custom_format = gralloc::GetImplDefinedFormat(usage, format);
354 BufferInfo info(width, height, custom_format, usage);
355 int ret = gralloc::GetBufferSizeAndDimensions(info, &size, &alignedw, &alignedh);
356 if (ret) {
357 err = Error::BAD_BUFFER;
358 hidl_cb(err, size, plane_info);
359 return Void();
360 }
361 gralloc::PlaneLayoutInfo plane_layout[8] = {};
362 ALOGD_IF(DEBUG, "%s: Aligned width and height - wxh: %ux%u custom_format = %d", __FUNCTION__,
363 alignedw, alignedh, custom_format);
364 if (gralloc::IsYuvFormat(custom_format)) {
365 gralloc::GetYUVPlaneInfo(info, custom_format, alignedw, alignedh, flags, &plane_count,
366 plane_layout);
367 } else if (gralloc::IsUncompressedRGBFormat(custom_format) ||
368 gralloc::IsCompressedRGBFormat(custom_format)) {
369 gralloc::GetRGBPlaneInfo(info, custom_format, alignedw, alignedh, flags, &plane_count,
370 plane_layout);
371 } else {
372 err = Error::BAD_BUFFER;
373 hidl_cb(err, size, plane_info);
374 return Void();
375 }
376 ALOGD_IF(DEBUG, "%s: Number of plane - %d, custom_format - %d", __FUNCTION__, plane_count,
377 custom_format);
378 plane_info.resize(plane_count);
379 for (int i = 0; i < plane_count; i++) {
380 plane_info[i].component = plane_layout[i].component;
381 plane_info[i].h_subsampling = plane_layout[i].h_subsampling;
382 plane_info[i].v_subsampling = plane_layout[i].v_subsampling;
383 plane_info[i].offset = plane_layout[i].offset;
384 plane_info[i].pixel_increment = plane_layout[i].step;
385 plane_info[i].stride = plane_layout[i].stride;
386 plane_info[i].stride_bytes = plane_layout[i].stride_bytes;
387 plane_info[i].scanlines = plane_layout[i].scanlines;
388 plane_info[i].size = plane_layout[i].size;
389 ALOGD_IF(DEBUG, "%s: plane info: component - %d", __FUNCTION__, plane_info[i].component);
390 ALOGD_IF(DEBUG, "h_subsampling - %u, v_subsampling - %u, offset - %u, pixel_increment - %d",
391 plane_info[i].h_subsampling, plane_info[i].v_subsampling, plane_info[i].offset,
392 plane_info[i].pixel_increment);
393 ALOGD_IF(DEBUG, "stride_pixel - %d, stride_bytes - %d, scanlines - %d, size - %u",
394 plane_info[i].stride, plane_info[i].stride_bytes, plane_info[i].scanlines,
395 plane_info[i].size);
396 }
397 hidl_cb(err, size, plane_info);
398 return Void();
399 }
400
getSurfaceMetadata_V1(void * buffer,void * metadata)401 Return<Error> QtiMapperExtensions::getSurfaceMetadata_V1(void *buffer, void *metadata) {
402 auto err = Error::BAD_BUFFER;
403 auto hnd = static_cast<private_handle_t *>(buffer);
404 if (metadata != nullptr && buffer != nullptr && private_handle_t::validate(hnd) == 0) {
405 if (getMetaData(hnd, GET_GRAPHICS_METADATA, metadata) == 0) {
406 err = Error::NONE;
407 } else {
408 err = Error::UNSUPPORTED;
409 }
410 } else {
411 ALOGE("%s: buffer pointer: %p, metadata pointer: %p ", __FUNCTION__, buffer, metadata);
412 }
413 return err;
414 }
415
416 } // namespace implementation
417 } // namespace V1_1
418 } // namespace mapperextensions
419 } // namespace display
420 } // namespace hardware
421 } // namespace qti
422 } // namespace vendor
423