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