blob: b9ddcecbe7ca1504bd7b90212ee3c58d07d4636d [file] [log] [blame]
Prabhanjan Kandula96e92342016-03-24 21:03:35 +05301/*
Ramakant Singh13596ae2020-01-06 20:12:34 +05302 * Copyright (c) 2011-2020, The Linux Foundation. All rights reserved.
Prabhanjan Kandula96e92342016-03-24 21:03:35 +05303
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
Saurabh Shah14c8e5b2017-04-07 10:37:23 -070030#include <media/msm_media_info.h>
31#include <algorithm>
32
Saurabh Shah14c8e5b2017-04-07 10:37:23 -070033#include "gr_adreno_info.h"
Naseer Ahmede36f2242017-12-01 15:33:56 -050034#include "gr_utils.h"
Saurabh Shah14c8e5b2017-04-07 10:37:23 -070035
36#define ASTC_BLOCK_SIZE 16
37
38#ifndef COLOR_FMT_P010_UBWC
39#define COLOR_FMT_P010_UBWC 9
40#endif
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053041
Naseer Ahmede36f2242017-12-01 15:33:56 -050042namespace gralloc {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053043
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +053044bool IsYuvFormat(int format) {
45 switch (format) {
Saurabh Shahdbb572e2018-01-04 15:38:01 -080046 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
47 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
48 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
Naseer Ahmede36f2242017-12-01 15:33:56 -050049 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
Ramakant Singh13596ae2020-01-06 20:12:34 +053050 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Saurabh Shahdbb572e2018-01-04 15:38:01 -080051 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:
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +053067 // Below formats used by camera and VR
68 case HAL_PIXEL_FORMAT_BLOB:
69 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
Rajavenu Kyatham6e8c1822018-07-31 10:27:19 +053070 case HAL_PIXEL_FORMAT_NV12_HEIF:
Camus Wonga300db62018-09-27 16:38:50 -040071 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
Saurabh Shahdbb572e2018-01-04 15:38:01 -080072 return true;
73 default:
74 return false;
75 }
76}
77
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053078bool 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:
Naseer Ahmed1c473d82017-02-27 13:39:37 -050099 case HAL_PIXEL_FORMAT_RGBA_FP16:
Camus Wong5c5e6fb2017-03-21 17:02:48 -0400100 case HAL_PIXEL_FORMAT_BGR_888:
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530101 return true;
102 default:
103 break;
104 }
105
106 return false;
107}
108
109bool 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
147uint32_t GetBppForUncompressedRGB(int format) {
148 uint32_t bpp = 0;
149 switch (format) {
Naseer Ahmed1c473d82017-02-27 13:39:37 -0500150 case HAL_PIXEL_FORMAT_RGBA_FP16:
151 bpp = 8;
152 break;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530153 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:
Arun Kumar K.Rb97ca302017-04-06 15:59:33 -0700157 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:
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530165 bpp = 4;
166 break;
167 case HAL_PIXEL_FORMAT_RGB_888:
Camus Wong5c5e6fb2017-03-21 17:02:48 -0400168 case HAL_PIXEL_FORMAT_BGR_888:
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530169 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 bpp = 2;
176 break;
177 default:
Arun Kumar K.Rb97ca302017-04-06 15:59:33 -0700178 ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530179 break;
180 }
181
182 return bpp;
183}
184
Naseer Ahmede36f2242017-12-01 15:33:56 -0500185bool CpuCanAccess(uint64_t usage) {
186 return CpuCanRead(usage) || CpuCanWrite(usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530187}
188
Naseer Ahmede36f2242017-12-01 15:33:56 -0500189bool CpuCanRead(uint64_t usage) {
190 if (usage & BufferUsage::CPU_READ_MASK) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530191 return true;
192 }
193
194 return false;
195}
196
Naseer Ahmede36f2242017-12-01 15:33:56 -0500197bool CpuCanWrite(uint64_t usage) {
198 if (usage & BufferUsage::CPU_WRITE_MASK) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530199 // Application intends to use CPU for rendering
200 return true;
201 }
202
203 return false;
204}
205
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400206uint32_t GetDataAlignment(int format, uint64_t usage) {
207 uint32_t align = UINT(getpagesize());
208 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
209 align = SIZE_8K;
210 }
211
212 if (usage & BufferUsage::PROTECTED) {
213 if ((usage & BufferUsage::CAMERA_OUTPUT) || (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
214 // The alignment here reflects qsee mmu V7L/V8L requirement
215 align = SZ_2M;
216 } else {
217 align = SECURE_ALIGN;
218 }
219 }
220
221 return align;
222}
223
Saurabh Dubey937c4e52018-06-26 11:31:18 +0530224bool IsGPUFlagSupported(uint64_t usage) {
225 bool ret = true;
226 if ((usage & BufferUsage::GPU_MIPMAP_COMPLETE)) {
227 ALOGE("GPU_MIPMAP_COMPLETE not supported");
228 ret = false;
229 }
230
231 if ((usage & BufferUsage::GPU_CUBE_MAP)) {
232 ALOGE("GPU_CUBE_MAP not supported");
233 ret = false;
234 }
235
236 return ret;
237}
238
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400239// Returns the final buffer size meant to be allocated with ion
Naseer Ahmede36f2242017-12-01 15:33:56 -0500240unsigned int GetSize(const BufferInfo &info, unsigned int alignedw, unsigned int alignedh) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700241 unsigned int size = 0;
242 int format = info.format;
243 int width = info.width;
244 int height = info.height;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500245 uint64_t usage = info.usage;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700246
Saurabh Dubey937c4e52018-06-26 11:31:18 +0530247 if (!IsGPUFlagSupported(usage)) {
248 ALOGE("Unsupported GPU usage flags present 0x%" PRIx64, usage);
249 return 0;
250 }
251
Naseer Ahmede36f2242017-12-01 15:33:56 -0500252 if (IsUBwcEnabled(format, usage)) {
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400253 size = GetUBwcSize(width, height, format, alignedw, alignedh);
254 } else if (IsUncompressedRGBFormat(format)) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700255 uint32_t bpp = GetBppForUncompressedRGB(format);
256 size = alignedw * alignedh * bpp;
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400257 } else if (IsCompressedRGBFormat(format)) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700258 size = alignedw * alignedh * ASTC_BLOCK_SIZE;
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400259 } else {
260 // Below switch should be for only YUV/custom formats
261 switch (format) {
262 case HAL_PIXEL_FORMAT_RAW16:
263 case HAL_PIXEL_FORMAT_Y16:size = alignedw * alignedh * 2;
264 break;
265 case HAL_PIXEL_FORMAT_RAW10:
266 case HAL_PIXEL_FORMAT_RAW12:size = ALIGN(alignedw * alignedh, SIZE_4K);
267 break;
268 case HAL_PIXEL_FORMAT_RAW8:
269 case HAL_PIXEL_FORMAT_Y8:size = alignedw * alignedh * 1;
270 break;
271 // adreno formats
272 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
273 size = ALIGN(alignedw * alignedh, SIZE_4K);
274 size += (unsigned int) ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
275 break;
276 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
277 // The chroma plane is subsampled,
278 // but the pitch in bytes is unchanged
279 // The GPU needs 4K alignment, but the video decoder needs 8K
280 size = ALIGN(alignedw * alignedh, SIZE_8K);
281 size += ALIGN(alignedw * (unsigned int) ALIGN(height / 2, 32), SIZE_8K);
282 break;
283 case HAL_PIXEL_FORMAT_YV12:
284 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
285 ALOGE("w or h is odd for the YV12 format");
286 return 0;
287 }
288 size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
289 size = ALIGN(size, (unsigned int) SIZE_4K);
290 break;
291 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
292 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
293 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
294 break;
295 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
296 size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
297 break;
298 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
299 size = VENUS_BUFFER_SIZE(COLOR_FMT_P010,
300 width,
301 height);
302 break;
303 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
304 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
305 case HAL_PIXEL_FORMAT_YCbCr_422_I:
306 case HAL_PIXEL_FORMAT_YCrCb_422_I:
307 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
308 if (width & 1) {
309 ALOGE("width is odd for the YUV422_SP format");
310 return 0;
311 }
312 size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
313 break;
314 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
315 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
316 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
317 break;
318 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
319 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
320 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
321 break;
322 case HAL_PIXEL_FORMAT_BLOB:
323 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
324 if (height != 1) {
325 ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
326 return 0;
327 }
328 size = (unsigned int) width;
329 break;
330 case HAL_PIXEL_FORMAT_NV21_ZSL:
331 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2,
332 SIZE_4K);
333 break;
Rajavenu Kyatham6e8c1822018-07-31 10:27:19 +0530334 case HAL_PIXEL_FORMAT_NV12_HEIF:
335 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_512, width, height);
336 break;
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400337 default:ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
338 return 0;
339 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700340 }
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400341 auto align = GetDataAlignment(format, usage);
342 size = ALIGN(size, align) * info.layer_count;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700343 return size;
344}
345
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700346int GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
347 unsigned int *alignedh) {
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +0530348 GraphicsMetadata graphics_metadata = {};
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700349 return GetBufferSizeAndDimensions(info, size, alignedw, alignedh, &graphics_metadata);
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +0530350}
351
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700352int GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
353 unsigned int *alignedh, GraphicsMetadata *graphics_metadata) {
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +0530354 int buffer_type = GetBufferType(info.format);
355 if (CanUseAdrenoForSize(buffer_type, info.usage)) {
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700356 return GetGpuResourceSizeAndDimensions(info, size, alignedw, alignedh, graphics_metadata);
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +0530357 } else {
358 GetAlignedWidthAndHeight(info, alignedw, alignedh);
359 *size = GetSize(info, *alignedw, *alignedh);
360 }
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700361 return 0;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700362}
363
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530364void GetYuvUbwcSPPlaneInfo(uint32_t width, uint32_t height, int color_format,
365 PlaneLayoutInfo *plane_info) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700366 // UBWC buffer has these 4 planes in the following sequence:
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530367 // Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700368 unsigned int y_meta_stride, y_meta_height, y_meta_size;
369 unsigned int y_stride, y_height, y_size;
370 unsigned int c_meta_stride, c_meta_height, c_meta_size;
371 unsigned int alignment = 4096;
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530372 unsigned int c_stride, c_height, c_size;
373 uint64_t yOffset, cOffset, yMetaOffset, cMetaOffset;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700374
375 y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
376 y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
377 y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
378
379 y_stride = VENUS_Y_STRIDE(color_format, INT(width));
380 y_height = VENUS_Y_SCANLINES(color_format, INT(height));
381 y_size = ALIGN((y_stride * y_height), alignment);
382
383 c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
384 c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
385 c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
386
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530387 c_stride = VENUS_UV_STRIDE(color_format, INT(width));
388 c_height = VENUS_UV_SCANLINES(color_format, INT(height));
389 c_size = ALIGN((c_stride * c_height), alignment);
390
391 yMetaOffset = 0;
392 yOffset = y_meta_size;
393 cMetaOffset = y_meta_size + y_size;
394 cOffset = y_meta_size + y_size + c_meta_size;
395
396 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
397 plane_info[0].offset = (uint32_t)yOffset;
398 plane_info[0].stride = static_cast<int32_t>(UINT(width));
399 plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
400 plane_info[0].scanlines = static_cast<int32_t>(y_height);
401 plane_info[0].size = static_cast<uint32_t>(y_size);
402
403 plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
404 plane_info[1].offset = (uint32_t)cOffset;
405 plane_info[1].stride = static_cast<int32_t>(UINT(width));
406 plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
407 plane_info[1].scanlines = static_cast<int32_t>(c_height);
408 plane_info[1].size = static_cast<uint32_t>(c_size);
409
410 plane_info[2].component = (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Y);
411 plane_info[2].offset = (uint32_t)yMetaOffset;
412 plane_info[2].stride = static_cast<int32_t>(UINT(width));
413 plane_info[2].stride_bytes = static_cast<int32_t>(y_meta_stride);
414 plane_info[2].scanlines = static_cast<int32_t>(y_meta_height);
415 plane_info[2].size = static_cast<uint32_t>(y_meta_size);
416
417 plane_info[3].component =
418 (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
419 plane_info[3].offset = (uint32_t)cMetaOffset;
420 plane_info[3].stride = static_cast<int32_t>(UINT(width));
421 plane_info[3].stride_bytes = static_cast<int32_t>(c_meta_stride);
422 plane_info[3].scanlines = static_cast<int32_t>(c_meta_height);
423 plane_info[3].size = static_cast<uint32_t>(c_meta_size);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700424}
425
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530426// This API gets information about 8 planes (Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane,
427// Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane) and it stores the
428// information in PlaneLayoutInfo array.
429void GetYuvUbwcInterlacedSPPlaneInfo(uint32_t width, uint32_t height,
430 PlaneLayoutInfo plane_info[8]) {
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700431 // UBWC interlaced has top-bottom field layout with each field as
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530432 // 8-plane (including meta plane also) NV12_UBWC with width = image_width
433 // & height = image_height / 2.
434 // Client passed plane_info argument is ptr to struct PlaneLayoutInfo[8].
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700435 // Plane info to be filled for each field separately.
436 height = (height + 1) >> 1;
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700437
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530438 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, &plane_info[0]);
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700439
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530440 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, &plane_info[4]);
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700441}
442
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530443// This API gets information about 2 planes (Y_Plane & UV_Plane)
444void GetYuvSPPlaneInfo(const BufferInfo &info, int format, uint32_t width, uint32_t height,
445 uint32_t bpp, PlaneLayoutInfo *plane_info) {
446 int unaligned_width = info.width;
447 int unaligned_height = info.height;
448 unsigned int y_stride = 0, y_height = 0, y_size = 0;
449 unsigned int c_stride = 0, c_height = 0, c_size = 0;
450 uint64_t yOffset, cOffset;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700451
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530452 y_stride = c_stride = UINT(width) * bpp;
453 y_height = INT(height);
454 y_size = y_stride * y_height;
455 switch (format) {
456 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
457 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
458 c_size = (width * height) / 2 + 1;
459 c_height = height >> 1;
460 break;
461 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
462 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
463 if (unaligned_width & 1) {
464 ALOGE("width is odd for the YUV422_SP format");
465 return;
466 }
467 c_size = width * height;
468 c_height = height;
469 break;
470 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
471 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
472 c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height);
473 c_size = c_stride * c_height;
474 break;
475 case HAL_PIXEL_FORMAT_NV12_HEIF:
476 c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12_512, height);
477 c_size = c_stride * c_height;
478 break;
479 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
480 y_size = ALIGN(width * height, 4096);
481 c_size = ALIGN(2 * ALIGN(unaligned_width / 2, 32) * ALIGN(unaligned_height / 2, 32), 4096);
482 break;
483 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
Ramakant Singh13596ae2020-01-06 20:12:34 +0530484 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530485 c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV21, height);
486 c_size = c_stride * c_height;
487 break;
488 case HAL_PIXEL_FORMAT_NV21_ZSL:
489 c_size = (width * height) / 2;
490 c_height = height >> 1;
491 break;
492 case HAL_PIXEL_FORMAT_RAW16:
493 case HAL_PIXEL_FORMAT_Y16:
494 c_size = width * height;
495 c_height = height;
496 break;
497 case HAL_PIXEL_FORMAT_RAW10:
498 c_size = 0;
499 break;
500 case HAL_PIXEL_FORMAT_RAW8:
501 case HAL_PIXEL_FORMAT_Y8:
502 c_size = 0;
503 break;
504 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
505 c_size = (width * height) + 1;
506 c_height = height;
507 break;
508 default:
509 break;
510 }
511
512 yOffset = 0;
513 cOffset = y_size;
514
515 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
516 plane_info[0].offset = (uint32_t)yOffset;
517 plane_info[0].step = 1;
518 plane_info[0].stride = static_cast<int32_t>(UINT(width));
519 plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
520 plane_info[0].scanlines = static_cast<int32_t>(y_height);
521 plane_info[0].size = static_cast<uint32_t>(y_size);
522
523 plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
524 plane_info[1].offset = (uint32_t)cOffset;
525 plane_info[1].step = 2 * bpp;
526 plane_info[1].stride = static_cast<int32_t>(UINT(width));
527 plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
528 plane_info[1].scanlines = static_cast<int32_t>(c_height);
529 plane_info[1].size = static_cast<uint32_t>(c_size);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700530}
531
Naseer Ahmed7aff2612017-10-05 20:39:05 -0400532int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700533 int err = 0;
534 uint32_t width = UINT(hnd->width);
535 uint32_t height = UINT(hnd->height);
536 int format = hnd->format;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500537 uint64_t usage = hnd->usage;
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530538 int32_t interlaced = 0;
539 int plane_count = 0;
540 int unaligned_width = INT(hnd->unaligned_width);
541 int unaligned_height = INT(hnd->unaligned_height);
542 BufferInfo info(unaligned_width, unaligned_height, format, usage);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700543
544 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700545
546 // Check if UBWC buffer has been rendered in linear format.
Ramakant Singhc7d07792017-07-26 15:36:33 +0530547 int linear_format = 0;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500548 if (getMetaData(const_cast<private_handle_t *>(hnd), GET_LINEAR_FORMAT, &linear_format) == 0) {
549 format = INT(linear_format);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700550 }
551
552 // Check metadata if the geometry has been updated.
Ramakant Singhc7d07792017-07-26 15:36:33 +0530553 BufferDim_t buffer_dim;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500554 if (getMetaData(const_cast<private_handle_t *>(hnd), GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
555 BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format, usage);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700556 GetAlignedWidthAndHeight(info, &width, &height);
557 }
558
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700559 // Check metadata for interlaced content.
Ramakant Singhc7d07792017-07-26 15:36:33 +0530560 int interlace_flag = 0;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500561 if (getMetaData(const_cast<private_handle_t *>(hnd), GET_PP_PARAM_INTERLACED, &interlace_flag) ==
562 0) {
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530563 if (interlace_flag) {
564 interlaced = LAYOUT_INTERLACED_FLAG;
565 }
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700566 }
567
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530568 PlaneLayoutInfo plane_info[8] = {};
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700569 // Get the chroma offsets from the handle width/height. We take advantage
570 // of the fact the width _is_ the stride
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530571 err = GetYUVPlaneInfo(info, format, width, height, interlaced, &plane_count, plane_info);
572 if (err == 0) {
573 if (interlaced && format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC) {
574 CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, &plane_info[0], &ycbcr[0]);
575 unsigned int uv_stride, uv_height, uv_size;
576 unsigned int alignment = 4096;
577 uint64_t field_base;
578 height = (height + 1) >> 1;
579 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, INT(width));
580 uv_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, INT(height));
581 uv_size = ALIGN((uv_stride * uv_height), alignment);
582 field_base = hnd->base + plane_info[1].offset + uv_size;
583 memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
584 CopyPlaneLayoutInfotoAndroidYcbcr(field_base, plane_count, &plane_info[4], &ycbcr[1]);
585 } else {
586 CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, plane_info, ycbcr);
587 switch (format) {
588 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
589 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
590 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
591 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
592 case HAL_PIXEL_FORMAT_NV21_ZSL:
593 case HAL_PIXEL_FORMAT_RAW16:
594 case HAL_PIXEL_FORMAT_Y16:
595 case HAL_PIXEL_FORMAT_RAW10:
596 case HAL_PIXEL_FORMAT_RAW8:
597 case HAL_PIXEL_FORMAT_Y8:
598 std::swap(ycbcr->cb, ycbcr->cr);
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700599 }
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530600 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700601 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700602 return err;
603}
604
605// Explicitly defined UBWC formats
606bool IsUBwcFormat(int format) {
607 switch (format) {
608 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
609 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
610 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
611 return true;
612 default:
613 return false;
614 }
615}
616
617bool IsUBwcSupported(int format) {
618 // Existing HAL formats with UBWC support
619 switch (format) {
620 case HAL_PIXEL_FORMAT_BGR_565:
621 case HAL_PIXEL_FORMAT_RGBA_8888:
622 case HAL_PIXEL_FORMAT_RGBX_8888:
623 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
624 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
625 case HAL_PIXEL_FORMAT_RGBA_1010102:
626 case HAL_PIXEL_FORMAT_RGBX_1010102:
Saurabh Dubey11df8e12018-07-25 19:16:25 +0530627 case HAL_PIXEL_FORMAT_DEPTH_16:
628 case HAL_PIXEL_FORMAT_DEPTH_24:
629 case HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
630 case HAL_PIXEL_FORMAT_DEPTH_32F:
631 case HAL_PIXEL_FORMAT_STENCIL_8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700632 return true;
633 default:
634 break;
635 }
636
637 return false;
638}
639
Saurabh Dubey48b757d2018-05-24 19:13:53 +0530640bool IsUBwcPISupported(int format, uint64_t usage) {
641 if (usage & BufferUsage::COMPOSER_OVERLAY || !(usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI)) {
642 return false;
643 }
644
645 // As of now only two formats
646 switch (format) {
647 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
648 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: {
649 if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
650 if (AdrenoMemInfo::GetInstance()) {
651 return AdrenoMemInfo::GetInstance()->IsPISupportedByGPU(format, usage);
652 }
653 } else {
654 return true;
655 }
656 }
657 }
658
659 return false;
660}
661
Naseer Ahmede36f2242017-12-01 15:33:56 -0500662bool IsUBwcEnabled(int format, uint64_t usage) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700663 // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
664 if (IsUBwcFormat(format)) {
665 return true;
666 }
667
668 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
669 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
670 // usage flag and MDP supports the format.
Naseer Ahmed2023cf32019-01-28 19:02:40 -0500671 if (((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) ||
672 (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI) ||
673 (usage & BufferUsage::COMPOSER_CLIENT_TARGET))
Saurabh Dubey48b757d2018-05-24 19:13:53 +0530674 && IsUBwcSupported(format)) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700675 bool enable = true;
676 // Query GPU for UBWC only if buffer is intended to be used by GPU.
Naseer Ahmede36f2242017-12-01 15:33:56 -0500677 if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530678 if (AdrenoMemInfo::GetInstance()) {
679 enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
680 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700681 }
682
683 // Allow UBWC, only if CPU usage flags are not set
Naseer Ahmede36f2242017-12-01 15:33:56 -0500684 if (enable && !(CpuCanAccess(usage))) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700685 return true;
686 }
687 }
688
689 return false;
690}
691
692void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
693 unsigned int *aligned_h) {
694 switch (format) {
695 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
696 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
697 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
698 *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
699 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
700 break;
701 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
702 // The macro returns the stride which is 4/3 times the width, hence * 3/4
703 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
704 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
705 break;
706 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
707 // The macro returns the stride which is 2 times the width, hence / 2
708 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
709 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
710 break;
711 default:
712 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
713 *aligned_w = 0;
714 *aligned_h = 0;
715 break;
716 }
717}
718
719void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
720 *block_width = 0;
721 *block_height = 0;
722
723 switch (bpp) {
724 case 2:
725 case 4:
726 *block_width = 16;
727 *block_height = 4;
728 break;
729 case 8:
730 *block_width = 8;
731 *block_height = 4;
732 break;
733 case 16:
734 *block_width = 4;
735 *block_height = 4;
736 break;
737 default:
738 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
739 break;
740 }
741}
742
743unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
744 unsigned int size = 0;
745 int meta_width, meta_height;
746 int block_width, block_height;
747
748 GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
749 if (!block_width || !block_height) {
750 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
751 return size;
752 }
753
754 // Align meta buffer height to 16 blocks
755 meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
756
757 // Align meta buffer width to 64 blocks
758 meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
759
760 // Align meta buffer size to 4K
761 size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
762
763 return size;
764}
765
766unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
767 unsigned int alignedh) {
768 unsigned int size = 0;
769 uint32_t bpp = 0;
770 switch (format) {
771 case HAL_PIXEL_FORMAT_BGR_565:
772 case HAL_PIXEL_FORMAT_RGBA_8888:
773 case HAL_PIXEL_FORMAT_RGBX_8888:
774 case HAL_PIXEL_FORMAT_RGBA_1010102:
775 case HAL_PIXEL_FORMAT_RGBX_1010102:
776 bpp = GetBppForUncompressedRGB(format);
777 size = alignedw * alignedh * bpp;
778 size += GetRgbUBwcMetaBufferSize(width, height, bpp);
779 break;
780 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
781 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
782 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
783 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
784 break;
785 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
786 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
787 break;
788 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
789 size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
790 break;
791 default:
792 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
793 break;
794 }
795
796 return size;
797}
798
Ashish Kumar8a1b56e2019-11-15 18:15:22 +0530799unsigned int GetRgbMetaSize(int format, uint32_t width, uint32_t height, uint64_t usage) {
800 unsigned int meta_size = 0;
801 if (!IsUBwcEnabled(format, usage)) {
802 return meta_size;
803 }
804 uint32_t bpp = GetBppForUncompressedRGB(format);
805 switch (format) {
806 case HAL_PIXEL_FORMAT_BGR_565:
807 case HAL_PIXEL_FORMAT_RGBA_8888:
808 case HAL_PIXEL_FORMAT_RGBX_8888:
809 case HAL_PIXEL_FORMAT_RGBA_1010102:
810 case HAL_PIXEL_FORMAT_RGBX_1010102:
811 case HAL_PIXEL_FORMAT_RGBA_FP16:
812 meta_size = GetRgbUBwcMetaBufferSize(width, height, bpp);
813 break;
814 default:
815 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, format);
816 break;
817 }
818 return meta_size;
819}
820
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700821int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
822 int err = 0;
823
824 // This api is for RGB* formats
Naseer Ahmede36f2242017-12-01 15:33:56 -0500825 if (!IsUncompressedRGBFormat(hnd->format)) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700826 return -EINVAL;
827 }
828
829 // linear buffer, nothing to do further
830 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
831 *rgb_data = reinterpret_cast<void *>(hnd->base);
832 return err;
833 }
Ashish Kumar8a1b56e2019-11-15 18:15:22 +0530834 unsigned int meta_size = GetRgbMetaSize(hnd->format, hnd->width, hnd->height, hnd->usage);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700835
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700836 *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
837
838 return err;
839}
840
Naseer Ahmede36f2242017-12-01 15:33:56 -0500841void GetCustomDimensions(private_handle_t *hnd, int *stride, int *height) {
842 BufferDim_t buffer_dim;
843 int interlaced = 0;
844
845 *stride = hnd->width;
846 *height = hnd->height;
847 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
848 *stride = buffer_dim.sliceWidth;
849 *height = buffer_dim.sliceHeight;
850 } else if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
851 if (interlaced && IsUBwcFormat(hnd->format)) {
852 unsigned int alignedw = 0, alignedh = 0;
853 // Get re-aligned height for single ubwc interlaced field and
854 // multiply by 2 to get frame height.
855 BufferInfo info(hnd->width, ((hnd->height + 1) >> 1), hnd->format);
856 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
857 *stride = static_cast<int>(alignedw);
858 *height = static_cast<int>(alignedh * 2);
859 }
860 }
861}
862
863void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space) {
864 ColorMetaData color_metadata;
865 if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
866 switch (color_metadata.colorPrimaries) {
867 case ColorPrimaries_BT709_5:
868 *color_space = HAL_CSC_ITU_R_709;
869 break;
870 case ColorPrimaries_BT601_6_525:
871 case ColorPrimaries_BT601_6_625:
872 *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
873 break;
874 case ColorPrimaries_BT2020:
875 *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
876 break;
877 default:
878 ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
879 break;
880 }
881 } else if (getMetaData(hnd, GET_COLOR_SPACE, color_space) != 0) {
882 *color_space = 0;
883 }
884}
885
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700886void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
887 unsigned int *alignedh) {
888 int width = info.width;
889 int height = info.height;
890 int format = info.format;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500891 uint64_t usage = info.usage;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700892
893 // Currently surface padding is only computed for RGB* surfaces.
Naseer Ahmede36f2242017-12-01 15:33:56 -0500894 bool ubwc_enabled = IsUBwcEnabled(format, usage);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700895 int tile = ubwc_enabled;
896
897 if (IsUncompressedRGBFormat(format)) {
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530898 if (AdrenoMemInfo::GetInstance()) {
899 AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
900 alignedh);
901 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700902 return;
903 }
904
905 if (ubwc_enabled) {
906 GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
907 return;
908 }
909
910 if (IsCompressedRGBFormat(format)) {
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530911 if (AdrenoMemInfo::GetInstance()) {
912 AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
913 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700914 return;
915 }
916
917 int aligned_w = width;
918 int aligned_h = height;
919 unsigned int alignment = 32;
920
921 // Below should be only YUV family
922 switch (format) {
923 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
924 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530925 if (AdrenoMemInfo::GetInstance() == nullptr) {
926 return;
927 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700928 alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
929 aligned_w = ALIGN(width, alignment);
930 break;
931 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
932 aligned_w = ALIGN(width, alignment);
933 break;
934 case HAL_PIXEL_FORMAT_RAW16:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530935 case HAL_PIXEL_FORMAT_Y16:
936 case HAL_PIXEL_FORMAT_Y8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700937 aligned_w = ALIGN(width, 16);
938 break;
939 case HAL_PIXEL_FORMAT_RAW12:
Naseer Ahmed1187a572017-08-14 13:16:55 -0400940 aligned_w = ALIGN(width * 12 / 8, 16);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700941 break;
942 case HAL_PIXEL_FORMAT_RAW10:
Naseer Ahmed1187a572017-08-14 13:16:55 -0400943 aligned_w = ALIGN(width * 10 / 8, 16);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700944 break;
945 case HAL_PIXEL_FORMAT_RAW8:
Naseer Ahmed1187a572017-08-14 13:16:55 -0400946 aligned_w = ALIGN(width, 16);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700947 break;
948 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
949 aligned_w = ALIGN(width, 128);
950 break;
951 case HAL_PIXEL_FORMAT_YV12:
952 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
953 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
954 case HAL_PIXEL_FORMAT_YCbCr_422_I:
955 case HAL_PIXEL_FORMAT_YCrCb_422_I:
956 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
957 aligned_w = ALIGN(width, 16);
958 break;
Mathew Joseph Karimpanala73082e2017-10-16 18:01:21 +0530959 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
960 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_P010, width) / 2);
961 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
962 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700963 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
964 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
965 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
966 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
967 break;
968 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
Ramakant Singh13596ae2020-01-06 20:12:34 +0530969 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700970 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
971 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
972 break;
973 case HAL_PIXEL_FORMAT_BLOB:
974 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
975 break;
976 case HAL_PIXEL_FORMAT_NV21_ZSL:
977 aligned_w = ALIGN(width, 64);
978 aligned_h = ALIGN(height, 64);
979 break;
Rajavenu Kyatham6e8c1822018-07-31 10:27:19 +0530980 case HAL_PIXEL_FORMAT_NV12_HEIF:
981 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12_512, width));
982 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12_512, height));
983 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700984 default:
985 break;
986 }
987
988 *alignedw = (unsigned int)aligned_w;
989 *alignedh = (unsigned int)aligned_h;
990}
991
Naseer Ahmede36f2242017-12-01 15:33:56 -0500992int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
993 uint32_t *num_planes) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700994 if (!hnd || !stride || !offset || !num_planes) {
995 return -EINVAL;
996 }
997
Naseer Ahmed7aff2612017-10-05 20:39:05 -0400998 struct android_ycbcr yuvPlaneInfo[2] = {};
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700999 *num_planes = 1;
1000 stride[0] = 0;
1001
1002 switch (hnd->format) {
1003 case HAL_PIXEL_FORMAT_RGB_565:
1004 case HAL_PIXEL_FORMAT_BGR_565:
1005 case HAL_PIXEL_FORMAT_RGBA_5551:
1006 case HAL_PIXEL_FORMAT_RGBA_4444:
1007 stride[0] = static_cast<uint32_t>(hnd->width * 2);
1008 break;
1009 case HAL_PIXEL_FORMAT_RGB_888:
1010 stride[0] = static_cast<uint32_t>(hnd->width * 3);
1011 break;
1012 case HAL_PIXEL_FORMAT_RGBA_8888:
1013 case HAL_PIXEL_FORMAT_BGRA_8888:
1014 case HAL_PIXEL_FORMAT_RGBX_8888:
1015 case HAL_PIXEL_FORMAT_BGRX_8888:
1016 case HAL_PIXEL_FORMAT_RGBA_1010102:
1017 case HAL_PIXEL_FORMAT_ARGB_2101010:
1018 case HAL_PIXEL_FORMAT_RGBX_1010102:
1019 case HAL_PIXEL_FORMAT_XRGB_2101010:
1020 case HAL_PIXEL_FORMAT_BGRA_1010102:
1021 case HAL_PIXEL_FORMAT_ABGR_2101010:
1022 case HAL_PIXEL_FORMAT_BGRX_1010102:
1023 case HAL_PIXEL_FORMAT_XBGR_2101010:
1024 stride[0] = static_cast<uint32_t>(hnd->width * 4);
1025 break;
1026 }
1027
1028 // Format is RGB
1029 if (stride[0]) {
1030 return 0;
1031 }
1032
1033 (*num_planes)++;
Naseer Ahmed7aff2612017-10-05 20:39:05 -04001034 int ret = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001035 if (ret < 0) {
1036 ALOGE("%s failed", __FUNCTION__);
1037 return ret;
1038 }
1039
Naseer Ahmed7aff2612017-10-05 20:39:05 -04001040 // We are only returning buffer layout for progressive or single field formats.
1041 struct android_ycbcr yuvInfo = yuvPlaneInfo[0];
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001042 stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
1043 offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
1044 stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
1045 switch (hnd->format) {
1046 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1047 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1048 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1049 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1050 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1051 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1052 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1053 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
Mathew Joseph Karimpanala73082e2017-10-16 18:01:21 +05301054 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
Rajavenu Kyatham6e8c1822018-07-31 10:27:19 +05301055 case HAL_PIXEL_FORMAT_NV12_HEIF:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001056 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
1057 break;
1058 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1059 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1060 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
Ramakant Singh13596ae2020-01-06 20:12:34 +05301061 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001062 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
1063 break;
1064 case HAL_PIXEL_FORMAT_YV12:
1065 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
1066 stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
1067 offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
1068 (*num_planes)++;
1069 break;
Camus Wonga300db62018-09-27 16:38:50 -04001070 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1071 *num_planes = 1;
1072 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001073 default:
1074 ALOGW("%s: Unsupported format", __FUNCTION__);
1075 ret = -EINVAL;
1076 }
1077
1078 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
1079 std::fill(offset, offset + 4, 0);
1080 }
1081
1082 return 0;
1083}
1084
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -07001085int GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
1086 unsigned int *alignedw, unsigned int *alignedh,
1087 GraphicsMetadata *graphics_metadata) {
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301088 GetAlignedWidthAndHeight(info, alignedw, alignedh);
1089 AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
1090 graphics_metadata->size = adreno_mem_info->AdrenoGetMetadataBlobSize();
1091 uint64_t adreno_usage = info.usage;
1092 // If gralloc disables UBWC based on any of the checks,
1093 // we pass modified usage flag to adreno to convey this.
1094 int is_ubwc_enabled = IsUBwcEnabled(info.format, info.usage);
1095 if (!is_ubwc_enabled) {
1096 adreno_usage &= ~(GRALLOC_USAGE_PRIVATE_ALLOC_UBWC);
Naseer Ahmed2023cf32019-01-28 19:02:40 -05001097 } else {
1098 adreno_usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301099 }
1100
1101 // Call adreno api for populating metadata blob
Saurabh Dubeyb637bb32018-05-15 16:20:10 +05301102 // Layer count is for 2D/Cubemap arrays and depth is used for 3D slice
1103 // Using depth to pass layer_count here
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301104 int ret = adreno_mem_info->AdrenoInitMemoryLayout(graphics_metadata->data, info.width,
Saurabh Dubeyb637bb32018-05-15 16:20:10 +05301105 info.height, info.layer_count, /* depth */
1106 info.format, 1, is_ubwc_enabled,
1107 adreno_usage, 1);
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301108 if (ret != 0) {
1109 ALOGE("%s Graphics metadata init failed", __FUNCTION__);
1110 *size = 0;
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -07001111 return -EINVAL;
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301112 }
1113 // Call adreno api with the metadata blob to get buffer size
1114 *size = adreno_mem_info->AdrenoGetAlignedGpuBufferSize(graphics_metadata->data);
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -07001115 return 0;
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301116}
1117
Saurabh Dubey52eb7a62018-06-15 16:31:23 +05301118bool CanUseAdrenoForSize(int buffer_type, uint64_t usage) {
1119 if (buffer_type == BUFFER_TYPE_VIDEO || !GetAdrenoSizeAPIStatus()) {
1120 return false;
1121 }
1122
1123 if ((usage & BufferUsage::PROTECTED) && ((usage & BufferUsage::CAMERA_OUTPUT) ||
1124 (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY))) {
1125 return false;
1126 }
1127
1128 return true;
1129}
1130
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301131bool GetAdrenoSizeAPIStatus() {
1132 AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
1133 if (adreno_mem_info) {
1134 return adreno_mem_info->AdrenoSizeAPIAvaliable();
1135 }
1136 return false;
1137}
1138
Saurabh Dubey48b757d2018-05-24 19:13:53 +05301139bool UseUncached(int format, uint64_t usage) {
1140 if ((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) || (usage & BufferUsage::PROTECTED)) {
1141 return true;
1142 }
1143
1144 // CPU read rarely
1145 if ((usage & BufferUsage::CPU_READ_MASK) == static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) {
1146 return true;
1147 }
1148
1149 // CPU write rarely
1150 if ((usage & BufferUsage::CPU_WRITE_MASK) ==
1151 static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) {
1152 return true;
1153 }
1154
1155 if ((usage & BufferUsage::SENSOR_DIRECT_DATA) || (usage & BufferUsage::GPU_DATA_BUFFER)) {
1156 return true;
1157 }
1158
1159 if (format && IsUBwcEnabled(format, usage)) {
1160 return true;
1161 }
1162
1163 return false;
1164}
1165
1166uint64_t GetHandleFlags(int format, uint64_t usage) {
1167 uint64_t priv_flags = 0;
1168
1169 if (usage & BufferUsage::VIDEO_ENCODER) {
1170 priv_flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
1171 }
1172
1173 if (usage & BufferUsage::CAMERA_OUTPUT) {
1174 priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
1175 }
1176
1177 if (usage & BufferUsage::CAMERA_INPUT) {
1178 priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
1179 }
1180
1181 if (usage & BufferUsage::COMPOSER_OVERLAY) {
1182 priv_flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
1183 }
1184
1185 if (usage & BufferUsage::GPU_TEXTURE) {
1186 priv_flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
1187 }
1188
1189 if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
1190 priv_flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
1191 }
1192
1193 if (IsUBwcEnabled(format, usage)) {
1194 if (IsUBwcPISupported(format, usage)) {
1195 priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI;
1196 } else {
1197 priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1198 }
1199 }
1200
1201 if (usage & (BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK)) {
1202 priv_flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
1203 }
1204
1205 if ((usage & (BufferUsage::VIDEO_ENCODER | BufferUsage::VIDEO_DECODER |
1206 BufferUsage::CAMERA_OUTPUT | BufferUsage::GPU_RENDER_TARGET))) {
1207 priv_flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
1208 }
1209
1210 if (!UseUncached(format, usage)) {
1211 priv_flags |= private_handle_t::PRIV_FLAGS_CACHED;
1212 }
1213
1214 return priv_flags;
1215}
1216
1217int GetImplDefinedFormat(uint64_t usage, int format) {
1218 int gr_format = format;
1219
1220 // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
1221 // the usage bits, gralloc assigns a format.
1222 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
1223 format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
Mathew Joseph Karimpanal71517182018-08-14 16:40:34 +05301224 if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC || usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI)
1225 && format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
Saurabh Dubey81aef932018-06-27 09:41:31 +05301226 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
Saurabh Dubey48b757d2018-05-24 19:13:53 +05301227 } else if (usage & BufferUsage::VIDEO_ENCODER) {
1228 if (usage & GRALLOC_USAGE_PRIVATE_VIDEO_NV21_ENCODER) {
1229 gr_format = HAL_PIXEL_FORMAT_NV21_ENCODEABLE; // NV21
Manikanta Kanamarlapudidfa32e82019-03-26 14:06:47 +05301230 } else if (usage & GRALLOC_USAGE_PRIVATE_HEIF) {
1231 gr_format = HAL_PIXEL_FORMAT_NV12_HEIF;
Mathew Joseph Karimpanal71517182018-08-14 16:40:34 +05301232 } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1233 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
Saurabh Dubey48b757d2018-05-24 19:13:53 +05301234 } else {
1235 gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; // NV12
1236 }
1237 } else if (usage & BufferUsage::CAMERA_INPUT) {
1238 if (usage & BufferUsage::CAMERA_OUTPUT) {
1239 // Assumed ZSL if both producer and consumer camera flags set
1240 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
1241 } else {
1242 gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; // NV21
1243 }
1244 } else if (usage & BufferUsage::CAMERA_OUTPUT) {
1245 if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1246 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
1247 } else {
1248 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; // NV12 preview
1249 }
1250 } else if (usage & BufferUsage::COMPOSER_OVERLAY) {
1251 // XXX: If we still haven't set a format, default to RGBA8888
1252 gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
1253 } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1254 // If no other usage flags are detected, default the
1255 // flexible YUV format to NV21_ZSL
1256 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
1257 }
1258 }
1259
1260 return gr_format;
1261}
1262
1263int GetCustomFormatFlags(int format, uint64_t usage,
1264 int *custom_format, uint64_t *priv_flags) {
1265 *custom_format = GetImplDefinedFormat(usage, format);
1266 *priv_flags = GetHandleFlags(*custom_format, usage);
1267
Saurabh Dubey81aef932018-06-27 09:41:31 +05301268 if (usage & GRALLOC_USAGE_PROTECTED) {
1269 *priv_flags |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
1270 }
1271
1272 *priv_flags |= private_handle_t::PRIV_FLAGS_USES_ION;
1273
Saurabh Dubey48b757d2018-05-24 19:13:53 +05301274 return 0;
1275}
1276
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +05301277int GetBufferType(int inputFormat) {
1278 return IsYuvFormat(inputFormat) ? BUFFER_TYPE_VIDEO : BUFFER_TYPE_UI;
1279}
1280
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301281int GetYUVPlaneInfo(const BufferInfo &info, int32_t format, int32_t width, int32_t height,
1282 int32_t flags, int *plane_count, PlaneLayoutInfo *plane_info) {
1283 int err = 0;
1284 unsigned int y_stride, c_stride, y_height, c_height, y_size, c_size;
1285 uint64_t yOffset, cOffset, crOffset, cbOffset;
1286 int h_subsampling = 0, v_subsampling = 0;
1287 switch (format) {
1288 // Semiplanar
1289 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1290 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1291 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1292 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
Ramakant Singh13596ae2020-01-06 20:12:34 +05301293 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301294 case HAL_PIXEL_FORMAT_NV12_HEIF: // Same as YCbCr_420_SP_VENUS
1295 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1296 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1297 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1298 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1299 case HAL_PIXEL_FORMAT_NV21_ZSL:
1300 case HAL_PIXEL_FORMAT_RAW16:
1301 case HAL_PIXEL_FORMAT_Y16:
1302 case HAL_PIXEL_FORMAT_RAW10:
1303 case HAL_PIXEL_FORMAT_RAW8:
1304 case HAL_PIXEL_FORMAT_Y8:
1305 *plane_count = 2;
1306 GetYuvSPPlaneInfo(info, format, width, height, 1, plane_info);
1307 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1308 plane_info[0].h_subsampling = 0;
1309 plane_info[0].v_subsampling = 0;
1310 plane_info[1].h_subsampling = h_subsampling;
1311 plane_info[1].v_subsampling = v_subsampling;
1312 break;
1313
1314 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1315 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1316 if (flags & LAYOUT_INTERLACED_FLAG) {
1317 *plane_count = 8;
1318 GetYuvUbwcInterlacedSPPlaneInfo(width, height, plane_info);
1319 plane_info[0].step = plane_info[4].step = 1;
1320 plane_info[1].step = plane_info[5].step = 2;
1321 plane_info[0].h_subsampling = plane_info[4].h_subsampling = 0;
1322 plane_info[0].v_subsampling = plane_info[4].v_subsampling = 0;
1323 plane_info[1].h_subsampling = plane_info[5].h_subsampling = h_subsampling;
1324 plane_info[1].v_subsampling = plane_info[5].v_subsampling = v_subsampling;
1325 plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1326 plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1327 plane_info[2].step = plane_info[3].step = 0;
1328 plane_info[6].h_subsampling = plane_info[7].h_subsampling = 0;
1329 plane_info[6].v_subsampling = plane_info[7].v_subsampling = 0;
1330 plane_info[6].step = plane_info[7].step = 0;
1331 } else {
1332 *plane_count = 4;
1333 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, plane_info);
1334 plane_info[0].h_subsampling = 0;
1335 plane_info[0].v_subsampling = 0;
1336 plane_info[0].step = 1;
1337 plane_info[1].h_subsampling = h_subsampling;
1338 plane_info[1].v_subsampling = v_subsampling;
1339 plane_info[1].step = 2;
1340 plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1341 plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1342 plane_info[2].step = plane_info[3].step = 0;
1343 }
1344 break;
1345
1346 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1347 *plane_count = 2;
1348 GetYuvSPPlaneInfo(info, format, width, height, 2, plane_info);
1349 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1350 plane_info[0].h_subsampling = 0;
1351 plane_info[0].v_subsampling = 0;
1352 plane_info[1].h_subsampling = h_subsampling;
1353 plane_info[1].v_subsampling = v_subsampling;
1354 break;
1355
1356 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1357 *plane_count = 4;
1358 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_BPP10_UBWC, plane_info);
1359 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1360 plane_info[0].h_subsampling = 0;
1361 plane_info[0].v_subsampling = 0;
1362 plane_info[1].step = 1;
1363 plane_info[1].h_subsampling = h_subsampling;
1364 plane_info[1].v_subsampling = v_subsampling;
1365 plane_info[1].step = 3;
1366 plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1367 plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1368 plane_info[2].step = plane_info[3].step = 0;
1369 break;
1370
1371 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1372 *plane_count = 4;
1373 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_P010_UBWC, plane_info);
1374 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1375 plane_info[0].h_subsampling = 0;
1376 plane_info[0].v_subsampling = 0;
1377 plane_info[1].step = 1;
1378 plane_info[1].h_subsampling = h_subsampling;
1379 plane_info[1].v_subsampling = v_subsampling;
1380 plane_info[1].step = 4;
1381 plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1382 plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1383 plane_info[2].step = plane_info[3].step = 0;
1384 break;
1385
1386 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1387 *plane_count = 2;
1388 y_stride = VENUS_Y_STRIDE(COLOR_FMT_P010, width);
1389 c_stride = VENUS_UV_STRIDE(COLOR_FMT_P010, width);
1390 y_height = VENUS_Y_SCANLINES(COLOR_FMT_P010, height);
1391 y_size = y_stride * y_height;
1392 yOffset = 0;
1393 cOffset = y_size;
1394 c_height = VENUS_UV_SCANLINES(COLOR_FMT_P010, INT(height));
1395 c_size = c_stride * c_height;
1396 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1397
1398 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
1399 plane_info[0].offset = (uint32_t)yOffset;
1400 plane_info[0].stride = static_cast<int32_t>(UINT(width));
1401 plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
1402 plane_info[0].scanlines = static_cast<int32_t>(y_height);
1403 plane_info[0].size = static_cast<uint32_t>(y_size);
1404 plane_info[0].step = 1;
1405 plane_info[0].h_subsampling = 0;
1406 plane_info[0].v_subsampling = 0;
1407
1408 plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
1409 plane_info[1].offset = (uint32_t)cOffset;
1410 plane_info[1].stride = static_cast<int32_t>(UINT(width));
1411 plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
1412 plane_info[1].scanlines = static_cast<int32_t>(c_height);
1413 plane_info[1].size = static_cast<uint32_t>(c_size);
1414 plane_info[1].step = 4;
1415 plane_info[1].h_subsampling = h_subsampling;
1416 plane_info[1].v_subsampling = v_subsampling;
1417 break;
1418
1419 // Planar
1420 case HAL_PIXEL_FORMAT_YV12:
1421 if ((info.width & 1) || (info.height & 1)) {
1422 ALOGE("w or h is odd for the YV12 format");
1423 err = -EINVAL;
1424 return err;
1425 }
1426 *plane_count = 3;
1427 y_stride = width;
1428 c_stride = ALIGN(width / 2, 16);
1429 y_height = UINT(height);
1430 y_size = (y_stride * y_height);
1431 height = height >> 1;
1432 c_height = UINT(height);
1433 c_size = (c_stride * c_height);
1434 yOffset = 0;
1435 crOffset = y_size;
1436 cbOffset = (y_size + c_size);
1437 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1438
1439 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
1440 plane_info[0].offset = (uint32_t)yOffset;
1441 plane_info[0].stride = static_cast<int32_t>(UINT(width));
1442 plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
1443 plane_info[0].scanlines = static_cast<int32_t>(y_height);
1444 plane_info[0].size = static_cast<uint32_t>(y_size);
1445 plane_info[0].step = 1;
1446 plane_info[0].h_subsampling = 0;
1447 plane_info[0].v_subsampling = 0;
1448
1449 plane_info[1].component = (PlaneComponent)PLANE_COMPONENT_Cb;
1450 plane_info[1].offset = (uint32_t)cbOffset;
1451 plane_info[2].component = (PlaneComponent)PLANE_COMPONENT_Cr;
1452 plane_info[2].offset = (uint32_t)crOffset;
1453 for (int i = 1; i < 3; i++) {
1454 plane_info[i].stride = static_cast<int32_t>(UINT(width));
1455 plane_info[i].stride_bytes = static_cast<int32_t>(c_stride);
1456 plane_info[i].scanlines = static_cast<int32_t>(c_height);
1457 plane_info[i].size = static_cast<uint32_t>(c_size);
1458 plane_info[i].step = 1;
1459 plane_info[i].h_subsampling = h_subsampling;
1460 plane_info[i].v_subsampling = v_subsampling;
1461 }
1462 break;
1463 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1464 if (info.width & 1) {
1465 ALOGE("width is odd for the YUV422_SP format");
1466 err = -EINVAL;
1467 return err;
1468 }
1469 *plane_count = 1;
1470 y_stride = width * 2;
1471 y_height = UINT(height);
1472 y_size = y_stride * y_height;
1473 yOffset = 0;
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 break;
1484
1485 // Unsupported formats
1486 case HAL_PIXEL_FORMAT_YCbCr_422_I:
1487 case HAL_PIXEL_FORMAT_YCrCb_422_I:
1488 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
1489 default:
1490 *plane_count = 0;
1491 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
1492 err = -EINVAL;
1493 }
1494 return err;
1495}
1496
1497void GetYuvSubSamplingFactor(int32_t format, int *h_subsampling, int *v_subsampling) {
1498 switch (format) {
1499 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1500 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1501 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1502 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1503 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1504 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1505 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1506 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1507 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1508 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1509 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
Ramakant Singh13596ae2020-01-06 20:12:34 +05301510 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301511 case HAL_PIXEL_FORMAT_NV21_ZSL:
1512 case HAL_PIXEL_FORMAT_YV12:
1513 *h_subsampling = 1;
1514 *v_subsampling = 1;
1515 break;
1516 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1517 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1518 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1519 *h_subsampling = 1;
1520 *v_subsampling = 0;
1521 break;
1522 case HAL_PIXEL_FORMAT_RAW16:
1523 case HAL_PIXEL_FORMAT_Y16:
1524 case HAL_PIXEL_FORMAT_RAW12:
1525 case HAL_PIXEL_FORMAT_RAW10:
1526 case HAL_PIXEL_FORMAT_Y8:
1527 case HAL_PIXEL_FORMAT_BLOB:
1528 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1529 case HAL_PIXEL_FORMAT_NV12_HEIF:
1530 default:
1531 *h_subsampling = 0;
1532 *v_subsampling = 0;
1533 break;
1534 }
1535}
1536
1537void CopyPlaneLayoutInfotoAndroidYcbcr(uint64_t base, int plane_count, PlaneLayoutInfo *plane_info,
1538 struct android_ycbcr *ycbcr) {
1539 ycbcr->y = reinterpret_cast<void *>(base + plane_info[0].offset);
1540 ycbcr->ystride = plane_info[0].stride_bytes;
1541 if (plane_count == 1) {
1542 ycbcr->cb = NULL;
1543 ycbcr->cr = NULL;
1544 ycbcr->cstride = 0;
1545 ycbcr->chroma_step = 0;
1546 } else if (plane_count == 2 || plane_count == 4 || plane_count == 8) {
1547 /* For YUV semiplanar :-
1548 * - In progressive & linear case plane count is 2 and plane_info[0] will
1549 * contain info about Y plane and plane_info[1] will contain info about UV plane.
1550 * - In progressive & compressed case plane count is 4 then plane_info[0] will
1551 * contain info about Y plane and plane_info[1] will contain info about UV plane.
1552 * Remaining two plane (plane_info[2] & plane_info[3]) contain info about the
1553 * Y_Meta_Plane and UV_Meta_Plane.
1554 * - In interlaced & compressed case plane count is 8 then plane_info[0], plane_info[1],
1555 * plane_info[4] & plane_info[5] will contain info about Y_plane, UV_plane, Y_plane
1556 * & UV_plane. Remaining plane will contain info about the meta planes. As in this case
1557 * this API is called twice through GetYUVPlaneInfo() with address of plane_info[0] &
1558 * plane_info[4], so this will calculate the information accordingly and will fill the
1559 * ycbcr structure with interlaced plane info only.
1560 */
1561 ycbcr->cb = reinterpret_cast<void *>(base + plane_info[1].offset);
1562 ycbcr->cr = reinterpret_cast<void *>(base + plane_info[1].offset + 1);
1563 ycbcr->cstride = plane_info[1].stride_bytes;
1564 ycbcr->chroma_step = plane_info[1].step;
1565 } else if (plane_count == 3) {
1566 /* For YUV planar :-
1567 * Plane size is 3 and plane_info[0], plane_info[1], plane_info[2] will
1568 * contain info about y_plane, cb_plane and cr_plane accordingly.
1569 */
1570 ycbcr->cb = reinterpret_cast<void *>(base + plane_info[1].offset);
1571 ycbcr->cr = reinterpret_cast<void *>(base + plane_info[2].offset);
1572 ycbcr->cstride = plane_info[1].stride_bytes;
1573 ycbcr->chroma_step = plane_info[1].step;
1574 }
1575}
1576
Ashish Kumar8a1b56e2019-11-15 18:15:22 +05301577bool HasAlphaComponent(int32_t format) {
1578 switch (format) {
1579 case HAL_PIXEL_FORMAT_RGBA_8888:
1580 case HAL_PIXEL_FORMAT_BGRA_8888:
1581 case HAL_PIXEL_FORMAT_RGBA_5551:
1582 case HAL_PIXEL_FORMAT_RGBA_4444:
1583 case HAL_PIXEL_FORMAT_RGBA_1010102:
1584 case HAL_PIXEL_FORMAT_ARGB_2101010:
1585 case HAL_PIXEL_FORMAT_BGRA_1010102:
1586 case HAL_PIXEL_FORMAT_ABGR_2101010:
1587 case HAL_PIXEL_FORMAT_RGBA_FP16:
1588 return true;
1589 default:
1590 return false;
1591 }
1592}
1593
1594void GetRGBPlaneInfo(const BufferInfo &info, int32_t format, int32_t width, int32_t height,
1595 int32_t /* flags */, int *plane_count, PlaneLayoutInfo *plane_info) {
1596 uint64_t usage = info.usage;
1597 *plane_count = 1;
1598 uint32_t bpp = 0;
1599 if (IsUncompressedRGBFormat(format)) {
1600 bpp = GetBppForUncompressedRGB(format);
1601 }
1602 plane_info->component =
1603 (PlaneComponent)(PLANE_COMPONENT_R | PLANE_COMPONENT_G | PLANE_COMPONENT_B);
1604 if (HasAlphaComponent(format)) {
1605 plane_info->component = (PlaneComponent)(plane_info->component | PLANE_COMPONENT_A);
1606 }
1607 plane_info->size = GetSize(info, width, height);
1608 plane_info->step = bpp;
1609 plane_info->offset = GetRgbMetaSize(format, width, height, usage);
1610 plane_info->h_subsampling = 0;
1611 plane_info->v_subsampling = 0;
1612 plane_info->stride = width;
1613 plane_info->stride_bytes = width * plane_info->step;
1614 plane_info->scanlines = height;
1615}
1616
Naseer Ahmede36f2242017-12-01 15:33:56 -05001617} // namespace gralloc