• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2011-2020, 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_NV21_ENCODEABLE:
51     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
52     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
53     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
54     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
55     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
56     case HAL_PIXEL_FORMAT_NV21_ZSL:
57     case HAL_PIXEL_FORMAT_RAW16:
58     case HAL_PIXEL_FORMAT_Y16:
59     case HAL_PIXEL_FORMAT_RAW12:
60     case HAL_PIXEL_FORMAT_RAW10:
61     case HAL_PIXEL_FORMAT_YV12:
62     case HAL_PIXEL_FORMAT_Y8:
63     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
64     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
65     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
66     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
67     // Below formats used by camera and VR
68     case HAL_PIXEL_FORMAT_BLOB:
69     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
70     case HAL_PIXEL_FORMAT_NV12_HEIF:
71     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
72       return true;
73     default:
74       return false;
75   }
76 }
77 
IsUncompressedRGBFormat(int format)78 bool IsUncompressedRGBFormat(int format) {
79   switch (format) {
80     case HAL_PIXEL_FORMAT_RGBA_8888:
81     case HAL_PIXEL_FORMAT_RGBX_8888:
82     case HAL_PIXEL_FORMAT_RGB_888:
83     case HAL_PIXEL_FORMAT_RGB_565:
84     case HAL_PIXEL_FORMAT_BGR_565:
85     case HAL_PIXEL_FORMAT_BGRA_8888:
86     case HAL_PIXEL_FORMAT_RGBA_5551:
87     case HAL_PIXEL_FORMAT_RGBA_4444:
88     case HAL_PIXEL_FORMAT_R_8:
89     case HAL_PIXEL_FORMAT_RG_88:
90     case HAL_PIXEL_FORMAT_BGRX_8888:
91     case HAL_PIXEL_FORMAT_RGBA_1010102:
92     case HAL_PIXEL_FORMAT_ARGB_2101010:
93     case HAL_PIXEL_FORMAT_RGBX_1010102:
94     case HAL_PIXEL_FORMAT_XRGB_2101010:
95     case HAL_PIXEL_FORMAT_BGRA_1010102:
96     case HAL_PIXEL_FORMAT_ABGR_2101010:
97     case HAL_PIXEL_FORMAT_BGRX_1010102:
98     case HAL_PIXEL_FORMAT_XBGR_2101010:
99     case HAL_PIXEL_FORMAT_RGBA_FP16:
100     case HAL_PIXEL_FORMAT_BGR_888:
101       return true;
102     default:
103       break;
104   }
105 
106   return false;
107 }
108 
IsCompressedRGBFormat(int format)109 bool IsCompressedRGBFormat(int format) {
110   switch (format) {
111     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
112     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
113     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
114     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
115     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
116     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
117     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
118     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
119     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
120     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
121     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
122     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
123     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
124     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
125     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
126     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
127     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
128     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
129     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
130     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
131     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
132     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
133     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
134     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
135     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
136     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
137     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
138     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
139       return true;
140     default:
141       break;
142   }
143 
144   return false;
145 }
146 
GetBppForUncompressedRGB(int format)147 uint32_t GetBppForUncompressedRGB(int format) {
148   uint32_t bpp = 0;
149   switch (format) {
150     case HAL_PIXEL_FORMAT_RGBA_FP16:
151       bpp = 8;
152       break;
153     case HAL_PIXEL_FORMAT_RGBA_8888:
154     case HAL_PIXEL_FORMAT_RGBX_8888:
155     case HAL_PIXEL_FORMAT_BGRA_8888:
156     case HAL_PIXEL_FORMAT_BGRX_8888:
157     case HAL_PIXEL_FORMAT_RGBA_1010102:
158     case HAL_PIXEL_FORMAT_ARGB_2101010:
159     case HAL_PIXEL_FORMAT_RGBX_1010102:
160     case HAL_PIXEL_FORMAT_XRGB_2101010:
161     case HAL_PIXEL_FORMAT_BGRA_1010102:
162     case HAL_PIXEL_FORMAT_ABGR_2101010:
163     case HAL_PIXEL_FORMAT_BGRX_1010102:
164     case HAL_PIXEL_FORMAT_XBGR_2101010:
165       bpp = 4;
166       break;
167     case HAL_PIXEL_FORMAT_RGB_888:
168     case HAL_PIXEL_FORMAT_BGR_888:
169       bpp = 3;
170       break;
171     case HAL_PIXEL_FORMAT_RGB_565:
172     case HAL_PIXEL_FORMAT_BGR_565:
173     case HAL_PIXEL_FORMAT_RGBA_5551:
174     case HAL_PIXEL_FORMAT_RGBA_4444:
175     case HAL_PIXEL_FORMAT_RG_88:
176       bpp = 2;
177       break;
178     case HAL_PIXEL_FORMAT_R_8:
179       bpp = 1;
180       break;
181     default:
182       ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
183       break;
184   }
185 
186   return bpp;
187 }
188 
CpuCanAccess(uint64_t usage)189 bool CpuCanAccess(uint64_t usage) {
190   return CpuCanRead(usage) || CpuCanWrite(usage);
191 }
192 
CpuCanRead(uint64_t usage)193 bool CpuCanRead(uint64_t usage) {
194   if (usage & BufferUsage::CPU_READ_MASK) {
195     return true;
196   }
197 
198   return false;
199 }
200 
CpuCanWrite(uint64_t usage)201 bool CpuCanWrite(uint64_t usage) {
202   if (usage & BufferUsage::CPU_WRITE_MASK) {
203     // Application intends to use CPU for rendering
204     return true;
205   }
206 
207   return false;
208 }
209 
GetDataAlignment(int format,uint64_t usage)210 uint32_t GetDataAlignment(int format, uint64_t usage) {
211   uint32_t align = UINT(getpagesize());
212   if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
213     align = SIZE_8K;
214   }
215 
216   if (usage & BufferUsage::PROTECTED) {
217     if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
218       align = SZ_2M;
219     } else {
220       align = SECURE_ALIGN;
221     }
222   }
223 
224   return align;
225 }
226 
IsGPUFlagSupported(uint64_t usage)227 bool IsGPUFlagSupported(uint64_t usage) {
228   bool ret = true;
229   if ((usage & BufferUsage::GPU_MIPMAP_COMPLETE)) {
230     ALOGE("GPU_MIPMAP_COMPLETE not supported");
231     ret = false;
232   }
233 
234   if ((usage & BufferUsage::GPU_CUBE_MAP)) {
235     ALOGE("GPU_CUBE_MAP not supported");
236     ret = false;
237   }
238 
239   return ret;
240 }
241 
GetBpp(int format)242 int GetBpp(int format) {
243   if (IsUncompressedRGBFormat(format)) {
244     return GetBppForUncompressedRGB(format);
245   }
246   switch (format) {
247     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
248     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
249     case HAL_PIXEL_FORMAT_RAW8:
250     case HAL_PIXEL_FORMAT_Y8:
251       return 1;
252     case HAL_PIXEL_FORMAT_RAW16:
253     case HAL_PIXEL_FORMAT_Y16:
254     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
255     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
256     case HAL_PIXEL_FORMAT_YCbCr_422_I:
257     case HAL_PIXEL_FORMAT_YCrCb_422_I:
258     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
259       return 2;
260     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
261     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
262       return 3;
263     default:
264       return -1;
265   }
266 }
267 
268 // Returns the final buffer size meant to be allocated with ion
GetSize(const BufferInfo & info,unsigned int alignedw,unsigned int alignedh)269 unsigned int GetSize(const BufferInfo &info, unsigned int alignedw, unsigned int alignedh) {
270   unsigned int size = 0;
271   int format = info.format;
272   int width = info.width;
273   int height = info.height;
274   uint64_t usage = info.usage;
275 
276   if (!IsGPUFlagSupported(usage)) {
277     ALOGE("Unsupported GPU usage flags present 0x%" PRIx64, usage);
278     return 0;
279   }
280 
281   if (IsUBwcEnabled(format, usage)) {
282     size = GetUBwcSize(width, height, format, alignedw, alignedh);
283   } else if (IsUncompressedRGBFormat(format)) {
284     uint32_t bpp = GetBppForUncompressedRGB(format);
285     size = alignedw * alignedh * bpp;
286   } else if (IsCompressedRGBFormat(format)) {
287     size = alignedw * alignedh * ASTC_BLOCK_SIZE;
288   } else {
289     // Below switch should be for only YUV/custom formats
290     switch (format) {
291       case HAL_PIXEL_FORMAT_RAW16:
292       case HAL_PIXEL_FORMAT_Y16:size = alignedw * alignedh * 2;
293         break;
294       case HAL_PIXEL_FORMAT_RAW10:
295       case HAL_PIXEL_FORMAT_RAW12:size = ALIGN(alignedw * alignedh, SIZE_4K);
296         break;
297       case HAL_PIXEL_FORMAT_RAW8:
298       case HAL_PIXEL_FORMAT_Y8:size = alignedw * alignedh * 1;
299         break;
300         // adreno formats
301       case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
302         size = ALIGN(alignedw * alignedh, SIZE_4K);
303         size += (unsigned int) ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
304         break;
305       case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:  // NV12
306         // The chroma plane is subsampled,
307         // but the pitch in bytes is unchanged
308         // The GPU needs 4K alignment, but the video decoder needs 8K
309         size = ALIGN(alignedw * alignedh, SIZE_8K);
310         size += ALIGN(alignedw * (unsigned int) ALIGN(height / 2, 32), SIZE_8K);
311         break;
312       case HAL_PIXEL_FORMAT_YV12:
313         if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
314           ALOGE("w or h is odd for the YV12 format");
315           return 0;
316         }
317         size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
318         size = ALIGN(size, (unsigned int) SIZE_4K);
319         break;
320       case HAL_PIXEL_FORMAT_YCbCr_420_SP:
321       case HAL_PIXEL_FORMAT_YCrCb_420_SP:
322         size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
323         break;
324       case HAL_PIXEL_FORMAT_YCbCr_420_P010:
325         size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
326         break;
327       case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
328         size = VENUS_BUFFER_SIZE(COLOR_FMT_P010,
329                                  width,
330                                  height);
331         break;
332       case HAL_PIXEL_FORMAT_YCbCr_422_SP:
333       case HAL_PIXEL_FORMAT_YCrCb_422_SP:
334       case HAL_PIXEL_FORMAT_YCbCr_422_I:
335       case HAL_PIXEL_FORMAT_YCrCb_422_I:
336       case HAL_PIXEL_FORMAT_CbYCrY_422_I:
337         if (width & 1) {
338           ALOGE("width is odd for the YUV422_SP format");
339           return 0;
340         }
341         size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
342         break;
343       case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
344       case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
345         size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
346         break;
347       case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
348       case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
349         size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
350         break;
351       case HAL_PIXEL_FORMAT_BLOB:
352       case HAL_PIXEL_FORMAT_RAW_OPAQUE:
353         if (height != 1) {
354           ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
355           return 0;
356         }
357         size = (unsigned int) width;
358         break;
359       case HAL_PIXEL_FORMAT_NV21_ZSL:
360         size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2,
361                      SIZE_4K);
362         break;
363       case HAL_PIXEL_FORMAT_NV12_HEIF:
364         size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_512, width, height);
365         break;
366       default:ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
367         return 0;
368     }
369   }
370   auto align = GetDataAlignment(format, usage);
371   size = ALIGN(size, align) * info.layer_count;
372   return size;
373 }
374 
GetBufferSizeAndDimensions(const BufferInfo & info,unsigned int * size,unsigned int * alignedw,unsigned int * alignedh)375 int GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
376                                unsigned int *alignedh) {
377   GraphicsMetadata graphics_metadata = {};
378   return GetBufferSizeAndDimensions(info, size, alignedw, alignedh, &graphics_metadata);
379 }
380 
GetBufferSizeAndDimensions(const BufferInfo & info,unsigned int * size,unsigned int * alignedw,unsigned int * alignedh,GraphicsMetadata * graphics_metadata)381 int GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
382                                unsigned int *alignedh, GraphicsMetadata *graphics_metadata) {
383   int buffer_type = GetBufferType(info.format);
384   if (CanUseAdrenoForSize(buffer_type, info.usage)) {
385     return GetGpuResourceSizeAndDimensions(info, size, alignedw, alignedh, graphics_metadata);
386   } else {
387     GetAlignedWidthAndHeight(info, alignedw, alignedh);
388     *size = GetSize(info, *alignedw, *alignedh);
389   }
390   return 0;
391 }
392 
GetYuvUbwcSPPlaneInfo(uint32_t width,uint32_t height,int color_format,PlaneLayoutInfo * plane_info)393 void GetYuvUbwcSPPlaneInfo(uint32_t width, uint32_t height, int color_format,
394                            PlaneLayoutInfo *plane_info) {
395   // UBWC buffer has these 4 planes in the following sequence:
396   // Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane
397   unsigned int y_meta_stride, y_meta_height, y_meta_size;
398   unsigned int y_stride, y_height, y_size;
399   unsigned int c_meta_stride, c_meta_height, c_meta_size;
400   unsigned int alignment = 4096;
401   unsigned int c_stride, c_height, c_size;
402   uint64_t yOffset, cOffset, yMetaOffset, cMetaOffset;
403 
404   y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
405   y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
406   y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
407 
408   y_stride = VENUS_Y_STRIDE(color_format, INT(width));
409   y_height = VENUS_Y_SCANLINES(color_format, INT(height));
410   y_size = ALIGN((y_stride * y_height), alignment);
411 
412   c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
413   c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
414   c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
415 
416   c_stride = VENUS_UV_STRIDE(color_format, INT(width));
417   c_height = VENUS_UV_SCANLINES(color_format, INT(height));
418   c_size = ALIGN((c_stride * c_height), alignment);
419 
420   yMetaOffset = 0;
421   yOffset = y_meta_size;
422   cMetaOffset = y_meta_size + y_size;
423   cOffset = y_meta_size + y_size + c_meta_size;
424 
425   plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
426   plane_info[0].offset = (uint32_t)yOffset;
427   plane_info[0].stride = static_cast<int32_t>(UINT(width));
428   plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
429   plane_info[0].scanlines = static_cast<int32_t>(y_height);
430   plane_info[0].size = static_cast<uint32_t>(y_size);
431 
432   plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
433   plane_info[1].offset = (uint32_t)cOffset;
434   plane_info[1].stride = static_cast<int32_t>(UINT(width));
435   plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
436   plane_info[1].scanlines = static_cast<int32_t>(c_height);
437   plane_info[1].size = static_cast<uint32_t>(c_size);
438 
439   plane_info[2].component = (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Y);
440   plane_info[2].offset = (uint32_t)yMetaOffset;
441   plane_info[2].stride = static_cast<int32_t>(UINT(width));
442   plane_info[2].stride_bytes = static_cast<int32_t>(y_meta_stride);
443   plane_info[2].scanlines = static_cast<int32_t>(y_meta_height);
444   plane_info[2].size = static_cast<uint32_t>(y_meta_size);
445 
446   plane_info[3].component =
447       (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
448   plane_info[3].offset = (uint32_t)cMetaOffset;
449   plane_info[3].stride = static_cast<int32_t>(UINT(width));
450   plane_info[3].stride_bytes = static_cast<int32_t>(c_meta_stride);
451   plane_info[3].scanlines = static_cast<int32_t>(c_meta_height);
452   plane_info[3].size = static_cast<uint32_t>(c_meta_size);
453 }
454 
455 // This API gets information about 8 planes (Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane,
456 // Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane) and it stores the
457 // information in PlaneLayoutInfo array.
GetYuvUbwcInterlacedSPPlaneInfo(uint32_t width,uint32_t height,PlaneLayoutInfo plane_info[8])458 void GetYuvUbwcInterlacedSPPlaneInfo(uint32_t width, uint32_t height,
459                                      PlaneLayoutInfo plane_info[8]) {
460   // UBWC interlaced has top-bottom field layout with each field as
461   // 8-plane (including meta plane also) NV12_UBWC with width = image_width
462   // & height = image_height / 2.
463   // Client passed plane_info argument is ptr to struct PlaneLayoutInfo[8].
464   // Plane info to be filled for each field separately.
465   height = (height + 1) >> 1;
466 
467   GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, &plane_info[0]);
468 
469   GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, &plane_info[4]);
470 }
471 
472 // This API gets information about 2 planes (Y_Plane & UV_Plane)
GetYuvSPPlaneInfo(const BufferInfo & info,int format,uint32_t width,uint32_t height,uint32_t bpp,PlaneLayoutInfo * plane_info)473 void GetYuvSPPlaneInfo(const BufferInfo &info, int format, uint32_t width, uint32_t height,
474                        uint32_t bpp, PlaneLayoutInfo *plane_info) {
475   int unaligned_width = info.width;
476   int unaligned_height = info.height;
477   unsigned int y_stride = 0, y_height = 0, y_size = 0;
478   unsigned int c_stride = 0, c_height = 0, c_size = 0;
479   uint64_t yOffset, cOffset;
480 
481   y_stride = c_stride = UINT(width) * bpp;
482   y_height = INT(height);
483   y_size = y_stride * y_height;
484   switch (format) {
485     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
486     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
487       c_size = (width * height) / 2 + 1;
488       c_height = height >> 1;
489       break;
490     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
491     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
492       if (unaligned_width & 1) {
493         ALOGE("width is odd for the YUV422_SP format");
494         return;
495       }
496       c_size = width * height;
497       c_height = height;
498       break;
499     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
500     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
501       c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height);
502       c_size = c_stride * c_height;
503       break;
504     case HAL_PIXEL_FORMAT_NV12_HEIF:
505       c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12_512, height);
506       c_size = c_stride * c_height;
507       break;
508     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
509       y_size = ALIGN(width * height, 4096);
510       c_size = ALIGN(2 * ALIGN(unaligned_width / 2, 32) * ALIGN(unaligned_height / 2, 32), 4096);
511       break;
512     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
513     case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
514       c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV21, height);
515       c_size = c_stride * c_height;
516       break;
517     case HAL_PIXEL_FORMAT_NV21_ZSL:
518       c_size = (width * height) / 2;
519       c_height = height >> 1;
520       break;
521     case HAL_PIXEL_FORMAT_RAW16:
522     case HAL_PIXEL_FORMAT_Y16:
523       c_size = width * height;
524       c_height = height;
525       break;
526     case HAL_PIXEL_FORMAT_RAW10:
527       c_size = 0;
528       break;
529     case HAL_PIXEL_FORMAT_RAW8:
530     case HAL_PIXEL_FORMAT_Y8:
531       c_size = 0;
532       break;
533     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
534       c_size = (width * height) + 1;
535       c_height = height;
536       break;
537     default:
538       break;
539   }
540 
541   yOffset = 0;
542   cOffset = y_size;
543 
544   plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
545   plane_info[0].offset = (uint32_t)yOffset;
546   plane_info[0].step = 1;
547   plane_info[0].stride = static_cast<int32_t>(UINT(width));
548   plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
549   plane_info[0].scanlines = static_cast<int32_t>(y_height);
550   plane_info[0].size = static_cast<uint32_t>(y_size);
551 
552   plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
553   plane_info[1].offset = (uint32_t)cOffset;
554   plane_info[1].step = 2 * bpp;
555   plane_info[1].stride = static_cast<int32_t>(UINT(width));
556   plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
557   plane_info[1].scanlines = static_cast<int32_t>(c_height);
558   plane_info[1].size = static_cast<uint32_t>(c_size);
559 }
560 
GetYUVPlaneInfo(const private_handle_t * hnd,struct android_ycbcr ycbcr[2])561 int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
562   int err = 0;
563   uint32_t width = UINT(hnd->width);
564   uint32_t height = UINT(hnd->height);
565   int format = hnd->format;
566   uint64_t usage = hnd->usage;
567   int32_t interlaced = 0;
568   int plane_count = 0;
569   int unaligned_width = INT(hnd->unaligned_width);
570   int unaligned_height = INT(hnd->unaligned_height);
571   BufferInfo info(unaligned_width, unaligned_height, format, usage);
572 
573   memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
574 
575   // Check if UBWC buffer has been rendered in linear format.
576   int linear_format = 0;
577   if (getMetaData(const_cast<private_handle_t *>(hnd), GET_LINEAR_FORMAT, &linear_format) == 0) {
578     format = INT(linear_format);
579   }
580 
581   // Check metadata if the geometry has been updated.
582   BufferDim_t buffer_dim;
583   if (getMetaData(const_cast<private_handle_t *>(hnd), GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
584     BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format, usage);
585     GetAlignedWidthAndHeight(info, &width, &height);
586   }
587 
588   // Check metadata for interlaced content.
589   int interlace_flag = 0;
590   if (getMetaData(const_cast<private_handle_t *>(hnd), GET_PP_PARAM_INTERLACED, &interlace_flag) ==
591       0) {
592     if (interlace_flag) {
593       interlaced = LAYOUT_INTERLACED_FLAG;
594     }
595   }
596 
597   PlaneLayoutInfo plane_info[8] = {};
598   // Get the chroma offsets from the handle width/height. We take advantage
599   // of the fact the width _is_ the stride
600   err = GetYUVPlaneInfo(info, format, width, height, interlaced, &plane_count, plane_info);
601   if (err == 0) {
602     if (interlaced && format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC) {
603       CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, &plane_info[0], &ycbcr[0]);
604       unsigned int uv_stride, uv_height, uv_size;
605       unsigned int alignment = 4096;
606       uint64_t field_base;
607       height = (height + 1) >> 1;
608       uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, INT(width));
609       uv_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, INT(height));
610       uv_size = ALIGN((uv_stride * uv_height), alignment);
611       field_base = hnd->base + plane_info[1].offset + uv_size;
612       memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
613       CopyPlaneLayoutInfotoAndroidYcbcr(field_base, plane_count, &plane_info[4], &ycbcr[1]);
614     } else {
615       CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, plane_info, ycbcr);
616       switch (format) {
617         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
618         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
619         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
620         case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
621         case HAL_PIXEL_FORMAT_NV21_ZSL:
622         case HAL_PIXEL_FORMAT_RAW16:
623         case HAL_PIXEL_FORMAT_Y16:
624         case HAL_PIXEL_FORMAT_RAW10:
625         case HAL_PIXEL_FORMAT_RAW8:
626         case HAL_PIXEL_FORMAT_Y8:
627           std::swap(ycbcr->cb, ycbcr->cr);
628       }
629     }
630   }
631   return err;
632 }
633 
634 // Explicitly defined UBWC formats
IsUBwcFormat(int format)635 bool IsUBwcFormat(int format) {
636   switch (format) {
637     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
638     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
639     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
640       return true;
641     default:
642       return false;
643   }
644 }
645 
IsUBwcSupported(int format)646 bool IsUBwcSupported(int format) {
647   // Existing HAL formats with UBWC support
648   switch (format) {
649     case HAL_PIXEL_FORMAT_BGR_565:
650     case HAL_PIXEL_FORMAT_RGBA_8888:
651     case HAL_PIXEL_FORMAT_RGBX_8888:
652     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
653     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
654     case HAL_PIXEL_FORMAT_RGBA_1010102:
655     case HAL_PIXEL_FORMAT_RGBX_1010102:
656     case HAL_PIXEL_FORMAT_DEPTH_16:
657     case HAL_PIXEL_FORMAT_DEPTH_24:
658     case HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
659     case HAL_PIXEL_FORMAT_DEPTH_32F:
660     case HAL_PIXEL_FORMAT_STENCIL_8:
661       return true;
662     default:
663       break;
664   }
665 
666   return false;
667 }
668 
IsUBwcPISupported(int format,uint64_t usage)669 bool IsUBwcPISupported(int format, uint64_t usage) {
670   if (usage & BufferUsage::COMPOSER_OVERLAY || !(usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI)) {
671     return false;
672   }
673 
674   // As of now only two formats
675   switch (format) {
676     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
677     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: {
678       if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
679         if (AdrenoMemInfo::GetInstance()) {
680           return AdrenoMemInfo::GetInstance()->IsPISupportedByGPU(format, usage);
681         }
682       } else {
683         return true;
684       }
685     }
686   }
687 
688   return false;
689 }
690 
IsUBwcEnabled(int format,uint64_t usage)691 bool IsUBwcEnabled(int format, uint64_t usage) {
692   // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
693   if (IsUBwcFormat(format)) {
694     return true;
695   }
696 
697   // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
698   // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
699   // usage flag and MDP supports the format.
700   if (((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) ||
701        (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI) ||
702        (usage & BufferUsage::COMPOSER_CLIENT_TARGET))
703         && IsUBwcSupported(format)) {
704     bool enable = true;
705     // Query GPU for UBWC only if buffer is intended to be used by GPU.
706     if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
707       if (AdrenoMemInfo::GetInstance()) {
708         enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
709       }
710     }
711 
712     // Allow UBWC, only if CPU usage flags are not set
713     if (enable && !(CpuCanAccess(usage))) {
714       return true;
715     }
716   }
717 
718   return false;
719 }
720 
GetYuvUBwcWidthAndHeight(int width,int height,int format,unsigned int * aligned_w,unsigned int * aligned_h)721 void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
722                               unsigned int *aligned_h) {
723   switch (format) {
724     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
725     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
726     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
727       *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
728       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
729       break;
730     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
731       // The macro returns the stride which is 4/3 times the width, hence * 3/4
732       *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
733       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
734       break;
735     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
736       // The macro returns the stride which is 2 times the width, hence / 2
737       *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
738       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
739       break;
740     default:
741       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
742       *aligned_w = 0;
743       *aligned_h = 0;
744       break;
745   }
746 }
747 
GetRgbUBwcBlockSize(uint32_t bpp,int * block_width,int * block_height)748 void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
749   *block_width = 0;
750   *block_height = 0;
751 
752   switch (bpp) {
753     case 2:
754     case 4:
755       *block_width = 16;
756       *block_height = 4;
757       break;
758     case 8:
759       *block_width = 8;
760       *block_height = 4;
761       break;
762     case 16:
763       *block_width = 4;
764       *block_height = 4;
765       break;
766     default:
767       ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
768       break;
769   }
770 }
771 
GetRgbUBwcMetaBufferSize(int width,int height,uint32_t bpp)772 unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
773   unsigned int size = 0;
774   int meta_width, meta_height;
775   int block_width, block_height;
776 
777   GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
778   if (!block_width || !block_height) {
779     ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
780     return size;
781   }
782 
783   // Align meta buffer height to 16 blocks
784   meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
785 
786   // Align meta buffer width to 64 blocks
787   meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
788 
789   // Align meta buffer size to 4K
790   size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
791 
792   return size;
793 }
794 
GetUBwcSize(int width,int height,int format,unsigned int alignedw,unsigned int alignedh)795 unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
796                          unsigned int alignedh) {
797   unsigned int size = 0;
798   uint32_t bpp = 0;
799   switch (format) {
800     case HAL_PIXEL_FORMAT_BGR_565:
801     case HAL_PIXEL_FORMAT_RGBA_8888:
802     case HAL_PIXEL_FORMAT_RGBX_8888:
803     case HAL_PIXEL_FORMAT_RGBA_1010102:
804     case HAL_PIXEL_FORMAT_RGBX_1010102:
805       bpp = GetBppForUncompressedRGB(format);
806       size = alignedw * alignedh * bpp;
807       size += GetRgbUBwcMetaBufferSize(width, height, bpp);
808       break;
809     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
810     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
811     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
812       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
813       break;
814     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
815       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
816       break;
817     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
818       size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
819       break;
820     default:
821       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
822       break;
823   }
824 
825   return size;
826 }
827 
GetRgbMetaSize(int format,uint32_t width,uint32_t height,uint64_t usage)828 unsigned int GetRgbMetaSize(int format, uint32_t width, uint32_t height, uint64_t usage) {
829   unsigned int meta_size = 0;
830   if (!IsUBwcEnabled(format, usage)) {
831     return meta_size;
832   }
833   uint32_t bpp = GetBppForUncompressedRGB(format);
834   switch (format) {
835     case HAL_PIXEL_FORMAT_BGR_565:
836     case HAL_PIXEL_FORMAT_RGBA_8888:
837     case HAL_PIXEL_FORMAT_RGBX_8888:
838     case HAL_PIXEL_FORMAT_RGBA_1010102:
839     case HAL_PIXEL_FORMAT_RGBX_1010102:
840     case HAL_PIXEL_FORMAT_RGBA_FP16:
841       meta_size = GetRgbUBwcMetaBufferSize(width, height, bpp);
842       break;
843     default:
844       ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, format);
845       break;
846   }
847   return meta_size;
848 }
849 
GetRgbDataAddress(private_handle_t * hnd,void ** rgb_data)850 int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
851   int err = 0;
852 
853   // This api is for RGB* formats
854   if (!IsUncompressedRGBFormat(hnd->format)) {
855     return -EINVAL;
856   }
857 
858   // linear buffer, nothing to do further
859   if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
860     *rgb_data = reinterpret_cast<void *>(hnd->base);
861     return err;
862   }
863   unsigned int meta_size = GetRgbMetaSize(hnd->format, hnd->width, hnd->height, hnd->usage);
864 
865   *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
866 
867   return err;
868 }
869 
GetCustomDimensions(private_handle_t * hnd,int * stride,int * height)870 void GetCustomDimensions(private_handle_t *hnd, int *stride, int *height) {
871   BufferDim_t buffer_dim;
872   int interlaced = 0;
873 
874   *stride = hnd->width;
875   *height = hnd->height;
876   if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
877     *stride = buffer_dim.sliceWidth;
878     *height = buffer_dim.sliceHeight;
879   } else if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
880     if (interlaced && IsUBwcFormat(hnd->format)) {
881       unsigned int alignedw = 0, alignedh = 0;
882       // Get re-aligned height for single ubwc interlaced field and
883       // multiply by 2 to get frame height.
884       BufferInfo info(hnd->width, ((hnd->height + 1) >> 1), hnd->format);
885       GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
886       *stride = static_cast<int>(alignedw);
887       *height = static_cast<int>(alignedh * 2);
888     }
889   }
890 }
891 
GetColorSpaceFromMetadata(private_handle_t * hnd,int * color_space)892 void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space) {
893   ColorMetaData color_metadata;
894   if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
895     switch (color_metadata.colorPrimaries) {
896       case ColorPrimaries_BT709_5:
897         *color_space = HAL_CSC_ITU_R_709;
898         break;
899       case ColorPrimaries_BT601_6_525:
900       case ColorPrimaries_BT601_6_625:
901         *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
902         break;
903       case ColorPrimaries_BT2020:
904         *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
905         break;
906       default:
907         ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
908         break;
909     }
910   } else if (getMetaData(hnd, GET_COLOR_SPACE, color_space) != 0) {
911     *color_space = 0;
912   }
913 }
914 
GetAlignedWidthAndHeight(const BufferInfo & info,unsigned int * alignedw,unsigned int * alignedh)915 void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
916                               unsigned int *alignedh) {
917   int width = info.width;
918   int height = info.height;
919   int format = info.format;
920   uint64_t usage = info.usage;
921 
922   // Currently surface padding is only computed for RGB* surfaces.
923   bool ubwc_enabled = IsUBwcEnabled(format, usage);
924   int tile = ubwc_enabled;
925 
926   if (IsUncompressedRGBFormat(format)) {
927     if (AdrenoMemInfo::GetInstance()) {
928       AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
929                                                          alignedh);
930     }
931     return;
932   }
933 
934   if (ubwc_enabled) {
935     GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
936     return;
937   }
938 
939   if (IsCompressedRGBFormat(format)) {
940     if (AdrenoMemInfo::GetInstance()) {
941       AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
942     }
943     return;
944   }
945 
946   int aligned_w = width;
947   int aligned_h = height;
948   unsigned int alignment = 32;
949 
950   // Below should be only YUV family
951   switch (format) {
952     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
953     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
954       if (AdrenoMemInfo::GetInstance() == nullptr) {
955         return;
956       }
957       alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
958       aligned_w = ALIGN(width, alignment);
959       break;
960     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
961       aligned_w = ALIGN(width, alignment);
962       break;
963     case HAL_PIXEL_FORMAT_RAW16:
964     case HAL_PIXEL_FORMAT_Y16:
965     case HAL_PIXEL_FORMAT_Y8:
966       aligned_w = ALIGN(width, 16);
967       break;
968     case HAL_PIXEL_FORMAT_RAW12:
969       aligned_w = ALIGN(width * 12 / 8, 16);
970       break;
971     case HAL_PIXEL_FORMAT_RAW10:
972       {
973         const unsigned int gpu_alignment =
974             AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
975         // gpu_alignment can return 1. Make sure it's at least 64.
976         const unsigned int raw10_alignment = std::max(gpu_alignment, 64u);
977         aligned_w = ALIGN(width * 10 / 8, raw10_alignment);
978       }
979       break;
980     case HAL_PIXEL_FORMAT_RAW8:
981       aligned_w = ALIGN(width, 16);
982       break;
983     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
984       aligned_w = ALIGN(width, 128);
985       break;
986     case HAL_PIXEL_FORMAT_YV12:
987     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
988     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
989     case HAL_PIXEL_FORMAT_YCbCr_422_I:
990     case HAL_PIXEL_FORMAT_YCrCb_422_I:
991     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
992       aligned_w = ALIGN(width, 16);
993       break;
994     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
995       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_P010, width) / 2);
996       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
997       break;
998     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
999     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1000       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
1001       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
1002       break;
1003     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1004     case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
1005       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
1006       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
1007       break;
1008     case HAL_PIXEL_FORMAT_BLOB:
1009     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1010       break;
1011     case HAL_PIXEL_FORMAT_NV21_ZSL:
1012       aligned_w = ALIGN(width, 64);
1013       aligned_h = ALIGN(height, 64);
1014       break;
1015     case HAL_PIXEL_FORMAT_NV12_HEIF:
1016       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12_512, width));
1017       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12_512, height));
1018       break;
1019     default:
1020       break;
1021   }
1022 
1023   *alignedw = (unsigned int)aligned_w;
1024   *alignedh = (unsigned int)aligned_h;
1025 }
1026 
GetBufferLayout(private_handle_t * hnd,uint32_t stride[4],uint32_t offset[4],uint32_t * num_planes)1027 int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
1028                     uint32_t *num_planes) {
1029   if (!hnd || !stride || !offset || !num_planes) {
1030     return -EINVAL;
1031   }
1032 
1033   struct android_ycbcr yuvPlaneInfo[2] = {};
1034   *num_planes = 1;
1035   stride[0] = 0;
1036 
1037   switch (hnd->format) {
1038     case HAL_PIXEL_FORMAT_RGB_565:
1039     case HAL_PIXEL_FORMAT_BGR_565:
1040     case HAL_PIXEL_FORMAT_RGBA_5551:
1041     case HAL_PIXEL_FORMAT_RGBA_4444:
1042       stride[0] = static_cast<uint32_t>(hnd->width * 2);
1043       break;
1044     case HAL_PIXEL_FORMAT_RGB_888:
1045       stride[0] = static_cast<uint32_t>(hnd->width * 3);
1046       break;
1047     case HAL_PIXEL_FORMAT_RGBA_8888:
1048     case HAL_PIXEL_FORMAT_BGRA_8888:
1049     case HAL_PIXEL_FORMAT_RGBX_8888:
1050     case HAL_PIXEL_FORMAT_BGRX_8888:
1051     case HAL_PIXEL_FORMAT_RGBA_1010102:
1052     case HAL_PIXEL_FORMAT_ARGB_2101010:
1053     case HAL_PIXEL_FORMAT_RGBX_1010102:
1054     case HAL_PIXEL_FORMAT_XRGB_2101010:
1055     case HAL_PIXEL_FORMAT_BGRA_1010102:
1056     case HAL_PIXEL_FORMAT_ABGR_2101010:
1057     case HAL_PIXEL_FORMAT_BGRX_1010102:
1058     case HAL_PIXEL_FORMAT_XBGR_2101010:
1059       stride[0] = static_cast<uint32_t>(hnd->width * 4);
1060       break;
1061   }
1062 
1063   // Format is RGB
1064   if (stride[0]) {
1065     return 0;
1066   }
1067 
1068   (*num_planes)++;
1069   int ret = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
1070   if (ret < 0) {
1071     ALOGE("%s failed", __FUNCTION__);
1072     return ret;
1073   }
1074 
1075   // We are only returning buffer layout for progressive or single field formats.
1076   struct android_ycbcr yuvInfo = yuvPlaneInfo[0];
1077   stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
1078   offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
1079   stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
1080   switch (hnd->format) {
1081     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1082     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1083     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1084     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1085     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1086     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1087     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1088     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1089     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1090     case HAL_PIXEL_FORMAT_NV12_HEIF:
1091       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
1092       break;
1093     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1094     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1095     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1096     case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
1097       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
1098       break;
1099     case HAL_PIXEL_FORMAT_YV12:
1100       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
1101       stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
1102       offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
1103       (*num_planes)++;
1104       break;
1105     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1106       *num_planes = 1;
1107       break;
1108     default:
1109       ALOGW("%s: Unsupported format", __FUNCTION__);
1110       ret = -EINVAL;
1111   }
1112 
1113   if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
1114     std::fill(offset, offset + 4, 0);
1115   }
1116 
1117   return 0;
1118 }
1119 
GetGpuResourceSizeAndDimensions(const BufferInfo & info,unsigned int * size,unsigned int * alignedw,unsigned int * alignedh,GraphicsMetadata * graphics_metadata)1120 int GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
1121                                     unsigned int *alignedw, unsigned int *alignedh,
1122                                     GraphicsMetadata *graphics_metadata) {
1123   GetAlignedWidthAndHeight(info, alignedw, alignedh);
1124   AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
1125   graphics_metadata->size = adreno_mem_info->AdrenoGetMetadataBlobSize();
1126   uint64_t adreno_usage = info.usage;
1127   // If gralloc disables UBWC based on any of the checks,
1128   // we pass modified usage flag to adreno to convey this.
1129   int is_ubwc_enabled = IsUBwcEnabled(info.format, info.usage);
1130   if (!is_ubwc_enabled) {
1131     adreno_usage &= ~(GRALLOC_USAGE_PRIVATE_ALLOC_UBWC);
1132   } else {
1133     adreno_usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
1134   }
1135 
1136   // Call adreno api for populating metadata blob
1137   // Layer count is for 2D/Cubemap arrays and depth is used for 3D slice
1138   // Using depth to pass layer_count here
1139   int ret = adreno_mem_info->AdrenoInitMemoryLayout(graphics_metadata->data, info.width,
1140                                                     info.height, info.layer_count, /* depth */
1141                                                     info.format, 1, is_ubwc_enabled,
1142                                                     adreno_usage, 1);
1143   if (ret != 0) {
1144     ALOGE("%s Graphics metadata init failed", __FUNCTION__);
1145     *size = 0;
1146     return -EINVAL;
1147   }
1148   // Call adreno api with the metadata blob to get buffer size
1149   *size = adreno_mem_info->AdrenoGetAlignedGpuBufferSize(graphics_metadata->data);
1150   return 0;
1151 }
1152 
CanUseAdrenoForSize(int buffer_type,uint64_t usage)1153 bool CanUseAdrenoForSize(int buffer_type, uint64_t usage) {
1154   if (buffer_type == BUFFER_TYPE_VIDEO || !GetAdrenoSizeAPIStatus()) {
1155     return false;
1156   }
1157 
1158   if ((usage & BufferUsage::PROTECTED) && ((usage & BufferUsage::CAMERA_OUTPUT) ||
1159       (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY))) {
1160     return false;
1161   }
1162 
1163   return true;
1164 }
1165 
GetAdrenoSizeAPIStatus()1166 bool GetAdrenoSizeAPIStatus() {
1167   AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
1168   if (adreno_mem_info) {
1169     return adreno_mem_info->AdrenoSizeAPIAvaliable();
1170   }
1171   return false;
1172 }
1173 
UseUncached(int format,uint64_t usage)1174 bool UseUncached(int format, uint64_t usage) {
1175   if ((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) || (usage & BufferUsage::PROTECTED)) {
1176     return true;
1177   }
1178 
1179   // CPU read rarely
1180   if ((usage & BufferUsage::CPU_READ_MASK) == static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) {
1181     return true;
1182   }
1183 
1184   // CPU  write rarely
1185   if ((usage & BufferUsage::CPU_WRITE_MASK) ==
1186       static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) {
1187     return true;
1188   }
1189 
1190   if ((usage & BufferUsage::SENSOR_DIRECT_DATA) || (usage & BufferUsage::GPU_DATA_BUFFER)) {
1191     return true;
1192   }
1193 
1194   if (format && IsUBwcEnabled(format, usage)) {
1195     return true;
1196   }
1197 
1198   return false;
1199 }
1200 
GetHandleFlags(int format,uint64_t usage)1201 uint64_t GetHandleFlags(int format, uint64_t usage) {
1202   uint64_t priv_flags = 0;
1203 
1204   if (usage & BufferUsage::VIDEO_ENCODER) {
1205     priv_flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
1206   }
1207 
1208   if (usage & BufferUsage::CAMERA_OUTPUT) {
1209     priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
1210   }
1211 
1212   if (usage & BufferUsage::CAMERA_INPUT) {
1213     priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
1214   }
1215 
1216   if (usage & BufferUsage::COMPOSER_OVERLAY) {
1217     priv_flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
1218   }
1219 
1220   if (usage & BufferUsage::GPU_TEXTURE) {
1221     priv_flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
1222   }
1223 
1224   if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
1225     priv_flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
1226   }
1227 
1228   if (IsUBwcEnabled(format, usage)) {
1229     if (IsUBwcPISupported(format, usage)) {
1230       priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI;
1231     } else {
1232       priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1233     }
1234   }
1235 
1236   if (usage & (BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK)) {
1237     priv_flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
1238   }
1239 
1240   if ((usage & (BufferUsage::VIDEO_ENCODER | BufferUsage::VIDEO_DECODER |
1241                 BufferUsage::CAMERA_OUTPUT | BufferUsage::GPU_RENDER_TARGET))) {
1242     priv_flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
1243   }
1244 
1245   if (!UseUncached(format, usage)) {
1246     priv_flags |= private_handle_t::PRIV_FLAGS_CACHED;
1247   }
1248 
1249   return priv_flags;
1250 }
1251 
GetImplDefinedFormat(uint64_t usage,int format)1252 int GetImplDefinedFormat(uint64_t usage, int format) {
1253   int gr_format = format;
1254 
1255   // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
1256   // the usage bits, gralloc assigns a format.
1257   if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
1258       format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1259     if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC || usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI)
1260         && format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
1261       gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
1262     } else if (usage & BufferUsage::VIDEO_ENCODER) {
1263       if (usage & GRALLOC_USAGE_PRIVATE_VIDEO_NV21_ENCODER) {
1264         gr_format = HAL_PIXEL_FORMAT_NV21_ENCODEABLE;  // NV21
1265       } else if (usage & GRALLOC_USAGE_PRIVATE_HEIF) {
1266         gr_format = HAL_PIXEL_FORMAT_NV12_HEIF;
1267       } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1268         gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
1269       } else {
1270         gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;  // NV12
1271       }
1272     } else if (usage & BufferUsage::CAMERA_INPUT) {
1273       if (usage & BufferUsage::CAMERA_OUTPUT) {
1274         // Assumed ZSL if both producer and consumer camera flags set
1275         gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
1276       } else {
1277         gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;  // NV21
1278       }
1279     } else if (usage & BufferUsage::CAMERA_OUTPUT) {
1280       if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1281         gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
1282       } else {
1283         gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;  // NV12 preview
1284       }
1285     } else if (usage & BufferUsage::COMPOSER_OVERLAY) {
1286       // XXX: If we still haven't set a format, default to RGBA8888
1287       gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
1288     } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1289       // If no other usage flags are detected, default the
1290       // flexible YUV format to NV21_ZSL
1291       gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
1292     }
1293   }
1294 
1295   return gr_format;
1296 }
1297 
GetCustomFormatFlags(int format,uint64_t usage,int * custom_format,uint64_t * priv_flags)1298 int GetCustomFormatFlags(int format, uint64_t usage,
1299                         int *custom_format, uint64_t *priv_flags) {
1300   *custom_format = GetImplDefinedFormat(usage, format);
1301   *priv_flags = GetHandleFlags(*custom_format, usage);
1302 
1303   if (usage & GRALLOC_USAGE_PROTECTED) {
1304     *priv_flags |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
1305   }
1306 
1307   *priv_flags |= private_handle_t::PRIV_FLAGS_USES_ION;
1308 
1309   return 0;
1310 }
1311 
GetBufferType(int inputFormat)1312 int GetBufferType(int inputFormat) {
1313   return IsYuvFormat(inputFormat) ? BUFFER_TYPE_VIDEO : BUFFER_TYPE_UI;
1314 }
1315 
GetYUVPlaneInfo(const BufferInfo & info,int32_t format,int32_t width,int32_t height,int32_t flags,int * plane_count,PlaneLayoutInfo * plane_info)1316 int GetYUVPlaneInfo(const BufferInfo &info, int32_t format, int32_t width, int32_t height,
1317                     int32_t flags, int *plane_count, PlaneLayoutInfo *plane_info) {
1318   int err = 0;
1319   unsigned int y_stride, c_stride, y_height, c_height, y_size, c_size;
1320   uint64_t yOffset, cOffset, crOffset, cbOffset;
1321   int h_subsampling = 0, v_subsampling = 0;
1322   switch (format) {
1323     // Semiplanar
1324     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1325     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1326     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1327     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1328     case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
1329     case HAL_PIXEL_FORMAT_NV12_HEIF:  // Same as YCbCr_420_SP_VENUS
1330     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1331     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1332     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1333     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1334     case HAL_PIXEL_FORMAT_NV21_ZSL:
1335     case HAL_PIXEL_FORMAT_RAW16:
1336     case HAL_PIXEL_FORMAT_Y16:
1337     case HAL_PIXEL_FORMAT_RAW10:
1338     case HAL_PIXEL_FORMAT_RAW8:
1339     case HAL_PIXEL_FORMAT_Y8:
1340       *plane_count = 2;
1341       GetYuvSPPlaneInfo(info, format, width, height, 1, plane_info);
1342       GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1343       plane_info[0].h_subsampling = 0;
1344       plane_info[0].v_subsampling = 0;
1345       plane_info[1].h_subsampling = h_subsampling;
1346       plane_info[1].v_subsampling = v_subsampling;
1347       break;
1348 
1349     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1350       GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1351       if (flags & LAYOUT_INTERLACED_FLAG) {
1352         *plane_count = 8;
1353         GetYuvUbwcInterlacedSPPlaneInfo(width, height, plane_info);
1354         plane_info[0].step = plane_info[4].step = 1;
1355         plane_info[1].step = plane_info[5].step = 2;
1356         plane_info[0].h_subsampling = plane_info[4].h_subsampling = 0;
1357         plane_info[0].v_subsampling = plane_info[4].v_subsampling = 0;
1358         plane_info[1].h_subsampling = plane_info[5].h_subsampling = h_subsampling;
1359         plane_info[1].v_subsampling = plane_info[5].v_subsampling = v_subsampling;
1360         plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1361         plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1362         plane_info[2].step = plane_info[3].step = 0;
1363         plane_info[6].h_subsampling = plane_info[7].h_subsampling = 0;
1364         plane_info[6].v_subsampling = plane_info[7].v_subsampling = 0;
1365         plane_info[6].step = plane_info[7].step = 0;
1366       } else {
1367         *plane_count = 4;
1368         GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, plane_info);
1369         plane_info[0].h_subsampling = 0;
1370         plane_info[0].v_subsampling = 0;
1371         plane_info[0].step = 1;
1372         plane_info[1].h_subsampling = h_subsampling;
1373         plane_info[1].v_subsampling = v_subsampling;
1374         plane_info[1].step = 2;
1375         plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1376         plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1377         plane_info[2].step = plane_info[3].step = 0;
1378       }
1379       break;
1380 
1381     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1382       *plane_count = 2;
1383       GetYuvSPPlaneInfo(info, format, width, height, 2, plane_info);
1384       GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1385       plane_info[0].h_subsampling = 0;
1386       plane_info[0].v_subsampling = 0;
1387       plane_info[1].h_subsampling = h_subsampling;
1388       plane_info[1].v_subsampling = v_subsampling;
1389       break;
1390 
1391     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1392       *plane_count = 4;
1393       GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_BPP10_UBWC, plane_info);
1394       GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1395       plane_info[0].h_subsampling = 0;
1396       plane_info[0].v_subsampling = 0;
1397       plane_info[1].step = 1;
1398       plane_info[1].h_subsampling = h_subsampling;
1399       plane_info[1].v_subsampling = v_subsampling;
1400       plane_info[1].step = 3;
1401       plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1402       plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1403       plane_info[2].step = plane_info[3].step = 0;
1404       break;
1405 
1406     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1407       *plane_count = 4;
1408       GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_P010_UBWC, plane_info);
1409       GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1410       plane_info[0].h_subsampling = 0;
1411       plane_info[0].v_subsampling = 0;
1412       plane_info[1].step = 1;
1413       plane_info[1].h_subsampling = h_subsampling;
1414       plane_info[1].v_subsampling = v_subsampling;
1415       plane_info[1].step = 4;
1416       plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1417       plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1418       plane_info[2].step = plane_info[3].step = 0;
1419       break;
1420 
1421     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1422       *plane_count = 2;
1423       y_stride = VENUS_Y_STRIDE(COLOR_FMT_P010, width);
1424       c_stride = VENUS_UV_STRIDE(COLOR_FMT_P010, width);
1425       y_height = VENUS_Y_SCANLINES(COLOR_FMT_P010, height);
1426       y_size = y_stride * y_height;
1427       yOffset = 0;
1428       cOffset = y_size;
1429       c_height = VENUS_UV_SCANLINES(COLOR_FMT_P010, INT(height));
1430       c_size = c_stride * c_height;
1431       GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1432 
1433       plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
1434       plane_info[0].offset = (uint32_t)yOffset;
1435       plane_info[0].stride = static_cast<int32_t>(UINT(width));
1436       plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
1437       plane_info[0].scanlines = static_cast<int32_t>(y_height);
1438       plane_info[0].size = static_cast<uint32_t>(y_size);
1439       plane_info[0].step = 1;
1440       plane_info[0].h_subsampling = 0;
1441       plane_info[0].v_subsampling = 0;
1442 
1443       plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
1444       plane_info[1].offset = (uint32_t)cOffset;
1445       plane_info[1].stride = static_cast<int32_t>(UINT(width));
1446       plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
1447       plane_info[1].scanlines = static_cast<int32_t>(c_height);
1448       plane_info[1].size = static_cast<uint32_t>(c_size);
1449       plane_info[1].step = 4;
1450       plane_info[1].h_subsampling = h_subsampling;
1451       plane_info[1].v_subsampling = v_subsampling;
1452       break;
1453 
1454       // Planar
1455     case HAL_PIXEL_FORMAT_YV12:
1456       if ((info.width & 1) || (info.height & 1)) {
1457         ALOGE("w or h is odd for the YV12 format");
1458         err = -EINVAL;
1459         return err;
1460       }
1461       *plane_count = 3;
1462       y_stride = width;
1463       c_stride = ALIGN(width / 2, 16);
1464       y_height = UINT(height);
1465       y_size = (y_stride * y_height);
1466       height = height >> 1;
1467       c_height = UINT(height);
1468       c_size = (c_stride * c_height);
1469       yOffset = 0;
1470       crOffset = y_size;
1471       cbOffset = (y_size + c_size);
1472       GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1473 
1474       plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
1475       plane_info[0].offset = (uint32_t)yOffset;
1476       plane_info[0].stride = static_cast<int32_t>(UINT(width));
1477       plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
1478       plane_info[0].scanlines = static_cast<int32_t>(y_height);
1479       plane_info[0].size = static_cast<uint32_t>(y_size);
1480       plane_info[0].step = 1;
1481       plane_info[0].h_subsampling = 0;
1482       plane_info[0].v_subsampling = 0;
1483 
1484       plane_info[1].component = (PlaneComponent)PLANE_COMPONENT_Cb;
1485       plane_info[1].offset = (uint32_t)cbOffset;
1486       plane_info[2].component = (PlaneComponent)PLANE_COMPONENT_Cr;
1487       plane_info[2].offset = (uint32_t)crOffset;
1488       for (int i = 1; i < 3; i++) {
1489         plane_info[i].stride = static_cast<int32_t>(UINT(width));
1490         plane_info[i].stride_bytes = static_cast<int32_t>(c_stride);
1491         plane_info[i].scanlines = static_cast<int32_t>(c_height);
1492         plane_info[i].size = static_cast<uint32_t>(c_size);
1493         plane_info[i].step = 1;
1494         plane_info[i].h_subsampling = h_subsampling;
1495         plane_info[i].v_subsampling = v_subsampling;
1496       }
1497       break;
1498     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1499       if (info.width & 1) {
1500         ALOGE("width is odd for the YUV422_SP format");
1501         err = -EINVAL;
1502         return err;
1503       }
1504       *plane_count = 1;
1505       y_stride = width * 2;
1506       y_height = UINT(height);
1507       y_size = y_stride * y_height;
1508       yOffset = 0;
1509       plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
1510       plane_info[0].offset = (uint32_t)yOffset;
1511       plane_info[0].stride = static_cast<int32_t>(UINT(width));
1512       plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
1513       plane_info[0].scanlines = static_cast<int32_t>(y_height);
1514       plane_info[0].size = static_cast<uint32_t>(y_size);
1515       plane_info[0].step = 1;
1516       plane_info[0].h_subsampling = 0;
1517       plane_info[0].v_subsampling = 0;
1518       break;
1519 
1520       // Unsupported formats
1521     case HAL_PIXEL_FORMAT_YCbCr_422_I:
1522     case HAL_PIXEL_FORMAT_YCrCb_422_I:
1523     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
1524     default:
1525       *plane_count = 0;
1526       ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
1527       err = -EINVAL;
1528   }
1529   return err;
1530 }
1531 
GetYuvSubSamplingFactor(int32_t format,int * h_subsampling,int * v_subsampling)1532 void GetYuvSubSamplingFactor(int32_t format, int *h_subsampling, int *v_subsampling) {
1533   switch (format) {
1534     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1535     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1536     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1537     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1538     case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1539     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1540     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1541     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1542     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1543     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1544     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:  // Same as YCbCr_420_SP_VENUS
1545     case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
1546     case HAL_PIXEL_FORMAT_NV21_ZSL:
1547     case HAL_PIXEL_FORMAT_YV12:
1548       *h_subsampling = 1;
1549       *v_subsampling = 1;
1550       break;
1551     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1552     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1553     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1554       *h_subsampling = 1;
1555       *v_subsampling = 0;
1556       break;
1557     case HAL_PIXEL_FORMAT_RAW16:
1558     case HAL_PIXEL_FORMAT_Y16:
1559     case HAL_PIXEL_FORMAT_RAW12:
1560     case HAL_PIXEL_FORMAT_RAW10:
1561     case HAL_PIXEL_FORMAT_Y8:
1562     case HAL_PIXEL_FORMAT_BLOB:
1563     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1564     case HAL_PIXEL_FORMAT_NV12_HEIF:
1565     default:
1566       *h_subsampling = 0;
1567       *v_subsampling = 0;
1568       break;
1569   }
1570 }
1571 
CopyPlaneLayoutInfotoAndroidYcbcr(uint64_t base,int plane_count,PlaneLayoutInfo * plane_info,struct android_ycbcr * ycbcr)1572 void CopyPlaneLayoutInfotoAndroidYcbcr(uint64_t base, int plane_count, PlaneLayoutInfo *plane_info,
1573                                        struct android_ycbcr *ycbcr) {
1574   ycbcr->y = reinterpret_cast<void *>(base + plane_info[0].offset);
1575   ycbcr->ystride = plane_info[0].stride_bytes;
1576   if (plane_count == 1) {
1577     ycbcr->cb = NULL;
1578     ycbcr->cr = NULL;
1579     ycbcr->cstride = 0;
1580     ycbcr->chroma_step = 0;
1581   } else if (plane_count == 2 || plane_count == 4 || plane_count == 8) {
1582     /* For YUV semiplanar :-
1583      *   - In progressive & linear case plane count is 2 and plane_info[0] will
1584      *     contain info about Y plane and plane_info[1] will contain info about UV plane.
1585      *   - In progressive & compressed case plane count is 4 then plane_info[0] will
1586      *     contain info about Y plane and plane_info[1] will contain info about UV plane.
1587      *     Remaining two plane (plane_info[2] & plane_info[3]) contain info about the
1588      *     Y_Meta_Plane and UV_Meta_Plane.
1589      *   - In interlaced & compressed case plane count is 8 then plane_info[0], plane_info[1],
1590      *     plane_info[4] & plane_info[5] will contain info about Y_plane, UV_plane, Y_plane
1591      *     & UV_plane. Remaining plane will contain info about the meta planes. As in this case
1592      *     this API is called twice through GetYUVPlaneInfo() with address of plane_info[0] &
1593      *     plane_info[4], so this will calculate the information accordingly and will fill the
1594      *     ycbcr structure with interlaced plane info only.
1595      */
1596     ycbcr->cb = reinterpret_cast<void *>(base + plane_info[1].offset);
1597     ycbcr->cr = reinterpret_cast<void *>(base + plane_info[1].offset + 1);
1598     ycbcr->cstride = plane_info[1].stride_bytes;
1599     ycbcr->chroma_step = plane_info[1].step;
1600   } else if (plane_count == 3) {
1601     /* For YUV planar :-
1602      * Plane size is 3 and plane_info[0], plane_info[1], plane_info[2] will
1603      * contain info about y_plane, cb_plane and cr_plane accordingly.
1604      */
1605     ycbcr->cb = reinterpret_cast<void *>(base + plane_info[1].offset);
1606     ycbcr->cr = reinterpret_cast<void *>(base + plane_info[2].offset);
1607     ycbcr->cstride = plane_info[1].stride_bytes;
1608     ycbcr->chroma_step = plane_info[1].step;
1609   }
1610 }
1611 
HasAlphaComponent(int32_t format)1612 bool HasAlphaComponent(int32_t format) {
1613   switch (format) {
1614     case HAL_PIXEL_FORMAT_RGBA_8888:
1615     case HAL_PIXEL_FORMAT_BGRA_8888:
1616     case HAL_PIXEL_FORMAT_RGBA_5551:
1617     case HAL_PIXEL_FORMAT_RGBA_4444:
1618     case HAL_PIXEL_FORMAT_RGBA_1010102:
1619     case HAL_PIXEL_FORMAT_ARGB_2101010:
1620     case HAL_PIXEL_FORMAT_BGRA_1010102:
1621     case HAL_PIXEL_FORMAT_ABGR_2101010:
1622     case HAL_PIXEL_FORMAT_RGBA_FP16:
1623       return true;
1624     default:
1625       return false;
1626   }
1627 }
1628 
GetRGBPlaneInfo(const BufferInfo & info,int32_t format,int32_t width,int32_t height,int32_t,int * plane_count,PlaneLayoutInfo * plane_info)1629 void GetRGBPlaneInfo(const BufferInfo &info, int32_t format, int32_t width, int32_t height,
1630                      int32_t /* flags */, int *plane_count, PlaneLayoutInfo *plane_info) {
1631   uint64_t usage = info.usage;
1632   *plane_count = 1;
1633   uint32_t bpp = 0;
1634   if (IsUncompressedRGBFormat(format)) {
1635     bpp = GetBppForUncompressedRGB(format);
1636   }
1637   plane_info->component =
1638       (PlaneComponent)(PLANE_COMPONENT_R | PLANE_COMPONENT_G | PLANE_COMPONENT_B);
1639   if (HasAlphaComponent(format)) {
1640     plane_info->component = (PlaneComponent)(plane_info->component | PLANE_COMPONENT_A);
1641   }
1642   plane_info->size = GetSize(info, width, height);
1643   plane_info->step = bpp;
1644   plane_info->offset = GetRgbMetaSize(format, width, height, usage);
1645   plane_info->h_subsampling = 0;
1646   plane_info->v_subsampling = 0;
1647   plane_info->stride = width;
1648   plane_info->stride_bytes = width * plane_info->step;
1649   plane_info->scanlines = height;
1650 }
1651 
1652 }  // namespace gralloc
1653