• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2011-2018, 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 #include <media/msm_media_info.h>
31 #include <algorithm>
32 
33 #include "gr_adreno_info.h"
34 #include "gr_utils.h"
35 
36 #define ASTC_BLOCK_SIZE 16
37 
38 #ifndef COLOR_FMT_P010_UBWC
39 #define COLOR_FMT_P010_UBWC 9
40 #endif
41 
42 namespace gralloc {
43 
IsYuvFormat(int format)44 bool IsYuvFormat(int format) {
45   switch (format) {
46     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
47     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
48     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
49     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:  // Same as YCbCr_420_SP_VENUS
50     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
51     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
52     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
53     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
54     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
55     case HAL_PIXEL_FORMAT_NV21_ZSL:
56     case HAL_PIXEL_FORMAT_RAW16:
57     case HAL_PIXEL_FORMAT_Y16:
58     case HAL_PIXEL_FORMAT_RAW12:
59     case HAL_PIXEL_FORMAT_RAW10:
60     case HAL_PIXEL_FORMAT_YV12:
61     case HAL_PIXEL_FORMAT_Y8:
62     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
63     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
64     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
65     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
66     // Below formats used by camera and VR
67     case HAL_PIXEL_FORMAT_BLOB:
68     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
69       return true;
70     default:
71       return false;
72   }
73 }
74 
IsUncompressedRGBFormat(int format)75 bool IsUncompressedRGBFormat(int format) {
76   switch (format) {
77     case HAL_PIXEL_FORMAT_RGBA_8888:
78     case HAL_PIXEL_FORMAT_RGBX_8888:
79     case HAL_PIXEL_FORMAT_RGB_888:
80     case HAL_PIXEL_FORMAT_RGB_565:
81     case HAL_PIXEL_FORMAT_BGR_565:
82     case HAL_PIXEL_FORMAT_BGRA_8888:
83     case HAL_PIXEL_FORMAT_RGBA_5551:
84     case HAL_PIXEL_FORMAT_RGBA_4444:
85     case HAL_PIXEL_FORMAT_R_8:
86     case HAL_PIXEL_FORMAT_RG_88:
87     case HAL_PIXEL_FORMAT_BGRX_8888:
88     case HAL_PIXEL_FORMAT_RGBA_1010102:
89     case HAL_PIXEL_FORMAT_ARGB_2101010:
90     case HAL_PIXEL_FORMAT_RGBX_1010102:
91     case HAL_PIXEL_FORMAT_XRGB_2101010:
92     case HAL_PIXEL_FORMAT_BGRA_1010102:
93     case HAL_PIXEL_FORMAT_ABGR_2101010:
94     case HAL_PIXEL_FORMAT_BGRX_1010102:
95     case HAL_PIXEL_FORMAT_XBGR_2101010:
96     case HAL_PIXEL_FORMAT_RGBA_FP16:
97     case HAL_PIXEL_FORMAT_BGR_888:
98       return true;
99     default:
100       break;
101   }
102 
103   return false;
104 }
105 
IsCompressedRGBFormat(int format)106 bool IsCompressedRGBFormat(int format) {
107   switch (format) {
108     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
109     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
110     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
111     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
112     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
113     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
114     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
115     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
116     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
117     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
118     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
119     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
120     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
121     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
122     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
123     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
124     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
125     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
126     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
127     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
128     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
129     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
130     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
131     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
132     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
133     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
134     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
135     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
136       return true;
137     default:
138       break;
139   }
140 
141   return false;
142 }
143 
GetBppForUncompressedRGB(int format)144 uint32_t GetBppForUncompressedRGB(int format) {
145   uint32_t bpp = 0;
146   switch (format) {
147     case HAL_PIXEL_FORMAT_RGBA_FP16:
148       bpp = 8;
149       break;
150     case HAL_PIXEL_FORMAT_RGBA_8888:
151     case HAL_PIXEL_FORMAT_RGBX_8888:
152     case HAL_PIXEL_FORMAT_BGRA_8888:
153     case HAL_PIXEL_FORMAT_BGRX_8888:
154     case HAL_PIXEL_FORMAT_RGBA_1010102:
155     case HAL_PIXEL_FORMAT_ARGB_2101010:
156     case HAL_PIXEL_FORMAT_RGBX_1010102:
157     case HAL_PIXEL_FORMAT_XRGB_2101010:
158     case HAL_PIXEL_FORMAT_BGRA_1010102:
159     case HAL_PIXEL_FORMAT_ABGR_2101010:
160     case HAL_PIXEL_FORMAT_BGRX_1010102:
161     case HAL_PIXEL_FORMAT_XBGR_2101010:
162       bpp = 4;
163       break;
164     case HAL_PIXEL_FORMAT_RGB_888:
165     case HAL_PIXEL_FORMAT_BGR_888:
166       bpp = 3;
167       break;
168     case HAL_PIXEL_FORMAT_RGB_565:
169     case HAL_PIXEL_FORMAT_BGR_565:
170     case HAL_PIXEL_FORMAT_RGBA_5551:
171     case HAL_PIXEL_FORMAT_RGBA_4444:
172       bpp = 2;
173       break;
174     default:
175       ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
176       break;
177   }
178 
179   return bpp;
180 }
181 
CpuCanAccess(uint64_t usage)182 bool CpuCanAccess(uint64_t usage) {
183   return CpuCanRead(usage) || CpuCanWrite(usage);
184 }
185 
CpuCanRead(uint64_t usage)186 bool CpuCanRead(uint64_t usage) {
187   if (usage & BufferUsage::CPU_READ_MASK) {
188     return true;
189   }
190 
191   return false;
192 }
193 
CpuCanWrite(uint64_t usage)194 bool CpuCanWrite(uint64_t usage) {
195   if (usage & BufferUsage::CPU_WRITE_MASK) {
196     // Application intends to use CPU for rendering
197     return true;
198   }
199 
200   return false;
201 }
202 
GetDataAlignment(int format,uint64_t usage)203 uint32_t GetDataAlignment(int format, uint64_t usage) {
204   uint32_t align = UINT(getpagesize());
205   if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
206     align = 8192;
207   }
208 
209   if (usage & BufferUsage::PROTECTED) {
210     if ((usage & BufferUsage::CAMERA_OUTPUT) || (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
211       // The alignment here reflects qsee mmu V7L/V8L requirement
212       align = SZ_2M;
213     } else {
214       align = SECURE_ALIGN;
215     }
216   }
217 
218   return align;
219 }
220 
IsGPUFlagSupported(uint64_t usage)221 bool IsGPUFlagSupported(uint64_t usage) {
222   bool ret = true;
223   if ((usage & BufferUsage::GPU_MIPMAP_COMPLETE)) {
224     ALOGE("GPU_MIPMAP_COMPLETE not supported");
225     ret = false;
226   }
227 
228   if ((usage & BufferUsage::GPU_CUBE_MAP)) {
229     ALOGE("GPU_CUBE_MAP not supported");
230     ret = false;
231   }
232 
233   return ret;
234 }
235 
236 // Returns the final buffer size meant to be allocated with ion
GetSize(const BufferInfo & info,unsigned int alignedw,unsigned int alignedh)237 unsigned int GetSize(const BufferInfo &info, unsigned int alignedw, unsigned int alignedh) {
238   unsigned int size = 0;
239   int format = info.format;
240   int width = info.width;
241   int height = info.height;
242   uint64_t usage = info.usage;
243 
244   if (!IsGPUFlagSupported(usage)) {
245     ALOGE("Unsupported GPU usage flags present 0x%" PRIx64, usage);
246     return 0;
247   }
248 
249   if (IsUBwcEnabled(format, usage)) {
250     size = GetUBwcSize(width, height, format, alignedw, alignedh);
251   } else if (IsUncompressedRGBFormat(format)) {
252     uint32_t bpp = GetBppForUncompressedRGB(format);
253     size = alignedw * alignedh * bpp;
254   } else if (IsCompressedRGBFormat(format)) {
255     size = alignedw * alignedh * ASTC_BLOCK_SIZE;
256   } else {
257     // Below switch should be for only YUV/custom formats
258     switch (format) {
259       case HAL_PIXEL_FORMAT_RAW16:
260       case HAL_PIXEL_FORMAT_Y16:size = alignedw * alignedh * 2;
261         break;
262       case HAL_PIXEL_FORMAT_RAW10:
263       case HAL_PIXEL_FORMAT_RAW12:size = ALIGN(alignedw * alignedh, SIZE_4K);
264         break;
265       case HAL_PIXEL_FORMAT_RAW8:
266       case HAL_PIXEL_FORMAT_Y8:size = alignedw * alignedh * 1;
267         break;
268 
269         // adreno formats
270       case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
271         size = ALIGN(alignedw * alignedh, SIZE_4K);
272         size += (unsigned int) ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
273         break;
274       case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:  // NV12
275         // The chroma plane is subsampled,
276         // but the pitch in bytes is unchanged
277         // The GPU needs 4K alignment, but the video decoder needs 8K
278         size = ALIGN(alignedw * alignedh, SIZE_8K);
279         size += ALIGN(alignedw * (unsigned int) ALIGN(height / 2, 32), SIZE_8K);
280         break;
281       case HAL_PIXEL_FORMAT_YV12:
282         if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
283           ALOGE("w or h is odd for the YV12 format");
284           return 0;
285         }
286         size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
287         size = ALIGN(size, (unsigned int) SIZE_4K);
288         break;
289       case HAL_PIXEL_FORMAT_YCbCr_420_SP:
290       case HAL_PIXEL_FORMAT_YCrCb_420_SP:
291         size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
292         break;
293       case HAL_PIXEL_FORMAT_YCbCr_420_P010:
294         size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
295         break;
296       case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
297         size = VENUS_BUFFER_SIZE(COLOR_FMT_P010,
298                                  width,
299                                  height);
300         break;
301       case HAL_PIXEL_FORMAT_YCbCr_422_SP:
302       case HAL_PIXEL_FORMAT_YCrCb_422_SP:
303       case HAL_PIXEL_FORMAT_YCbCr_422_I:
304       case HAL_PIXEL_FORMAT_YCrCb_422_I:
305       case HAL_PIXEL_FORMAT_CbYCrY_422_I:
306         if (width & 1) {
307           ALOGE("width is odd for the YUV422_SP format");
308           return 0;
309         }
310         size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
311         break;
312       case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
313       case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
314         size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
315         break;
316       case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
317       case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
318         size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
319         break;
320       case HAL_PIXEL_FORMAT_BLOB:
321       case HAL_PIXEL_FORMAT_RAW_OPAQUE:
322         if (height != 1) {
323           ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
324           return 0;
325         }
326         size = (unsigned int) width;
327         break;
328       case HAL_PIXEL_FORMAT_NV21_ZSL:
329         size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2,
330                      SIZE_4K);
331         break;
332       default:ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
333         return 0;
334     }
335   }
336   auto align = GetDataAlignment(format, usage);
337   size = ALIGN(size, align) * info.layer_count;
338   return size;
339 }
340 
GetBufferSizeAndDimensions(const BufferInfo & info,unsigned int * size,unsigned int * alignedw,unsigned int * alignedh)341 void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
342                                 unsigned int *alignedh) {
343   GraphicsMetadata graphics_metadata = {};
344   GetBufferSizeAndDimensions(info, size, alignedw, alignedh, &graphics_metadata);
345 }
346 
GetBufferSizeAndDimensions(const BufferInfo & info,unsigned int * size,unsigned int * alignedw,unsigned int * alignedh,GraphicsMetadata * graphics_metadata)347 void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
348                                 unsigned int *alignedh, GraphicsMetadata *graphics_metadata) {
349   int buffer_type = GetBufferType(info.format);
350   if (CanUseAdrenoForSize(buffer_type, info.usage)) {
351     GetGpuResourceSizeAndDimensions(info, size, alignedw, alignedh, graphics_metadata);
352   } else {
353     GetAlignedWidthAndHeight(info, alignedw, alignedh);
354     *size = GetSize(info, *alignedw, *alignedh);
355   }
356 }
357 
GetYuvUbwcSPPlaneInfo(uint64_t base,uint32_t width,uint32_t height,int color_format,struct android_ycbcr * ycbcr)358 void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, int color_format,
359                            struct android_ycbcr *ycbcr) {
360   // UBWC buffer has these 4 planes in the following sequence:
361   // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
362   unsigned int y_meta_stride, y_meta_height, y_meta_size;
363   unsigned int y_stride, y_height, y_size;
364   unsigned int c_meta_stride, c_meta_height, c_meta_size;
365   unsigned int alignment = 4096;
366 
367   y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
368   y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
369   y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
370 
371   y_stride = VENUS_Y_STRIDE(color_format, INT(width));
372   y_height = VENUS_Y_SCANLINES(color_format, INT(height));
373   y_size = ALIGN((y_stride * y_height), alignment);
374 
375   c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
376   c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
377   c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
378 
379   ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
380   ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
381   ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
382   ycbcr->ystride = y_stride;
383   ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
384 }
385 
GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base,uint32_t width,uint32_t height,int color_format,struct android_ycbcr ycbcr[2])386 void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
387                                      int color_format, struct android_ycbcr ycbcr[2]) {
388   unsigned int uv_stride, uv_height, uv_size;
389   unsigned int alignment = 4096;
390   uint64_t field_base;
391 
392   // UBWC interlaced has top-bottom field layout with each field as
393   // 4-plane NV12_UBWC with width = image_width & height = image_height / 2.
394   // Client passed ycbcr argument is ptr to struct android_ycbcr[2].
395   // Plane info to be filled for each field separately.
396   height = (height + 1) >> 1;
397   uv_stride = VENUS_UV_STRIDE(color_format, INT(width));
398   uv_height = VENUS_UV_SCANLINES(color_format, INT(height));
399   uv_size = ALIGN((uv_stride * uv_height), alignment);
400 
401   field_base = base;
402   GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
403 
404   memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
405   field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
406   GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
407 }
408 
GetYuvSPPlaneInfo(uint64_t base,uint32_t width,uint32_t height,uint32_t bpp,struct android_ycbcr * ycbcr)409 void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
410                        struct android_ycbcr *ycbcr) {
411   unsigned int ystride, cstride;
412 
413   ystride = cstride = UINT(width) * bpp;
414   ycbcr->y = reinterpret_cast<void *>(base);
415   ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
416   ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
417   ycbcr->ystride = ystride;
418   ycbcr->cstride = cstride;
419   ycbcr->chroma_step = 2 * bpp;
420 }
421 
GetYUVPlaneInfo(const private_handle_t * hnd,struct android_ycbcr ycbcr[2])422 int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
423   int err = 0;
424   uint32_t width = UINT(hnd->width);
425   uint32_t height = UINT(hnd->height);
426   int format = hnd->format;
427   uint64_t usage = hnd->usage;
428   unsigned int ystride, cstride;
429   bool interlaced = false;
430 
431   memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
432 
433   // Check if UBWC buffer has been rendered in linear format.
434   int linear_format = 0;
435   if (getMetaData(const_cast<private_handle_t *>(hnd), GET_LINEAR_FORMAT, &linear_format) == 0) {
436     format = INT(linear_format);
437   }
438 
439   // Check metadata if the geometry has been updated.
440   BufferDim_t buffer_dim;
441   if (getMetaData(const_cast<private_handle_t *>(hnd), GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
442     BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format, usage);
443     GetAlignedWidthAndHeight(info, &width, &height);
444   }
445 
446   // Check metadata for interlaced content.
447   int interlace_flag = 0;
448   if (getMetaData(const_cast<private_handle_t *>(hnd), GET_PP_PARAM_INTERLACED, &interlace_flag) ==
449       0) {
450     interlaced = interlace_flag;
451   }
452 
453   // Get the chroma offsets from the handle width/height. We take advantage
454   // of the fact the width _is_ the stride
455   switch (format) {
456     // Semiplanar
457     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
458     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
459     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
460     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
461       // Same as YCbCr_420_SP_VENUS
462       GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
463       break;
464 
465     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
466       if (!interlaced) {
467         GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
468       } else {
469         GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
470       }
471       ycbcr->chroma_step = 2;
472       break;
473 
474     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
475       GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
476       break;
477 
478     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
479       GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
480       ycbcr->chroma_step = 3;
481       break;
482 
483     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
484       GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
485       ycbcr->chroma_step = 4;
486       break;
487 
488     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
489       ystride = VENUS_Y_STRIDE(COLOR_FMT_P010, width);
490       cstride = VENUS_UV_STRIDE(COLOR_FMT_P010, width);
491       ycbcr->y = reinterpret_cast<void *>(hnd->base);
492       ycbcr->cb =
493           reinterpret_cast<void *>(hnd->base + ystride * VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
494       ycbcr->cr = reinterpret_cast<void *>(hnd->base +
495                                            ystride * VENUS_Y_SCANLINES(COLOR_FMT_P010, height) + 1);
496       ycbcr->ystride = ystride;
497       ycbcr->cstride = cstride;
498       ycbcr->chroma_step = 4;
499       break;
500 
501     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
502     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
503     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
504     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
505     case HAL_PIXEL_FORMAT_NV21_ZSL:
506     case HAL_PIXEL_FORMAT_RAW16:
507     case HAL_PIXEL_FORMAT_Y16:
508     case HAL_PIXEL_FORMAT_RAW10:
509     case HAL_PIXEL_FORMAT_RAW8:
510     case HAL_PIXEL_FORMAT_Y8:
511       GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
512       std::swap(ycbcr->cb, ycbcr->cr);
513       break;
514 
515       // Planar
516     case HAL_PIXEL_FORMAT_YV12:
517       ystride = width;
518       cstride = ALIGN(width / 2, 16);
519       ycbcr->y = reinterpret_cast<void *>(hnd->base);
520       ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
521       ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
522       ycbcr->ystride = ystride;
523       ycbcr->cstride = cstride;
524       ycbcr->chroma_step = 1;
525       break;
526     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
527       ystride = width * 2;
528       cstride = 0;
529       ycbcr->y = reinterpret_cast<void *>(hnd->base);
530       ycbcr->cr = NULL;
531       ycbcr->cb = NULL;
532       ycbcr->ystride = ystride;
533       ycbcr->cstride = 0;
534       ycbcr->chroma_step = 0;
535       break;
536       // Unsupported formats
537     case HAL_PIXEL_FORMAT_YCbCr_422_I:
538     case HAL_PIXEL_FORMAT_YCrCb_422_I:
539     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
540     default:
541       ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
542       err = -EINVAL;
543   }
544 
545   return err;
546 }
547 
548 // Explicitly defined UBWC formats
IsUBwcFormat(int format)549 bool IsUBwcFormat(int format) {
550   switch (format) {
551     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
552     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
553     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
554       return true;
555     default:
556       return false;
557   }
558 }
559 
IsUBwcSupported(int format)560 bool IsUBwcSupported(int format) {
561   // Existing HAL formats with UBWC support
562   switch (format) {
563     case HAL_PIXEL_FORMAT_BGR_565:
564     case HAL_PIXEL_FORMAT_RGBA_8888:
565     case HAL_PIXEL_FORMAT_RGBX_8888:
566     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
567     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
568     case HAL_PIXEL_FORMAT_RGBA_1010102:
569     case HAL_PIXEL_FORMAT_RGBX_1010102:
570     case HAL_PIXEL_FORMAT_DEPTH_16:
571     case HAL_PIXEL_FORMAT_DEPTH_24:
572     case HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
573     case HAL_PIXEL_FORMAT_DEPTH_32F:
574     case HAL_PIXEL_FORMAT_STENCIL_8:
575       return true;
576     default:
577       break;
578   }
579 
580   return false;
581 }
582 
IsUBwcEnabled(int format,uint64_t usage)583 bool IsUBwcEnabled(int format, uint64_t usage) {
584   // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
585   if (IsUBwcFormat(format)) {
586     return true;
587   }
588 
589   // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
590   // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
591   // usage flag and MDP supports the format.
592   if (IsUBwcSupported(format)) {
593     bool enable =
594         (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) | (usage & BufferUsage::COMPOSER_CLIENT_TARGET);
595     // Query GPU for UBWC only if buffer is intended to be used by GPU.
596     if (enable &&
597         ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET))) {
598       if (AdrenoMemInfo::GetInstance()) {
599         enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
600       }
601     }
602 
603     // Allow UBWC, only if CPU usage flags are not set
604     if (enable && !(CpuCanAccess(usage))) {
605       return true;
606     }
607   }
608 
609   return false;
610 }
611 
GetYuvUBwcWidthAndHeight(int width,int height,int format,unsigned int * aligned_w,unsigned int * aligned_h)612 void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
613                               unsigned int *aligned_h) {
614   switch (format) {
615     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
616     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
617     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
618       *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
619       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
620       break;
621     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
622       // The macro returns the stride which is 4/3 times the width, hence * 3/4
623       *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
624       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
625       break;
626     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
627       // The macro returns the stride which is 2 times the width, hence / 2
628       *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
629       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
630       break;
631     default:
632       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
633       *aligned_w = 0;
634       *aligned_h = 0;
635       break;
636   }
637 }
638 
GetRgbUBwcBlockSize(uint32_t bpp,int * block_width,int * block_height)639 void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
640   *block_width = 0;
641   *block_height = 0;
642 
643   switch (bpp) {
644     case 2:
645     case 4:
646       *block_width = 16;
647       *block_height = 4;
648       break;
649     case 8:
650       *block_width = 8;
651       *block_height = 4;
652       break;
653     case 16:
654       *block_width = 4;
655       *block_height = 4;
656       break;
657     default:
658       ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
659       break;
660   }
661 }
662 
GetRgbUBwcMetaBufferSize(int width,int height,uint32_t bpp)663 unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
664   unsigned int size = 0;
665   int meta_width, meta_height;
666   int block_width, block_height;
667 
668   GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
669   if (!block_width || !block_height) {
670     ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
671     return size;
672   }
673 
674   // Align meta buffer height to 16 blocks
675   meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
676 
677   // Align meta buffer width to 64 blocks
678   meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
679 
680   // Align meta buffer size to 4K
681   size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
682 
683   return size;
684 }
685 
GetUBwcSize(int width,int height,int format,unsigned int alignedw,unsigned int alignedh)686 unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
687                          unsigned int alignedh) {
688   unsigned int size = 0;
689   uint32_t bpp = 0;
690   switch (format) {
691     case HAL_PIXEL_FORMAT_BGR_565:
692     case HAL_PIXEL_FORMAT_RGBA_8888:
693     case HAL_PIXEL_FORMAT_RGBX_8888:
694     case HAL_PIXEL_FORMAT_RGBA_1010102:
695     case HAL_PIXEL_FORMAT_RGBX_1010102:
696       bpp = GetBppForUncompressedRGB(format);
697       size = alignedw * alignedh * bpp;
698       size += GetRgbUBwcMetaBufferSize(width, height, bpp);
699       break;
700     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
701     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
702     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
703       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
704       break;
705     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
706       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
707       break;
708     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
709       size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
710       break;
711     default:
712       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
713       break;
714   }
715 
716   return size;
717 }
718 
GetRgbDataAddress(private_handle_t * hnd,void ** rgb_data)719 int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
720   int err = 0;
721 
722   // This api is for RGB* formats
723   if (!IsUncompressedRGBFormat(hnd->format)) {
724     return -EINVAL;
725   }
726 
727   // linear buffer, nothing to do further
728   if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
729     *rgb_data = reinterpret_cast<void *>(hnd->base);
730     return err;
731   }
732 
733   unsigned int meta_size = 0;
734   uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
735   switch (hnd->format) {
736     case HAL_PIXEL_FORMAT_BGR_565:
737     case HAL_PIXEL_FORMAT_RGBA_8888:
738     case HAL_PIXEL_FORMAT_RGBX_8888:
739     case HAL_PIXEL_FORMAT_RGBA_1010102:
740     case HAL_PIXEL_FORMAT_RGBX_1010102:
741       meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
742       break;
743     default:
744       ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
745       err = -EINVAL;
746       break;
747   }
748   *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
749 
750   return err;
751 }
752 
GetCustomDimensions(private_handle_t * hnd,int * stride,int * height)753 void GetCustomDimensions(private_handle_t *hnd, int *stride, int *height) {
754   BufferDim_t buffer_dim;
755   int interlaced = 0;
756 
757   *stride = hnd->width;
758   *height = hnd->height;
759   if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
760     *stride = buffer_dim.sliceWidth;
761     *height = buffer_dim.sliceHeight;
762   } else if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
763     if (interlaced && IsUBwcFormat(hnd->format)) {
764       unsigned int alignedw = 0, alignedh = 0;
765       // Get re-aligned height for single ubwc interlaced field and
766       // multiply by 2 to get frame height.
767       BufferInfo info(hnd->width, ((hnd->height + 1) >> 1), hnd->format);
768       GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
769       *stride = static_cast<int>(alignedw);
770       *height = static_cast<int>(alignedh * 2);
771     }
772   }
773 }
774 
GetColorSpaceFromMetadata(private_handle_t * hnd,int * color_space)775 void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space) {
776   ColorMetaData color_metadata;
777   if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
778     switch (color_metadata.colorPrimaries) {
779       case ColorPrimaries_BT709_5:
780         *color_space = HAL_CSC_ITU_R_709;
781         break;
782       case ColorPrimaries_BT601_6_525:
783       case ColorPrimaries_BT601_6_625:
784         *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
785         break;
786       case ColorPrimaries_BT2020:
787         *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
788         break;
789       default:
790         ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
791         break;
792     }
793   } else if (getMetaData(hnd, GET_COLOR_SPACE, color_space) != 0) {
794     *color_space = 0;
795   }
796 }
797 
GetAlignedWidthAndHeight(const BufferInfo & info,unsigned int * alignedw,unsigned int * alignedh)798 void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
799                               unsigned int *alignedh) {
800   int width = info.width;
801   int height = info.height;
802   int format = info.format;
803   uint64_t usage = info.usage;
804 
805   // Currently surface padding is only computed for RGB* surfaces.
806   bool ubwc_enabled = IsUBwcEnabled(format, usage);
807   int tile = ubwc_enabled;
808 
809   if (IsUncompressedRGBFormat(format)) {
810     if (AdrenoMemInfo::GetInstance()) {
811       AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
812                                                          alignedh);
813     }
814     return;
815   }
816 
817   if (ubwc_enabled) {
818     GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
819     return;
820   }
821 
822   if (IsCompressedRGBFormat(format)) {
823     if (AdrenoMemInfo::GetInstance()) {
824       AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
825     }
826     return;
827   }
828 
829   int aligned_w = width;
830   int aligned_h = height;
831   unsigned int alignment = 32;
832 
833   // Below should be only YUV family
834   switch (format) {
835     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
836     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
837       if (AdrenoMemInfo::GetInstance() == nullptr) {
838         return;
839       }
840       alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
841       aligned_w = ALIGN(width, alignment);
842       break;
843     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
844       aligned_w = ALIGN(width, alignment);
845       break;
846     case HAL_PIXEL_FORMAT_RAW16:
847     case HAL_PIXEL_FORMAT_Y16:
848     case HAL_PIXEL_FORMAT_Y8:
849       aligned_w = ALIGN(width, 16);
850       break;
851     case HAL_PIXEL_FORMAT_RAW12:
852       aligned_w = ALIGN(width * 12 / 8, 16);
853       break;
854     case HAL_PIXEL_FORMAT_RAW10:
855       {
856         const unsigned int gpu_alignment =
857             AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
858         // gpu_alignment can return 1. Make sure it's at least 8.
859         const unsigned int raw10_alignment = std::max(gpu_alignment, 8u);
860         aligned_w = ALIGN(width * 10 / 8, raw10_alignment);
861       }
862       break;
863     case HAL_PIXEL_FORMAT_RAW8:
864       aligned_w = ALIGN(width, 16);
865       break;
866     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
867       aligned_w = ALIGN(width, 128);
868       break;
869     case HAL_PIXEL_FORMAT_YV12:
870     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
871     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
872     case HAL_PIXEL_FORMAT_YCbCr_422_I:
873     case HAL_PIXEL_FORMAT_YCrCb_422_I:
874     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
875       aligned_w = ALIGN(width, 16);
876       break;
877     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
878       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_P010, width) / 2);
879       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
880       break;
881     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
882     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
883       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
884       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
885       break;
886     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
887       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
888       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
889       break;
890     case HAL_PIXEL_FORMAT_BLOB:
891     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
892       break;
893     case HAL_PIXEL_FORMAT_NV21_ZSL:
894       aligned_w = ALIGN(width, 64);
895       aligned_h = ALIGN(height, 64);
896       break;
897     default:
898       break;
899   }
900 
901   *alignedw = (unsigned int)aligned_w;
902   *alignedh = (unsigned int)aligned_h;
903 }
904 
GetBufferLayout(private_handle_t * hnd,uint32_t stride[4],uint32_t offset[4],uint32_t * num_planes)905 int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
906                     uint32_t *num_planes) {
907   if (!hnd || !stride || !offset || !num_planes) {
908     return -EINVAL;
909   }
910 
911   struct android_ycbcr yuvPlaneInfo[2] = {};
912   *num_planes = 1;
913   stride[0] = 0;
914 
915   switch (hnd->format) {
916     case HAL_PIXEL_FORMAT_RGB_565:
917     case HAL_PIXEL_FORMAT_BGR_565:
918     case HAL_PIXEL_FORMAT_RGBA_5551:
919     case HAL_PIXEL_FORMAT_RGBA_4444:
920       stride[0] = static_cast<uint32_t>(hnd->width * 2);
921       break;
922     case HAL_PIXEL_FORMAT_RGB_888:
923       stride[0] = static_cast<uint32_t>(hnd->width * 3);
924       break;
925     case HAL_PIXEL_FORMAT_RGBA_8888:
926     case HAL_PIXEL_FORMAT_BGRA_8888:
927     case HAL_PIXEL_FORMAT_RGBX_8888:
928     case HAL_PIXEL_FORMAT_BGRX_8888:
929     case HAL_PIXEL_FORMAT_RGBA_1010102:
930     case HAL_PIXEL_FORMAT_ARGB_2101010:
931     case HAL_PIXEL_FORMAT_RGBX_1010102:
932     case HAL_PIXEL_FORMAT_XRGB_2101010:
933     case HAL_PIXEL_FORMAT_BGRA_1010102:
934     case HAL_PIXEL_FORMAT_ABGR_2101010:
935     case HAL_PIXEL_FORMAT_BGRX_1010102:
936     case HAL_PIXEL_FORMAT_XBGR_2101010:
937       stride[0] = static_cast<uint32_t>(hnd->width * 4);
938       break;
939   }
940 
941   // Format is RGB
942   if (stride[0]) {
943     return 0;
944   }
945 
946   (*num_planes)++;
947   int ret = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
948   if (ret < 0) {
949     ALOGE("%s failed", __FUNCTION__);
950     return ret;
951   }
952 
953   // We are only returning buffer layout for progressive or single field formats.
954   struct android_ycbcr yuvInfo = yuvPlaneInfo[0];
955   stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
956   offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
957   stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
958   switch (hnd->format) {
959     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
960     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
961     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
962     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
963     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
964     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
965     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
966     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
967     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
968       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
969       break;
970     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
971     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
972     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
973       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
974       break;
975     case HAL_PIXEL_FORMAT_YV12:
976       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
977       stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
978       offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
979       (*num_planes)++;
980       break;
981     default:
982       ALOGW("%s: Unsupported format", __FUNCTION__);
983       ret = -EINVAL;
984   }
985 
986   if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
987     std::fill(offset, offset + 4, 0);
988   }
989 
990   return 0;
991 }
992 
GetGpuResourceSizeAndDimensions(const BufferInfo & info,unsigned int * size,unsigned int * alignedw,unsigned int * alignedh,GraphicsMetadata * graphics_metadata)993 void GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
994                                      unsigned int *alignedw, unsigned int *alignedh,
995                                      GraphicsMetadata *graphics_metadata) {
996   GetAlignedWidthAndHeight(info, alignedw, alignedh);
997   AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
998   graphics_metadata->size = adreno_mem_info->AdrenoGetMetadataBlobSize();
999   uint64_t adreno_usage = info.usage;
1000   // If gralloc disables UBWC based on any of the checks,
1001   // we pass modified usage flag to adreno to convey this.
1002   int is_ubwc_enabled = IsUBwcEnabled(info.format, info.usage);
1003   if (!is_ubwc_enabled) {
1004     adreno_usage &= ~(GRALLOC_USAGE_PRIVATE_ALLOC_UBWC);
1005   } else {
1006     adreno_usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
1007   }
1008 
1009   // Call adreno api for populating metadata blob
1010   // Layer count is for 2D/Cubemap arrays and depth is used for 3D slice
1011   // Using depth to pass layer_count here
1012   int ret = adreno_mem_info->AdrenoInitMemoryLayout(graphics_metadata->data, info.width,
1013                                                     info.height, info.layer_count, /* depth */
1014                                                     info.format, 1, is_ubwc_enabled,
1015                                                     adreno_usage, 1);
1016   if (ret != 0) {
1017     ALOGE("%s Graphics metadata init failed", __FUNCTION__);
1018     *size = 0;
1019     return;
1020   }
1021   // Call adreno api with the metadata blob to get buffer size
1022   *size = adreno_mem_info->AdrenoGetAlignedGpuBufferSize(graphics_metadata->data);
1023 }
1024 
CanUseAdrenoForSize(int buffer_type,uint64_t usage)1025 bool CanUseAdrenoForSize(int buffer_type, uint64_t usage) {
1026   if (buffer_type == BUFFER_TYPE_VIDEO || !GetAdrenoSizeAPIStatus()) {
1027     return false;
1028   }
1029 
1030   if ((usage & BufferUsage::PROTECTED) && ((usage & BufferUsage::CAMERA_OUTPUT) ||
1031       (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY))) {
1032     return false;
1033   }
1034 
1035   return true;
1036 }
1037 
GetAdrenoSizeAPIStatus()1038 bool GetAdrenoSizeAPIStatus() {
1039   AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
1040   if (adreno_mem_info) {
1041     return adreno_mem_info->AdrenoSizeAPIAvaliable();
1042   }
1043   return false;
1044 }
1045 
GetBufferType(int inputFormat)1046 int GetBufferType(int inputFormat) {
1047   return IsYuvFormat(inputFormat) ? BUFFER_TYPE_VIDEO : BUFFER_TYPE_UI;
1048 }
1049 
1050 }  // namespace gralloc
1051