1 /*
2  * Copyright (c) 2011-2017, 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_utils.h"
34 #include "gr_adreno_info.h"
35 #include "qdMetaData.h"
36 
37 #define ASTC_BLOCK_SIZE 16
38 
39 #ifndef COLOR_FMT_P010_UBWC
40 #define COLOR_FMT_P010_UBWC 9
41 #endif
42 
43 namespace gralloc1 {
44 
IsUncompressedRGBFormat(int format)45 bool IsUncompressedRGBFormat(int format) {
46   switch (format) {
47     case HAL_PIXEL_FORMAT_RGBA_8888:
48     case HAL_PIXEL_FORMAT_RGBX_8888:
49     case HAL_PIXEL_FORMAT_RGB_888:
50     case HAL_PIXEL_FORMAT_RGB_565:
51     case HAL_PIXEL_FORMAT_BGR_565:
52     case HAL_PIXEL_FORMAT_BGRA_8888:
53     case HAL_PIXEL_FORMAT_RGBA_5551:
54     case HAL_PIXEL_FORMAT_RGBA_4444:
55     case HAL_PIXEL_FORMAT_R_8:
56     case HAL_PIXEL_FORMAT_RG_88:
57     case HAL_PIXEL_FORMAT_BGRX_8888:
58     case HAL_PIXEL_FORMAT_RGBA_1010102:
59     case HAL_PIXEL_FORMAT_ARGB_2101010:
60     case HAL_PIXEL_FORMAT_RGBX_1010102:
61     case HAL_PIXEL_FORMAT_XRGB_2101010:
62     case HAL_PIXEL_FORMAT_BGRA_1010102:
63     case HAL_PIXEL_FORMAT_ABGR_2101010:
64     case HAL_PIXEL_FORMAT_BGRX_1010102:
65     case HAL_PIXEL_FORMAT_XBGR_2101010:
66     case HAL_PIXEL_FORMAT_RGBA_FP16:
67     case HAL_PIXEL_FORMAT_BGR_888:
68       return true;
69     default:
70       break;
71   }
72 
73   return false;
74 }
75 
IsCompressedRGBFormat(int format)76 bool IsCompressedRGBFormat(int format) {
77   switch (format) {
78     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
79     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
80     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
81     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
82     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
83     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
84     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
85     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
86     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
87     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
88     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
89     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
90     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
91     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
92     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
93     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
94     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
95     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
96     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
97     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
98     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
99     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
100     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
101     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
102     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
103     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
104     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
105     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
106       return true;
107     default:
108       break;
109   }
110 
111   return false;
112 }
113 
GetBppForUncompressedRGB(int format)114 uint32_t GetBppForUncompressedRGB(int format) {
115   uint32_t bpp = 0;
116   switch (format) {
117     case HAL_PIXEL_FORMAT_RGBA_FP16:
118       bpp = 8;
119       break;
120     case HAL_PIXEL_FORMAT_RGBA_8888:
121     case HAL_PIXEL_FORMAT_RGBX_8888:
122     case HAL_PIXEL_FORMAT_BGRA_8888:
123     case HAL_PIXEL_FORMAT_BGRX_8888:
124     case HAL_PIXEL_FORMAT_RGBA_1010102:
125     case HAL_PIXEL_FORMAT_ARGB_2101010:
126     case HAL_PIXEL_FORMAT_RGBX_1010102:
127     case HAL_PIXEL_FORMAT_XRGB_2101010:
128     case HAL_PIXEL_FORMAT_BGRA_1010102:
129     case HAL_PIXEL_FORMAT_ABGR_2101010:
130     case HAL_PIXEL_FORMAT_BGRX_1010102:
131     case HAL_PIXEL_FORMAT_XBGR_2101010:
132       bpp = 4;
133       break;
134     case HAL_PIXEL_FORMAT_RGB_888:
135     case HAL_PIXEL_FORMAT_BGR_888:
136       bpp = 3;
137       break;
138     case HAL_PIXEL_FORMAT_RGB_565:
139     case HAL_PIXEL_FORMAT_BGR_565:
140     case HAL_PIXEL_FORMAT_RGBA_5551:
141     case HAL_PIXEL_FORMAT_RGBA_4444:
142       bpp = 2;
143       break;
144     default:
145       ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
146       break;
147   }
148 
149   return bpp;
150 }
151 
CpuCanAccess(gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)152 bool CpuCanAccess(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) {
153   return CpuCanRead(prod_usage, cons_usage) || CpuCanWrite(prod_usage);
154 }
155 
CpuCanRead(gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)156 bool CpuCanRead(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) {
157   if (prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) {
158     return true;
159   }
160 
161   if (cons_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ) {
162     return true;
163   }
164 
165   return false;
166 }
167 
CpuCanWrite(gralloc1_producer_usage_t prod_usage)168 bool CpuCanWrite(gralloc1_producer_usage_t prod_usage) {
169   if (prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) {
170     // Application intends to use CPU for rendering
171     return true;
172   }
173 
174   return false;
175 }
176 
GetSize(const BufferInfo & info,unsigned int alignedw,unsigned int alignedh)177 unsigned int GetSize(const BufferInfo &info, unsigned int alignedw,
178                      unsigned int alignedh) {
179   unsigned int size = 0;
180   int format = info.format;
181   int width = info.width;
182   int height = info.height;
183   gralloc1_producer_usage_t prod_usage = info.prod_usage;
184   gralloc1_consumer_usage_t cons_usage = info.cons_usage;
185 
186   if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
187     return GetUBwcSize(width, height, format, alignedw, alignedh);
188   }
189 
190   if (IsUncompressedRGBFormat(format)) {
191     uint32_t bpp = GetBppForUncompressedRGB(format);
192     size = alignedw * alignedh * bpp;
193     return size;
194   }
195 
196   if (IsCompressedRGBFormat(format)) {
197     size = alignedw * alignedh * ASTC_BLOCK_SIZE;
198     return size;
199   }
200 
201   // Below switch should be for only YUV/custom formats
202   switch (format) {
203     case HAL_PIXEL_FORMAT_RAW16:
204     case HAL_PIXEL_FORMAT_Y16:
205       size = alignedw * alignedh * 2;
206       break;
207     case HAL_PIXEL_FORMAT_RAW10:
208     case HAL_PIXEL_FORMAT_RAW12:
209       size = ALIGN(alignedw * alignedh, SIZE_4K);
210       break;
211     case HAL_PIXEL_FORMAT_RAW8:
212     case HAL_PIXEL_FORMAT_Y8:
213       size = alignedw * alignedh * 1;
214       break;
215 
216       // adreno formats
217     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
218       size = ALIGN(alignedw * alignedh, SIZE_4K);
219       size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
220       break;
221     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:  // NV12
222       // The chroma plane is subsampled,
223       // but the pitch in bytes is unchanged
224       // The GPU needs 4K alignment, but the video decoder needs 8K
225       size = ALIGN(alignedw * alignedh, SIZE_8K);
226       size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
227       break;
228     case HAL_PIXEL_FORMAT_YV12:
229       if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
230         ALOGE("w or h is odd for the YV12 format");
231         return 0;
232       }
233       size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
234       size = ALIGN(size, (unsigned int)SIZE_4K);
235       break;
236     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
237     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
238       size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
239       break;
240     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
241       size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
242       break;
243     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
244     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
245     case HAL_PIXEL_FORMAT_YCbCr_422_I:
246     case HAL_PIXEL_FORMAT_YCrCb_422_I:
247     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
248       if (width & 1) {
249         ALOGE("width is odd for the YUV422_SP format");
250         return 0;
251       }
252       size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
253       break;
254     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
255     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
256       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
257       break;
258     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
259       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
260       break;
261     case HAL_PIXEL_FORMAT_BLOB:
262     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
263       if (height != 1) {
264         ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
265         return 0;
266       }
267       size = (unsigned int)width;
268       break;
269     case HAL_PIXEL_FORMAT_NV21_ZSL:
270       size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
271       break;
272     default:
273       ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
274       return 0;
275   }
276 
277   return size;
278 }
279 
GetBufferSizeAndDimensions(const BufferInfo & info,unsigned int * size,unsigned int * alignedw,unsigned int * alignedh)280 void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size,
281                                 unsigned int *alignedw, unsigned int *alignedh) {
282   GetAlignedWidthAndHeight(info, alignedw, alignedh);
283   *size = GetSize(info, *alignedw, *alignedh);
284 }
285 
GetYuvUbwcSPPlaneInfo(uint64_t base,uint32_t width,uint32_t height,int color_format,struct android_ycbcr * ycbcr)286 void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
287                            int color_format, struct android_ycbcr *ycbcr) {
288   // UBWC buffer has these 4 planes in the following sequence:
289   // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
290   unsigned int y_meta_stride, y_meta_height, y_meta_size;
291   unsigned int y_stride, y_height, y_size;
292   unsigned int c_meta_stride, c_meta_height, c_meta_size;
293   unsigned int alignment = 4096;
294 
295   y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
296   y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
297   y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
298 
299   y_stride = VENUS_Y_STRIDE(color_format, INT(width));
300   y_height = VENUS_Y_SCANLINES(color_format, INT(height));
301   y_size = ALIGN((y_stride * y_height), alignment);
302 
303   c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
304   c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
305   c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
306 
307   ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
308   ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
309   ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
310   ycbcr->ystride = y_stride;
311   ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
312 }
313 
GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base,uint32_t width,uint32_t height,int color_format,struct android_ycbcr * ycbcr)314 void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
315                                      int color_format, struct android_ycbcr *ycbcr) {
316   unsigned int uv_stride, uv_height, uv_size;
317   unsigned int alignment = 4096;
318   uint64_t field_base;
319 
320   // UBWC interlaced has top-bottom field layout with each field as
321   // 4-plane NV12_UBWC with width = image_width & height = image_height / 2.
322   // Client passed ycbcr argument is ptr to struct android_ycbcr[2].
323   // Plane info to be filled for each field separately.
324   height = (height + 1) >> 1;
325   uv_stride = VENUS_UV_STRIDE(color_format, INT(width));
326   uv_height = VENUS_UV_SCANLINES(color_format, INT(height));
327   uv_size = ALIGN((uv_stride * uv_height), alignment);
328 
329   field_base = base;
330   GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
331 
332   field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
333   GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
334 }
335 
GetYuvSPPlaneInfo(uint64_t base,uint32_t width,uint32_t height,uint32_t bpp,struct android_ycbcr * ycbcr)336 void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
337                        struct android_ycbcr *ycbcr) {
338   unsigned int ystride, cstride;
339 
340   ystride = cstride = UINT(width) * bpp;
341   ycbcr->y = reinterpret_cast<void *>(base);
342   ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
343   ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
344   ycbcr->ystride = ystride;
345   ycbcr->cstride = cstride;
346   ycbcr->chroma_step = 2 * bpp;
347 }
348 
GetYUVPlaneInfo(const private_handle_t * hnd,struct android_ycbcr * ycbcr)349 int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
350   int err = 0;
351   uint32_t width = UINT(hnd->width);
352   uint32_t height = UINT(hnd->height);
353   int format = hnd->format;
354   gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
355   gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
356   unsigned int ystride, cstride;
357   bool interlaced = false;
358 
359   memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
360 
361   // Check if UBWC buffer has been rendered in linear format.
362   int linear_format = 0;
363   if (getMetaData(const_cast<private_handle_t *>(hnd),
364                   GET_LINEAR_FORMAT, &linear_format) == 0) {
365       format = INT(linear_format);
366   }
367 
368   // Check metadata if the geometry has been updated.
369   BufferDim_t buffer_dim;
370   if (getMetaData(const_cast<private_handle_t *>(hnd),
371                   GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
372     int usage = 0;
373     if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
374       usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
375     }
376 
377     BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format,
378                     prod_usage, cons_usage);
379     GetAlignedWidthAndHeight(info, &width, &height);
380   }
381 
382   // Check metadata for interlaced content.
383   int interlace_flag = 0;
384   if (getMetaData(const_cast<private_handle_t *>(hnd),
385                   GET_PP_PARAM_INTERLACED, &interlace_flag) != 0) {
386     interlaced = interlace_flag;
387   }
388 
389   // Get the chroma offsets from the handle width/height. We take advantage
390   // of the fact the width _is_ the stride
391   switch (format) {
392     // Semiplanar
393     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
394     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
395     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
396     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
397       // Same as YCbCr_420_SP_VENUS
398       GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
399       break;
400 
401     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
402       GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
403       break;
404 
405     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
406       if (!interlaced) {
407         GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
408       } else {
409         GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
410       }
411       ycbcr->chroma_step = 2;
412       break;
413 
414     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
415       GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
416       ycbcr->chroma_step = 3;
417       break;
418 
419     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
420       GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
421       ycbcr->chroma_step = 4;
422       break;
423 
424     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
425     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
426     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
427     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
428     case HAL_PIXEL_FORMAT_NV21_ZSL:
429     case HAL_PIXEL_FORMAT_RAW16:
430     case HAL_PIXEL_FORMAT_Y16:
431     case HAL_PIXEL_FORMAT_RAW10:
432     case HAL_PIXEL_FORMAT_RAW8:
433     case HAL_PIXEL_FORMAT_Y8:
434       GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
435       std::swap(ycbcr->cb, ycbcr->cr);
436       break;
437 
438       // Planar
439     case HAL_PIXEL_FORMAT_YV12:
440       ystride = width;
441       cstride = ALIGN(width / 2, 16);
442       ycbcr->y = reinterpret_cast<void *>(hnd->base);
443       ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
444       ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
445       ycbcr->ystride = ystride;
446       ycbcr->cstride = cstride;
447       ycbcr->chroma_step = 1;
448       break;
449     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
450       ystride = width * 2;
451       cstride = 0;
452       ycbcr->y  = reinterpret_cast<void *>(hnd->base);
453       ycbcr->cr = NULL;
454       ycbcr->cb = NULL;
455       ycbcr->ystride = ystride;
456       ycbcr->cstride = 0;
457       ycbcr->chroma_step = 0;
458       break;
459       // Unsupported formats
460     case HAL_PIXEL_FORMAT_YCbCr_422_I:
461     case HAL_PIXEL_FORMAT_YCrCb_422_I:
462     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
463     default:
464       ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
465       err = -EINVAL;
466   }
467 
468   return err;
469 }
470 
471 // Explicitly defined UBWC formats
IsUBwcFormat(int format)472 bool IsUBwcFormat(int format) {
473   switch (format) {
474     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
475     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
476     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
477       return true;
478     default:
479       return false;
480   }
481 }
482 
IsUBwcSupported(int format)483 bool IsUBwcSupported(int format) {
484   // Existing HAL formats with UBWC support
485   switch (format) {
486     case HAL_PIXEL_FORMAT_BGR_565:
487     case HAL_PIXEL_FORMAT_RGBA_8888:
488     case HAL_PIXEL_FORMAT_RGBX_8888:
489     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
490     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
491     case HAL_PIXEL_FORMAT_RGBA_1010102:
492     case HAL_PIXEL_FORMAT_RGBX_1010102:
493       return true;
494     default:
495       break;
496   }
497 
498   return false;
499 }
500 
IsUBwcEnabled(int format,gralloc1_producer_usage_t prod_usage,gralloc1_consumer_usage_t cons_usage)501 bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
502                    gralloc1_consumer_usage_t cons_usage) {
503   // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
504   if (IsUBwcFormat(format)) {
505     return true;
506   }
507 
508   // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
509   // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
510   // usage flag and MDP supports the format.
511   if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
512     bool enable = true;
513     // Query GPU for UBWC only if buffer is intended to be used by GPU.
514     if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
515         (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
516       if (AdrenoMemInfo::GetInstance()) {
517         enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
518       }
519     }
520 
521     // Allow UBWC, only if CPU usage flags are not set
522     if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
523       return true;
524     }
525   }
526 
527   return false;
528 }
529 
GetYuvUBwcWidthAndHeight(int width,int height,int format,unsigned int * aligned_w,unsigned int * aligned_h)530 void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
531                               unsigned int *aligned_h) {
532   switch (format) {
533     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
534     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
535     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
536       *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
537       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
538       break;
539     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
540       // The macro returns the stride which is 4/3 times the width, hence * 3/4
541       *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
542       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
543       break;
544     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
545       // The macro returns the stride which is 2 times the width, hence / 2
546       *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
547       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
548       break;
549     default:
550       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
551       *aligned_w = 0;
552       *aligned_h = 0;
553       break;
554   }
555 }
556 
GetRgbUBwcBlockSize(uint32_t bpp,int * block_width,int * block_height)557 void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
558   *block_width = 0;
559   *block_height = 0;
560 
561   switch (bpp) {
562     case 2:
563     case 4:
564       *block_width = 16;
565       *block_height = 4;
566       break;
567     case 8:
568       *block_width = 8;
569       *block_height = 4;
570       break;
571     case 16:
572       *block_width = 4;
573       *block_height = 4;
574       break;
575     default:
576       ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
577       break;
578   }
579 }
580 
GetRgbUBwcMetaBufferSize(int width,int height,uint32_t bpp)581 unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
582   unsigned int size = 0;
583   int meta_width, meta_height;
584   int block_width, block_height;
585 
586   GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
587   if (!block_width || !block_height) {
588     ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
589     return size;
590   }
591 
592   // Align meta buffer height to 16 blocks
593   meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
594 
595   // Align meta buffer width to 64 blocks
596   meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
597 
598   // Align meta buffer size to 4K
599   size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
600 
601   return size;
602 }
603 
GetUBwcSize(int width,int height,int format,unsigned int alignedw,unsigned int alignedh)604 unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
605                          unsigned int alignedh) {
606   unsigned int size = 0;
607   uint32_t bpp = 0;
608   switch (format) {
609     case HAL_PIXEL_FORMAT_BGR_565:
610     case HAL_PIXEL_FORMAT_RGBA_8888:
611     case HAL_PIXEL_FORMAT_RGBX_8888:
612     case HAL_PIXEL_FORMAT_RGBA_1010102:
613     case HAL_PIXEL_FORMAT_RGBX_1010102:
614       bpp = GetBppForUncompressedRGB(format);
615       size = alignedw * alignedh * bpp;
616       size += GetRgbUBwcMetaBufferSize(width, height, bpp);
617       break;
618     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
619     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
620     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
621       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
622       break;
623     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
624       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
625       break;
626     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
627       size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
628       break;
629     default:
630       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
631       break;
632   }
633 
634   return size;
635 }
636 
GetRgbDataAddress(private_handle_t * hnd,void ** rgb_data)637 int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
638   int err = 0;
639 
640   // This api is for RGB* formats
641   if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
642     return -EINVAL;
643   }
644 
645   // linear buffer, nothing to do further
646   if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
647     *rgb_data = reinterpret_cast<void *>(hnd->base);
648     return err;
649   }
650 
651   unsigned int meta_size = 0;
652   uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
653   switch (hnd->format) {
654     case HAL_PIXEL_FORMAT_BGR_565:
655     case HAL_PIXEL_FORMAT_RGBA_8888:
656     case HAL_PIXEL_FORMAT_RGBX_8888:
657     case HAL_PIXEL_FORMAT_RGBA_1010102:
658     case HAL_PIXEL_FORMAT_RGBX_1010102:
659       meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
660       break;
661     default:
662       ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
663       err = -EINVAL;
664       break;
665   }
666   *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
667 
668   return err;
669 }
670 
GetAlignedWidthAndHeight(const BufferInfo & info,unsigned int * alignedw,unsigned int * alignedh)671 void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
672                               unsigned int *alignedh) {
673   int width = info.width;
674   int height = info.height;
675   int format = info.format;
676   gralloc1_producer_usage_t prod_usage = info.prod_usage;
677   gralloc1_consumer_usage_t cons_usage = info.cons_usage;
678 
679   // Currently surface padding is only computed for RGB* surfaces.
680   bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
681   int tile = ubwc_enabled;
682 
683   if (IsUncompressedRGBFormat(format)) {
684     if (AdrenoMemInfo::GetInstance()) {
685       AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
686                                                          alignedh);
687     }
688     return;
689   }
690 
691   if (ubwc_enabled) {
692     GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
693     return;
694   }
695 
696   if (IsCompressedRGBFormat(format)) {
697     if (AdrenoMemInfo::GetInstance()) {
698       AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
699     }
700     return;
701   }
702 
703   int aligned_w = width;
704   int aligned_h = height;
705   unsigned int alignment = 32;
706 
707   // Below should be only YUV family
708   switch (format) {
709     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
710     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
711       if (AdrenoMemInfo::GetInstance() == nullptr) {
712         return;
713       }
714       alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
715       aligned_w = ALIGN(width, alignment);
716       break;
717     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
718       aligned_w = ALIGN(width, alignment);
719       break;
720     case HAL_PIXEL_FORMAT_RAW16:
721     case HAL_PIXEL_FORMAT_Y16:
722     case HAL_PIXEL_FORMAT_Y8:
723       aligned_w = ALIGN(width, 16);
724       break;
725     case HAL_PIXEL_FORMAT_RAW12:
726       aligned_w = ALIGN(width * 12 / 8, 8);
727       break;
728     case HAL_PIXEL_FORMAT_RAW10:
729       aligned_w = ALIGN(width * 10 / 8, 8);
730       break;
731     case HAL_PIXEL_FORMAT_RAW8:
732       aligned_w = ALIGN(width, 8);
733       break;
734     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
735       aligned_w = ALIGN(width, 128);
736       break;
737     case HAL_PIXEL_FORMAT_YV12:
738     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
739     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
740     case HAL_PIXEL_FORMAT_YCbCr_422_I:
741     case HAL_PIXEL_FORMAT_YCrCb_422_I:
742     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
743       aligned_w = ALIGN(width, 16);
744       break;
745     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
746     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
747       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
748       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
749       break;
750     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
751       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
752       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
753       break;
754     case HAL_PIXEL_FORMAT_BLOB:
755     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
756       break;
757     case HAL_PIXEL_FORMAT_NV21_ZSL:
758       aligned_w = ALIGN(width, 64);
759       aligned_h = ALIGN(height, 64);
760       break;
761     default:
762       break;
763   }
764 
765   *alignedw = (unsigned int)aligned_w;
766   *alignedh = (unsigned int)aligned_h;
767 }
768 
GetBufferLayout(private_handle_t * hnd,uint32_t stride[4],uint32_t offset[4],uint32_t * num_planes)769 int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4],
770                     uint32_t offset[4], uint32_t *num_planes) {
771   if (!hnd || !stride || !offset || !num_planes) {
772     return -EINVAL;
773   }
774 
775   struct android_ycbcr yuvInfo = {};
776   *num_planes = 1;
777   stride[0] = 0;
778 
779   switch (hnd->format) {
780     case HAL_PIXEL_FORMAT_RGB_565:
781     case HAL_PIXEL_FORMAT_BGR_565:
782     case HAL_PIXEL_FORMAT_RGBA_5551:
783     case HAL_PIXEL_FORMAT_RGBA_4444:
784       stride[0] = static_cast<uint32_t>(hnd->width * 2);
785       break;
786     case HAL_PIXEL_FORMAT_RGB_888:
787       stride[0] = static_cast<uint32_t>(hnd->width * 3);
788       break;
789     case HAL_PIXEL_FORMAT_RGBA_8888:
790     case HAL_PIXEL_FORMAT_BGRA_8888:
791     case HAL_PIXEL_FORMAT_RGBX_8888:
792     case HAL_PIXEL_FORMAT_BGRX_8888:
793     case HAL_PIXEL_FORMAT_RGBA_1010102:
794     case HAL_PIXEL_FORMAT_ARGB_2101010:
795     case HAL_PIXEL_FORMAT_RGBX_1010102:
796     case HAL_PIXEL_FORMAT_XRGB_2101010:
797     case HAL_PIXEL_FORMAT_BGRA_1010102:
798     case HAL_PIXEL_FORMAT_ABGR_2101010:
799     case HAL_PIXEL_FORMAT_BGRX_1010102:
800     case HAL_PIXEL_FORMAT_XBGR_2101010:
801       stride[0] = static_cast<uint32_t>(hnd->width * 4);
802       break;
803   }
804 
805   // Format is RGB
806   if (stride[0]) {
807     return 0;
808   }
809 
810   (*num_planes)++;
811   int ret = GetYUVPlaneInfo(hnd, &yuvInfo);
812   if (ret < 0) {
813     ALOGE("%s failed", __FUNCTION__);
814     return ret;
815   }
816 
817   stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
818   offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
819   stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
820   switch (hnd->format) {
821     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
822     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
823     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
824     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
825     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
826     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
827     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
828     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
829       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
830       break;
831     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
832     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
833     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
834       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
835       break;
836     case HAL_PIXEL_FORMAT_YV12:
837       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
838       stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
839       offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
840       (*num_planes)++;
841       break;
842     default:
843       ALOGW("%s: Unsupported format", __FUNCTION__);
844       ret = -EINVAL;
845   }
846 
847   if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
848     std::fill(offset, offset + 4, 0);
849   }
850 
851   return 0;
852 }
853 
854 }  // namespace gralloc1
855