blob: 98e60e2cbe7dd58f70e705c2a33278ece81dfa1d [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>
Tharaga Balachandran74ab1112020-01-08 17:17:56 -050031
32#include <drm/drm_fourcc.h>
33
Saurabh Shah14c8e5b2017-04-07 10:37:23 -070034#include <algorithm>
35
Saurabh Shah14c8e5b2017-04-07 10:37:23 -070036#include "gr_adreno_info.h"
Naseer Ahmede36f2242017-12-01 15:33:56 -050037#include "gr_utils.h"
Saurabh Shah14c8e5b2017-04-07 10:37:23 -070038
39#define ASTC_BLOCK_SIZE 16
40
41#ifndef COLOR_FMT_P010_UBWC
42#define COLOR_FMT_P010_UBWC 9
43#endif
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053044
Naseer Ahmede36f2242017-12-01 15:33:56 -050045namespace gralloc {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053046
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +053047bool IsYuvFormat(int format) {
48 switch (format) {
Saurabh Shahdbb572e2018-01-04 15:38:01 -080049 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
50 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
51 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
Naseer Ahmede36f2242017-12-01 15:33:56 -050052 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
Ramakant Singh13596ae2020-01-06 20:12:34 +053053 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Saurabh Shahdbb572e2018-01-04 15:38:01 -080054 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
55 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
56 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
57 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
58 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
59 case HAL_PIXEL_FORMAT_NV21_ZSL:
60 case HAL_PIXEL_FORMAT_RAW16:
61 case HAL_PIXEL_FORMAT_Y16:
62 case HAL_PIXEL_FORMAT_RAW12:
63 case HAL_PIXEL_FORMAT_RAW10:
64 case HAL_PIXEL_FORMAT_YV12:
65 case HAL_PIXEL_FORMAT_Y8:
66 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
67 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
68 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
69 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +053070 // Below formats used by camera and VR
71 case HAL_PIXEL_FORMAT_BLOB:
72 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
Rajavenu Kyatham6e8c1822018-07-31 10:27:19 +053073 case HAL_PIXEL_FORMAT_NV12_HEIF:
Camus Wonga300db62018-09-27 16:38:50 -040074 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
Saurabh Shahdbb572e2018-01-04 15:38:01 -080075 return true;
76 default:
77 return false;
78 }
79}
80
Prabhanjan Kandula96e92342016-03-24 21:03:35 +053081bool IsUncompressedRGBFormat(int format) {
82 switch (format) {
83 case HAL_PIXEL_FORMAT_RGBA_8888:
84 case HAL_PIXEL_FORMAT_RGBX_8888:
85 case HAL_PIXEL_FORMAT_RGB_888:
86 case HAL_PIXEL_FORMAT_RGB_565:
87 case HAL_PIXEL_FORMAT_BGR_565:
88 case HAL_PIXEL_FORMAT_BGRA_8888:
89 case HAL_PIXEL_FORMAT_RGBA_5551:
90 case HAL_PIXEL_FORMAT_RGBA_4444:
91 case HAL_PIXEL_FORMAT_R_8:
92 case HAL_PIXEL_FORMAT_RG_88:
93 case HAL_PIXEL_FORMAT_BGRX_8888:
94 case HAL_PIXEL_FORMAT_RGBA_1010102:
95 case HAL_PIXEL_FORMAT_ARGB_2101010:
96 case HAL_PIXEL_FORMAT_RGBX_1010102:
97 case HAL_PIXEL_FORMAT_XRGB_2101010:
98 case HAL_PIXEL_FORMAT_BGRA_1010102:
99 case HAL_PIXEL_FORMAT_ABGR_2101010:
100 case HAL_PIXEL_FORMAT_BGRX_1010102:
101 case HAL_PIXEL_FORMAT_XBGR_2101010:
Naseer Ahmed1c473d82017-02-27 13:39:37 -0500102 case HAL_PIXEL_FORMAT_RGBA_FP16:
Camus Wong5c5e6fb2017-03-21 17:02:48 -0400103 case HAL_PIXEL_FORMAT_BGR_888:
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530104 return true;
105 default:
106 break;
107 }
108
109 return false;
110}
111
112bool IsCompressedRGBFormat(int format) {
113 switch (format) {
114 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
115 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
116 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
117 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
118 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
119 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
120 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
121 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
122 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
123 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
124 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
125 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
126 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
127 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
128 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
129 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
130 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
131 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
132 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
133 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
134 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
135 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
136 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
137 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
138 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
139 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
140 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
141 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
142 return true;
143 default:
144 break;
145 }
146
147 return false;
148}
149
150uint32_t GetBppForUncompressedRGB(int format) {
151 uint32_t bpp = 0;
152 switch (format) {
Naseer Ahmed1c473d82017-02-27 13:39:37 -0500153 case HAL_PIXEL_FORMAT_RGBA_FP16:
154 bpp = 8;
155 break;
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530156 case HAL_PIXEL_FORMAT_RGBA_8888:
157 case HAL_PIXEL_FORMAT_RGBX_8888:
158 case HAL_PIXEL_FORMAT_BGRA_8888:
159 case HAL_PIXEL_FORMAT_BGRX_8888:
Arun Kumar K.Rb97ca302017-04-06 15:59:33 -0700160 case HAL_PIXEL_FORMAT_RGBA_1010102:
161 case HAL_PIXEL_FORMAT_ARGB_2101010:
162 case HAL_PIXEL_FORMAT_RGBX_1010102:
163 case HAL_PIXEL_FORMAT_XRGB_2101010:
164 case HAL_PIXEL_FORMAT_BGRA_1010102:
165 case HAL_PIXEL_FORMAT_ABGR_2101010:
166 case HAL_PIXEL_FORMAT_BGRX_1010102:
167 case HAL_PIXEL_FORMAT_XBGR_2101010:
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530168 bpp = 4;
169 break;
170 case HAL_PIXEL_FORMAT_RGB_888:
Camus Wong5c5e6fb2017-03-21 17:02:48 -0400171 case HAL_PIXEL_FORMAT_BGR_888:
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530172 bpp = 3;
173 break;
174 case HAL_PIXEL_FORMAT_RGB_565:
175 case HAL_PIXEL_FORMAT_BGR_565:
176 case HAL_PIXEL_FORMAT_RGBA_5551:
177 case HAL_PIXEL_FORMAT_RGBA_4444:
178 bpp = 2;
179 break;
180 default:
Arun Kumar K.Rb97ca302017-04-06 15:59:33 -0700181 ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530182 break;
183 }
184
185 return bpp;
186}
187
Naseer Ahmede36f2242017-12-01 15:33:56 -0500188bool CpuCanAccess(uint64_t usage) {
189 return CpuCanRead(usage) || CpuCanWrite(usage);
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530190}
191
Naseer Ahmede36f2242017-12-01 15:33:56 -0500192bool CpuCanRead(uint64_t usage) {
193 if (usage & BufferUsage::CPU_READ_MASK) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530194 return true;
195 }
196
197 return false;
198}
199
Naseer Ahmede36f2242017-12-01 15:33:56 -0500200bool CpuCanWrite(uint64_t usage) {
201 if (usage & BufferUsage::CPU_WRITE_MASK) {
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530202 // Application intends to use CPU for rendering
203 return true;
204 }
205
206 return false;
207}
208
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400209uint32_t GetDataAlignment(int format, uint64_t usage) {
210 uint32_t align = UINT(getpagesize());
211 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
212 align = SIZE_8K;
213 }
214
215 if (usage & BufferUsage::PROTECTED) {
216 if ((usage & BufferUsage::CAMERA_OUTPUT) || (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
217 // The alignment here reflects qsee mmu V7L/V8L requirement
218 align = SZ_2M;
219 } else {
220 align = SECURE_ALIGN;
221 }
222 }
223
224 return align;
225}
226
Saurabh Dubey937c4e52018-06-26 11:31:18 +0530227bool IsGPUFlagSupported(uint64_t usage) {
228 bool ret = true;
229 if ((usage & BufferUsage::GPU_MIPMAP_COMPLETE)) {
230 ALOGE("GPU_MIPMAP_COMPLETE not supported");
231 ret = false;
232 }
233
234 if ((usage & BufferUsage::GPU_CUBE_MAP)) {
235 ALOGE("GPU_CUBE_MAP not supported");
236 ret = false;
237 }
238
239 return ret;
240}
241
Tharaga Balachandranab150ab2019-09-26 19:17:58 -0400242int GetBpp(int format) {
243 if (IsUncompressedRGBFormat(format)) {
244 return GetBppForUncompressedRGB(format);
245 }
246 switch (format) {
247 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
248 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
249 case HAL_PIXEL_FORMAT_RAW8:
250 case HAL_PIXEL_FORMAT_Y8:
251 return 1;
252 case HAL_PIXEL_FORMAT_RAW16:
253 case HAL_PIXEL_FORMAT_Y16:
254 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
255 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
256 case HAL_PIXEL_FORMAT_YCbCr_422_I:
257 case HAL_PIXEL_FORMAT_YCrCb_422_I:
258 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
259 return 2;
260 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
261 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
262 return 3;
263 default:
264 return -1;
265 }
266}
267
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400268// Returns the final buffer size meant to be allocated with ion
Naseer Ahmede36f2242017-12-01 15:33:56 -0500269unsigned int GetSize(const BufferInfo &info, unsigned int alignedw, unsigned int alignedh) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700270 unsigned int size = 0;
271 int format = info.format;
272 int width = info.width;
273 int height = info.height;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500274 uint64_t usage = info.usage;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700275
Saurabh Dubey937c4e52018-06-26 11:31:18 +0530276 if (!IsGPUFlagSupported(usage)) {
277 ALOGE("Unsupported GPU usage flags present 0x%" PRIx64, usage);
278 return 0;
279 }
280
Naseer Ahmede36f2242017-12-01 15:33:56 -0500281 if (IsUBwcEnabled(format, usage)) {
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400282 size = GetUBwcSize(width, height, format, alignedw, alignedh);
283 } else if (IsUncompressedRGBFormat(format)) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700284 uint32_t bpp = GetBppForUncompressedRGB(format);
285 size = alignedw * alignedh * bpp;
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400286 } else if (IsCompressedRGBFormat(format)) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700287 size = alignedw * alignedh * ASTC_BLOCK_SIZE;
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400288 } else {
289 // Below switch should be for only YUV/custom formats
290 switch (format) {
291 case HAL_PIXEL_FORMAT_RAW16:
292 case HAL_PIXEL_FORMAT_Y16:size = alignedw * alignedh * 2;
293 break;
294 case HAL_PIXEL_FORMAT_RAW10:
295 case HAL_PIXEL_FORMAT_RAW12:size = ALIGN(alignedw * alignedh, SIZE_4K);
296 break;
297 case HAL_PIXEL_FORMAT_RAW8:
298 case HAL_PIXEL_FORMAT_Y8:size = alignedw * alignedh * 1;
299 break;
300 // adreno formats
301 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
302 size = ALIGN(alignedw * alignedh, SIZE_4K);
303 size += (unsigned int) ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
304 break;
305 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
306 // The chroma plane is subsampled,
307 // but the pitch in bytes is unchanged
308 // The GPU needs 4K alignment, but the video decoder needs 8K
309 size = ALIGN(alignedw * alignedh, SIZE_8K);
310 size += ALIGN(alignedw * (unsigned int) ALIGN(height / 2, 32), SIZE_8K);
311 break;
312 case HAL_PIXEL_FORMAT_YV12:
313 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
314 ALOGE("w or h is odd for the YV12 format");
315 return 0;
316 }
317 size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
318 size = ALIGN(size, (unsigned int) SIZE_4K);
319 break;
320 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
321 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
322 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
323 break;
324 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
325 size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
326 break;
327 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
328 size = VENUS_BUFFER_SIZE(COLOR_FMT_P010,
329 width,
330 height);
331 break;
332 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
333 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
334 case HAL_PIXEL_FORMAT_YCbCr_422_I:
335 case HAL_PIXEL_FORMAT_YCrCb_422_I:
336 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
337 if (width & 1) {
338 ALOGE("width is odd for the YUV422_SP format");
339 return 0;
340 }
341 size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
342 break;
343 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
344 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
345 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
346 break;
347 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
348 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
349 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
350 break;
351 case HAL_PIXEL_FORMAT_BLOB:
352 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
353 if (height != 1) {
354 ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
355 return 0;
356 }
357 size = (unsigned int) width;
358 break;
359 case HAL_PIXEL_FORMAT_NV21_ZSL:
360 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2,
361 SIZE_4K);
362 break;
Rajavenu Kyatham6e8c1822018-07-31 10:27:19 +0530363 case HAL_PIXEL_FORMAT_NV12_HEIF:
364 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_512, width, height);
365 break;
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400366 default:ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
367 return 0;
368 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700369 }
Naseer Ahmedda214ec2018-03-12 20:15:07 -0400370 auto align = GetDataAlignment(format, usage);
371 size = ALIGN(size, align) * info.layer_count;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700372 return size;
373}
374
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700375int GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
376 unsigned int *alignedh) {
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +0530377 GraphicsMetadata graphics_metadata = {};
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700378 return GetBufferSizeAndDimensions(info, size, alignedw, alignedh, &graphics_metadata);
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +0530379}
380
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700381int GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size, unsigned int *alignedw,
382 unsigned int *alignedh, GraphicsMetadata *graphics_metadata) {
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +0530383 int buffer_type = GetBufferType(info.format);
384 if (CanUseAdrenoForSize(buffer_type, info.usage)) {
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700385 return GetGpuResourceSizeAndDimensions(info, size, alignedw, alignedh, graphics_metadata);
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +0530386 } else {
387 GetAlignedWidthAndHeight(info, alignedw, alignedh);
388 *size = GetSize(info, *alignedw, *alignedh);
389 }
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -0700390 return 0;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700391}
392
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530393void GetYuvUbwcSPPlaneInfo(uint32_t width, uint32_t height, int color_format,
394 PlaneLayoutInfo *plane_info) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700395 // UBWC buffer has these 4 planes in the following sequence:
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530396 // Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700397 unsigned int y_meta_stride, y_meta_height, y_meta_size;
398 unsigned int y_stride, y_height, y_size;
399 unsigned int c_meta_stride, c_meta_height, c_meta_size;
400 unsigned int alignment = 4096;
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530401 unsigned int c_stride, c_height, c_size;
402 uint64_t yOffset, cOffset, yMetaOffset, cMetaOffset;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700403
404 y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
405 y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
406 y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
407
408 y_stride = VENUS_Y_STRIDE(color_format, INT(width));
409 y_height = VENUS_Y_SCANLINES(color_format, INT(height));
410 y_size = ALIGN((y_stride * y_height), alignment);
411
412 c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
413 c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
414 c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
415
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530416 c_stride = VENUS_UV_STRIDE(color_format, INT(width));
417 c_height = VENUS_UV_SCANLINES(color_format, INT(height));
418 c_size = ALIGN((c_stride * c_height), alignment);
419
420 yMetaOffset = 0;
421 yOffset = y_meta_size;
422 cMetaOffset = y_meta_size + y_size;
423 cOffset = y_meta_size + y_size + c_meta_size;
424
425 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
426 plane_info[0].offset = (uint32_t)yOffset;
427 plane_info[0].stride = static_cast<int32_t>(UINT(width));
428 plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
429 plane_info[0].scanlines = static_cast<int32_t>(y_height);
430 plane_info[0].size = static_cast<uint32_t>(y_size);
431
432 plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
433 plane_info[1].offset = (uint32_t)cOffset;
434 plane_info[1].stride = static_cast<int32_t>(UINT(width));
435 plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
436 plane_info[1].scanlines = static_cast<int32_t>(c_height);
437 plane_info[1].size = static_cast<uint32_t>(c_size);
438
439 plane_info[2].component = (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Y);
440 plane_info[2].offset = (uint32_t)yMetaOffset;
441 plane_info[2].stride = static_cast<int32_t>(UINT(width));
442 plane_info[2].stride_bytes = static_cast<int32_t>(y_meta_stride);
443 plane_info[2].scanlines = static_cast<int32_t>(y_meta_height);
444 plane_info[2].size = static_cast<uint32_t>(y_meta_size);
445
446 plane_info[3].component =
447 (PlaneComponent)(PLANE_COMPONENT_META | PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
448 plane_info[3].offset = (uint32_t)cMetaOffset;
449 plane_info[3].stride = static_cast<int32_t>(UINT(width));
450 plane_info[3].stride_bytes = static_cast<int32_t>(c_meta_stride);
451 plane_info[3].scanlines = static_cast<int32_t>(c_meta_height);
452 plane_info[3].size = static_cast<uint32_t>(c_meta_size);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700453}
454
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530455// This API gets information about 8 planes (Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane,
456// Y_Plane, UV_Plane, Y_Meta_Plane, UV_Meta_Plane) and it stores the
457// information in PlaneLayoutInfo array.
458void GetYuvUbwcInterlacedSPPlaneInfo(uint32_t width, uint32_t height,
459 PlaneLayoutInfo plane_info[8]) {
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700460 // UBWC interlaced has top-bottom field layout with each field as
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530461 // 8-plane (including meta plane also) NV12_UBWC with width = image_width
462 // & height = image_height / 2.
463 // Client passed plane_info argument is ptr to struct PlaneLayoutInfo[8].
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700464 // Plane info to be filled for each field separately.
465 height = (height + 1) >> 1;
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700466
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530467 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, &plane_info[0]);
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700468
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530469 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, &plane_info[4]);
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700470}
471
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530472// This API gets information about 2 planes (Y_Plane & UV_Plane)
473void GetYuvSPPlaneInfo(const BufferInfo &info, int format, uint32_t width, uint32_t height,
474 uint32_t bpp, PlaneLayoutInfo *plane_info) {
475 int unaligned_width = info.width;
476 int unaligned_height = info.height;
477 unsigned int y_stride = 0, y_height = 0, y_size = 0;
478 unsigned int c_stride = 0, c_height = 0, c_size = 0;
479 uint64_t yOffset, cOffset;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700480
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530481 y_stride = c_stride = UINT(width) * bpp;
482 y_height = INT(height);
483 y_size = y_stride * y_height;
484 switch (format) {
485 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
486 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
487 c_size = (width * height) / 2 + 1;
488 c_height = height >> 1;
489 break;
490 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
491 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
492 if (unaligned_width & 1) {
493 ALOGE("width is odd for the YUV422_SP format");
494 return;
495 }
496 c_size = width * height;
497 c_height = height;
498 break;
499 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
500 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
501 c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height);
502 c_size = c_stride * c_height;
503 break;
504 case HAL_PIXEL_FORMAT_NV12_HEIF:
505 c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12_512, height);
506 c_size = c_stride * c_height;
507 break;
508 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
509 y_size = ALIGN(width * height, 4096);
510 c_size = ALIGN(2 * ALIGN(unaligned_width / 2, 32) * ALIGN(unaligned_height / 2, 32), 4096);
511 break;
512 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
Ramakant Singh13596ae2020-01-06 20:12:34 +0530513 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530514 c_height = VENUS_UV_SCANLINES(COLOR_FMT_NV21, height);
515 c_size = c_stride * c_height;
516 break;
517 case HAL_PIXEL_FORMAT_NV21_ZSL:
518 c_size = (width * height) / 2;
519 c_height = height >> 1;
520 break;
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530521 case HAL_PIXEL_FORMAT_Y16:
522 c_size = width * height;
523 c_height = height;
524 break;
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530525 case HAL_PIXEL_FORMAT_Y8:
526 c_size = 0;
527 break;
528 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
529 c_size = (width * height) + 1;
530 c_height = height;
531 break;
532 default:
533 break;
534 }
535
536 yOffset = 0;
537 cOffset = y_size;
538
539 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
540 plane_info[0].offset = (uint32_t)yOffset;
541 plane_info[0].step = 1;
542 plane_info[0].stride = static_cast<int32_t>(UINT(width));
543 plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
544 plane_info[0].scanlines = static_cast<int32_t>(y_height);
545 plane_info[0].size = static_cast<uint32_t>(y_size);
546
547 plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
548 plane_info[1].offset = (uint32_t)cOffset;
549 plane_info[1].step = 2 * bpp;
550 plane_info[1].stride = static_cast<int32_t>(UINT(width));
551 plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
552 plane_info[1].scanlines = static_cast<int32_t>(c_height);
553 plane_info[1].size = static_cast<uint32_t>(c_size);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700554}
555
Naseer Ahmed7aff2612017-10-05 20:39:05 -0400556int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr ycbcr[2]) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700557 int err = 0;
558 uint32_t width = UINT(hnd->width);
559 uint32_t height = UINT(hnd->height);
560 int format = hnd->format;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500561 uint64_t usage = hnd->usage;
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530562 int32_t interlaced = 0;
563 int plane_count = 0;
564 int unaligned_width = INT(hnd->unaligned_width);
565 int unaligned_height = INT(hnd->unaligned_height);
566 BufferInfo info(unaligned_width, unaligned_height, format, usage);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700567
568 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700569
570 // Check if UBWC buffer has been rendered in linear format.
Ramakant Singhc7d07792017-07-26 15:36:33 +0530571 int linear_format = 0;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500572 if (getMetaData(const_cast<private_handle_t *>(hnd), GET_LINEAR_FORMAT, &linear_format) == 0) {
573 format = INT(linear_format);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700574 }
575
576 // Check metadata if the geometry has been updated.
Ramakant Singhc7d07792017-07-26 15:36:33 +0530577 BufferDim_t buffer_dim;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500578 if (getMetaData(const_cast<private_handle_t *>(hnd), GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
579 BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format, usage);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700580 GetAlignedWidthAndHeight(info, &width, &height);
581 }
582
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700583 // Check metadata for interlaced content.
Ramakant Singhc7d07792017-07-26 15:36:33 +0530584 int interlace_flag = 0;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500585 if (getMetaData(const_cast<private_handle_t *>(hnd), GET_PP_PARAM_INTERLACED, &interlace_flag) ==
586 0) {
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530587 if (interlace_flag) {
588 interlaced = LAYOUT_INTERLACED_FLAG;
589 }
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700590 }
591
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530592 PlaneLayoutInfo plane_info[8] = {};
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700593 // Get the chroma offsets from the handle width/height. We take advantage
594 // of the fact the width _is_ the stride
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530595 err = GetYUVPlaneInfo(info, format, width, height, interlaced, &plane_count, plane_info);
596 if (err == 0) {
597 if (interlaced && format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC) {
598 CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, &plane_info[0], &ycbcr[0]);
599 unsigned int uv_stride, uv_height, uv_size;
600 unsigned int alignment = 4096;
601 uint64_t field_base;
602 height = (height + 1) >> 1;
603 uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12_UBWC, INT(width));
604 uv_height = VENUS_UV_SCANLINES(COLOR_FMT_NV12_UBWC, INT(height));
605 uv_size = ALIGN((uv_stride * uv_height), alignment);
606 field_base = hnd->base + plane_info[1].offset + uv_size;
607 memset(ycbcr[1].reserved, 0, sizeof(ycbcr[1].reserved));
608 CopyPlaneLayoutInfotoAndroidYcbcr(field_base, plane_count, &plane_info[4], &ycbcr[1]);
609 } else {
610 CopyPlaneLayoutInfotoAndroidYcbcr(hnd->base, plane_count, plane_info, ycbcr);
611 switch (format) {
612 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
613 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
614 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
615 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
616 case HAL_PIXEL_FORMAT_NV21_ZSL:
617 case HAL_PIXEL_FORMAT_RAW16:
618 case HAL_PIXEL_FORMAT_Y16:
619 case HAL_PIXEL_FORMAT_RAW10:
620 case HAL_PIXEL_FORMAT_RAW8:
621 case HAL_PIXEL_FORMAT_Y8:
622 std::swap(ycbcr->cb, ycbcr->cr);
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700623 }
Ashish Kumarb9392ff2019-03-27 18:30:39 +0530624 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700625 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700626 return err;
627}
628
Yichi Chen24d146c2020-05-27 20:16:13 +0800629int GetRawPlaneInfo(int32_t format, int32_t width, int32_t height, PlaneLayoutInfo *plane_info) {
630 int32_t step = 0;
631
632 switch (format) {
633 case HAL_PIXEL_FORMAT_RAW16:
634 step = 2;
635 break;
636 case HAL_PIXEL_FORMAT_RAW8:
637 step = 1;
638 break;
639 case HAL_PIXEL_FORMAT_RAW12:
640 case HAL_PIXEL_FORMAT_RAW10:
641 step = 0;
642 break;
643 default:
644 ALOGW("RawPlaneInfo is unsupported for format 0x%x", format);
645 return -EINVAL;
646 }
647
648 BufferInfo info(width, height, format);
649 uint32_t alignedWidth, alignedHeight;
650 GetAlignedWidthAndHeight(info, &alignedWidth, &alignedHeight);
651
652 uint32_t size = GetSize(info, alignedWidth, alignedHeight);
653
654 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_RAW;
655 plane_info[0].h_subsampling = 0;
656 plane_info[0].v_subsampling = 0;
657 plane_info[0].offset = 0;
658 plane_info[0].step = step;
659 plane_info[0].stride = width;
660 plane_info[0].stride_bytes = static_cast<int32_t>(alignedWidth);
Ramakant Singh7540b712020-07-28 00:19:35 +0530661 if (format == HAL_PIXEL_FORMAT_RAW16) {
662 plane_info[0].stride_bytes = static_cast<int32_t>(alignedWidth * GetBpp(format));
663 }
Yichi Chen24d146c2020-05-27 20:16:13 +0800664 plane_info[0].scanlines = height;
665 plane_info[0].size = size;
666
667 return 0;
668}
669
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700670// Explicitly defined UBWC formats
671bool IsUBwcFormat(int format) {
672 switch (format) {
673 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
674 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
675 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
676 return true;
677 default:
678 return false;
679 }
680}
681
682bool IsUBwcSupported(int format) {
683 // Existing HAL formats with UBWC support
684 switch (format) {
685 case HAL_PIXEL_FORMAT_BGR_565:
686 case HAL_PIXEL_FORMAT_RGBA_8888:
687 case HAL_PIXEL_FORMAT_RGBX_8888:
688 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
689 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
690 case HAL_PIXEL_FORMAT_RGBA_1010102:
691 case HAL_PIXEL_FORMAT_RGBX_1010102:
Saurabh Dubey11df8e12018-07-25 19:16:25 +0530692 case HAL_PIXEL_FORMAT_DEPTH_16:
693 case HAL_PIXEL_FORMAT_DEPTH_24:
694 case HAL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
695 case HAL_PIXEL_FORMAT_DEPTH_32F:
696 case HAL_PIXEL_FORMAT_STENCIL_8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700697 return true;
698 default:
699 break;
700 }
701
702 return false;
703}
704
Saurabh Dubey48b757d2018-05-24 19:13:53 +0530705bool IsUBwcPISupported(int format, uint64_t usage) {
706 if (usage & BufferUsage::COMPOSER_OVERLAY || !(usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI)) {
707 return false;
708 }
709
710 // As of now only two formats
711 switch (format) {
712 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
713 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: {
714 if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
715 if (AdrenoMemInfo::GetInstance()) {
716 return AdrenoMemInfo::GetInstance()->IsPISupportedByGPU(format, usage);
717 }
718 } else {
719 return true;
720 }
721 }
722 }
723
724 return false;
725}
726
Naseer Ahmede36f2242017-12-01 15:33:56 -0500727bool IsUBwcEnabled(int format, uint64_t usage) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700728 // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
729 if (IsUBwcFormat(format)) {
730 return true;
731 }
732
733 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
734 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
735 // usage flag and MDP supports the format.
Naseer Ahmed2023cf32019-01-28 19:02:40 -0500736 if (((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) ||
737 (usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI) ||
738 (usage & BufferUsage::COMPOSER_CLIENT_TARGET))
Saurabh Dubey48b757d2018-05-24 19:13:53 +0530739 && IsUBwcSupported(format)) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700740 bool enable = true;
741 // Query GPU for UBWC only if buffer is intended to be used by GPU.
Naseer Ahmede36f2242017-12-01 15:33:56 -0500742 if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530743 if (AdrenoMemInfo::GetInstance()) {
744 enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
745 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700746 }
747
748 // Allow UBWC, only if CPU usage flags are not set
Naseer Ahmede36f2242017-12-01 15:33:56 -0500749 if (enable && !(CpuCanAccess(usage))) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700750 return true;
751 }
752 }
753
754 return false;
755}
756
757void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
758 unsigned int *aligned_h) {
759 switch (format) {
760 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
761 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
Priyanka Gujjula5eb8c8b2020-07-16 00:51:40 +0530762 *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
763 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
764 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700765 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
766 *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
767 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
768 break;
769 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
770 // The macro returns the stride which is 4/3 times the width, hence * 3/4
771 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
772 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
773 break;
774 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
775 // The macro returns the stride which is 2 times the width, hence / 2
776 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
777 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
778 break;
779 default:
780 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
781 *aligned_w = 0;
782 *aligned_h = 0;
783 break;
784 }
785}
786
787void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
788 *block_width = 0;
789 *block_height = 0;
790
791 switch (bpp) {
792 case 2:
793 case 4:
794 *block_width = 16;
795 *block_height = 4;
796 break;
797 case 8:
798 *block_width = 8;
799 *block_height = 4;
800 break;
801 case 16:
802 *block_width = 4;
803 *block_height = 4;
804 break;
805 default:
806 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
807 break;
808 }
809}
810
811unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
812 unsigned int size = 0;
813 int meta_width, meta_height;
814 int block_width, block_height;
815
816 GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
817 if (!block_width || !block_height) {
818 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
819 return size;
820 }
821
822 // Align meta buffer height to 16 blocks
823 meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
824
825 // Align meta buffer width to 64 blocks
826 meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
827
828 // Align meta buffer size to 4K
829 size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
830
831 return size;
832}
833
834unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
835 unsigned int alignedh) {
836 unsigned int size = 0;
837 uint32_t bpp = 0;
838 switch (format) {
839 case HAL_PIXEL_FORMAT_BGR_565:
840 case HAL_PIXEL_FORMAT_RGBA_8888:
841 case HAL_PIXEL_FORMAT_RGBX_8888:
842 case HAL_PIXEL_FORMAT_RGBA_1010102:
843 case HAL_PIXEL_FORMAT_RGBX_1010102:
844 bpp = GetBppForUncompressedRGB(format);
845 size = alignedw * alignedh * bpp;
846 size += GetRgbUBwcMetaBufferSize(width, height, bpp);
847 break;
Priyanka Gujjula5eb8c8b2020-07-16 00:51:40 +0530848 /*
849 * 1. The CtsMediaV2TestCases#CodecEncoderSurfaceTest is a transcode use case and shares
850 * same surface between encoder and decoder.
851 * 2. Configures encoder with Opaque color format thus encoder sets ubwc usage bits and
852 * is configured with NV12_UBWC format.
853 * 3. Configures decoder as 'flexible', thus configuring decoder with NV12 format.
854 * 4. Decoder should produce output to surface that will be fed back to encoder as input.
855 * 5. Though UBWC is enabled, we need to compute the actual buffer size (including aligned
856 * width and height) based on pixel format that is set.
857 */
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700858 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
859 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
Priyanka Gujjula5eb8c8b2020-07-16 00:51:40 +0530860 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
861 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700862 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
863 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
864 break;
865 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
866 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
867 break;
868 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
869 size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
870 break;
871 default:
872 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
873 break;
874 }
875
876 return size;
877}
878
Ashish Kumar8a1b56e2019-11-15 18:15:22 +0530879unsigned int GetRgbMetaSize(int format, uint32_t width, uint32_t height, uint64_t usage) {
880 unsigned int meta_size = 0;
881 if (!IsUBwcEnabled(format, usage)) {
882 return meta_size;
883 }
884 uint32_t bpp = GetBppForUncompressedRGB(format);
885 switch (format) {
886 case HAL_PIXEL_FORMAT_BGR_565:
887 case HAL_PIXEL_FORMAT_RGBA_8888:
888 case HAL_PIXEL_FORMAT_RGBX_8888:
889 case HAL_PIXEL_FORMAT_RGBA_1010102:
890 case HAL_PIXEL_FORMAT_RGBX_1010102:
891 case HAL_PIXEL_FORMAT_RGBA_FP16:
892 meta_size = GetRgbUBwcMetaBufferSize(width, height, bpp);
893 break;
894 default:
895 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, format);
896 break;
897 }
898 return meta_size;
899}
900
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700901int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
902 int err = 0;
903
904 // This api is for RGB* formats
Naseer Ahmede36f2242017-12-01 15:33:56 -0500905 if (!IsUncompressedRGBFormat(hnd->format)) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700906 return -EINVAL;
907 }
908
909 // linear buffer, nothing to do further
910 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
911 *rgb_data = reinterpret_cast<void *>(hnd->base);
912 return err;
913 }
Ashish Kumar8a1b56e2019-11-15 18:15:22 +0530914 unsigned int meta_size = GetRgbMetaSize(hnd->format, hnd->width, hnd->height, hnd->usage);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700915
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700916 *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
917
918 return err;
919}
920
Naseer Ahmede36f2242017-12-01 15:33:56 -0500921void GetCustomDimensions(private_handle_t *hnd, int *stride, int *height) {
922 BufferDim_t buffer_dim;
923 int interlaced = 0;
924
925 *stride = hnd->width;
926 *height = hnd->height;
927 if (getMetaData(hnd, GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
928 *stride = buffer_dim.sliceWidth;
929 *height = buffer_dim.sliceHeight;
930 } else if (getMetaData(hnd, GET_PP_PARAM_INTERLACED, &interlaced) == 0) {
931 if (interlaced && IsUBwcFormat(hnd->format)) {
932 unsigned int alignedw = 0, alignedh = 0;
933 // Get re-aligned height for single ubwc interlaced field and
934 // multiply by 2 to get frame height.
935 BufferInfo info(hnd->width, ((hnd->height + 1) >> 1), hnd->format);
936 GetAlignedWidthAndHeight(info, &alignedw, &alignedh);
937 *stride = static_cast<int>(alignedw);
938 *height = static_cast<int>(alignedh * 2);
939 }
940 }
941}
942
943void GetColorSpaceFromMetadata(private_handle_t *hnd, int *color_space) {
944 ColorMetaData color_metadata;
945 if (getMetaData(hnd, GET_COLOR_METADATA, &color_metadata) == 0) {
946 switch (color_metadata.colorPrimaries) {
947 case ColorPrimaries_BT709_5:
948 *color_space = HAL_CSC_ITU_R_709;
949 break;
950 case ColorPrimaries_BT601_6_525:
951 case ColorPrimaries_BT601_6_625:
952 *color_space = ((color_metadata.range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
953 break;
954 case ColorPrimaries_BT2020:
955 *color_space = (color_metadata.range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
956 break;
957 default:
958 ALOGE("Unknown Color Space = %d", color_metadata.colorPrimaries);
959 break;
960 }
961 } else if (getMetaData(hnd, GET_COLOR_SPACE, color_space) != 0) {
962 *color_space = 0;
963 }
964}
965
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700966void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
967 unsigned int *alignedh) {
968 int width = info.width;
969 int height = info.height;
970 int format = info.format;
Naseer Ahmede36f2242017-12-01 15:33:56 -0500971 uint64_t usage = info.usage;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700972
973 // Currently surface padding is only computed for RGB* surfaces.
Naseer Ahmede36f2242017-12-01 15:33:56 -0500974 bool ubwc_enabled = IsUBwcEnabled(format, usage);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700975 int tile = ubwc_enabled;
976
977 if (IsUncompressedRGBFormat(format)) {
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530978 if (AdrenoMemInfo::GetInstance()) {
979 AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
980 alignedh);
981 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700982 return;
983 }
984
985 if (ubwc_enabled) {
986 GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
987 return;
988 }
989
990 if (IsCompressedRGBFormat(format)) {
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530991 if (AdrenoMemInfo::GetInstance()) {
992 AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
993 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700994 return;
995 }
996
997 int aligned_w = width;
998 int aligned_h = height;
999 unsigned int alignment = 32;
1000
1001 // Below should be only YUV family
1002 switch (format) {
1003 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1004 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +05301005 if (AdrenoMemInfo::GetInstance() == nullptr) {
1006 return;
1007 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001008 alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
1009 aligned_w = ALIGN(width, alignment);
1010 break;
1011 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1012 aligned_w = ALIGN(width, alignment);
1013 break;
1014 case HAL_PIXEL_FORMAT_RAW16:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +05301015 case HAL_PIXEL_FORMAT_Y16:
1016 case HAL_PIXEL_FORMAT_Y8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001017 aligned_w = ALIGN(width, 16);
1018 break;
1019 case HAL_PIXEL_FORMAT_RAW12:
Naseer Ahmed1187a572017-08-14 13:16:55 -04001020 aligned_w = ALIGN(width * 12 / 8, 16);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001021 break;
1022 case HAL_PIXEL_FORMAT_RAW10:
Naseer Ahmed1187a572017-08-14 13:16:55 -04001023 aligned_w = ALIGN(width * 10 / 8, 16);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001024 break;
1025 case HAL_PIXEL_FORMAT_RAW8:
Naseer Ahmed1187a572017-08-14 13:16:55 -04001026 aligned_w = ALIGN(width, 16);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001027 break;
1028 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
1029 aligned_w = ALIGN(width, 128);
1030 break;
1031 case HAL_PIXEL_FORMAT_YV12:
Venkat Thogaru63b01d02020-06-12 14:28:01 +05301032 if ((usage & BufferUsage::GPU_TEXTURE) || (usage & BufferUsage::GPU_RENDER_TARGET)) {
1033 if (AdrenoMemInfo::GetInstance() == nullptr) {
1034 return;
1035 }
1036 alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
1037 aligned_w = ALIGN(width, alignment);
1038 } else {
1039 aligned_w = ALIGN(width, 16);
1040 }
1041 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001042 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1043 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1044 case HAL_PIXEL_FORMAT_YCbCr_422_I:
1045 case HAL_PIXEL_FORMAT_YCrCb_422_I:
1046 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1047 aligned_w = ALIGN(width, 16);
1048 break;
Mathew Joseph Karimpanala73082e2017-10-16 18:01:21 +05301049 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1050 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_P010, width) / 2);
1051 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_P010, height));
1052 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001053 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1054 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1055 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
1056 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
1057 break;
1058 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
Ramakant Singh13596ae2020-01-06 20:12:34 +05301059 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001060 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
1061 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
1062 break;
1063 case HAL_PIXEL_FORMAT_BLOB:
1064 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1065 break;
1066 case HAL_PIXEL_FORMAT_NV21_ZSL:
1067 aligned_w = ALIGN(width, 64);
1068 aligned_h = ALIGN(height, 64);
1069 break;
Rajavenu Kyatham6e8c1822018-07-31 10:27:19 +05301070 case HAL_PIXEL_FORMAT_NV12_HEIF:
1071 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12_512, width));
1072 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12_512, height));
1073 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001074 default:
1075 break;
1076 }
1077
1078 *alignedw = (unsigned int)aligned_w;
1079 *alignedh = (unsigned int)aligned_h;
1080}
1081
Naseer Ahmede36f2242017-12-01 15:33:56 -05001082int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], uint32_t offset[4],
1083 uint32_t *num_planes) {
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001084 if (!hnd || !stride || !offset || !num_planes) {
1085 return -EINVAL;
1086 }
1087
Naseer Ahmed7aff2612017-10-05 20:39:05 -04001088 struct android_ycbcr yuvPlaneInfo[2] = {};
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001089 *num_planes = 1;
1090 stride[0] = 0;
1091
1092 switch (hnd->format) {
1093 case HAL_PIXEL_FORMAT_RGB_565:
1094 case HAL_PIXEL_FORMAT_BGR_565:
1095 case HAL_PIXEL_FORMAT_RGBA_5551:
1096 case HAL_PIXEL_FORMAT_RGBA_4444:
1097 stride[0] = static_cast<uint32_t>(hnd->width * 2);
1098 break;
1099 case HAL_PIXEL_FORMAT_RGB_888:
1100 stride[0] = static_cast<uint32_t>(hnd->width * 3);
1101 break;
1102 case HAL_PIXEL_FORMAT_RGBA_8888:
1103 case HAL_PIXEL_FORMAT_BGRA_8888:
1104 case HAL_PIXEL_FORMAT_RGBX_8888:
1105 case HAL_PIXEL_FORMAT_BGRX_8888:
1106 case HAL_PIXEL_FORMAT_RGBA_1010102:
1107 case HAL_PIXEL_FORMAT_ARGB_2101010:
1108 case HAL_PIXEL_FORMAT_RGBX_1010102:
1109 case HAL_PIXEL_FORMAT_XRGB_2101010:
1110 case HAL_PIXEL_FORMAT_BGRA_1010102:
1111 case HAL_PIXEL_FORMAT_ABGR_2101010:
1112 case HAL_PIXEL_FORMAT_BGRX_1010102:
1113 case HAL_PIXEL_FORMAT_XBGR_2101010:
1114 stride[0] = static_cast<uint32_t>(hnd->width * 4);
1115 break;
1116 }
1117
1118 // Format is RGB
1119 if (stride[0]) {
1120 return 0;
1121 }
1122
1123 (*num_planes)++;
Naseer Ahmed7aff2612017-10-05 20:39:05 -04001124 int ret = GetYUVPlaneInfo(hnd, yuvPlaneInfo);
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001125 if (ret < 0) {
1126 ALOGE("%s failed", __FUNCTION__);
1127 return ret;
1128 }
1129
Naseer Ahmed7aff2612017-10-05 20:39:05 -04001130 // We are only returning buffer layout for progressive or single field formats.
1131 struct android_ycbcr yuvInfo = yuvPlaneInfo[0];
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001132 stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
1133 offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
1134 stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
1135 switch (hnd->format) {
1136 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1137 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1138 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1139 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1140 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1141 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1142 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1143 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
Mathew Joseph Karimpanala73082e2017-10-16 18:01:21 +05301144 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
Rajavenu Kyatham6e8c1822018-07-31 10:27:19 +05301145 case HAL_PIXEL_FORMAT_NV12_HEIF:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001146 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
1147 break;
1148 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1149 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1150 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
Ramakant Singh13596ae2020-01-06 20:12:34 +05301151 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001152 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
1153 break;
1154 case HAL_PIXEL_FORMAT_YV12:
1155 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
1156 stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
1157 offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
1158 (*num_planes)++;
1159 break;
Camus Wonga300db62018-09-27 16:38:50 -04001160 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1161 *num_planes = 1;
1162 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -07001163 default:
1164 ALOGW("%s: Unsupported format", __FUNCTION__);
1165 ret = -EINVAL;
1166 }
1167
1168 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
1169 std::fill(offset, offset + 4, 0);
1170 }
1171
1172 return 0;
1173}
1174
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -07001175int GetGpuResourceSizeAndDimensions(const BufferInfo &info, unsigned int *size,
1176 unsigned int *alignedw, unsigned int *alignedh,
1177 GraphicsMetadata *graphics_metadata) {
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301178 GetAlignedWidthAndHeight(info, alignedw, alignedh);
1179 AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
1180 graphics_metadata->size = adreno_mem_info->AdrenoGetMetadataBlobSize();
1181 uint64_t adreno_usage = info.usage;
1182 // If gralloc disables UBWC based on any of the checks,
1183 // we pass modified usage flag to adreno to convey this.
1184 int is_ubwc_enabled = IsUBwcEnabled(info.format, info.usage);
1185 if (!is_ubwc_enabled) {
1186 adreno_usage &= ~(GRALLOC_USAGE_PRIVATE_ALLOC_UBWC);
Naseer Ahmed2023cf32019-01-28 19:02:40 -05001187 } else {
1188 adreno_usage |= GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301189 }
1190
1191 // Call adreno api for populating metadata blob
Saurabh Dubeyb637bb32018-05-15 16:20:10 +05301192 // Layer count is for 2D/Cubemap arrays and depth is used for 3D slice
1193 // Using depth to pass layer_count here
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301194 int ret = adreno_mem_info->AdrenoInitMemoryLayout(graphics_metadata->data, info.width,
Saurabh Dubeyb637bb32018-05-15 16:20:10 +05301195 info.height, info.layer_count, /* depth */
1196 info.format, 1, is_ubwc_enabled,
1197 adreno_usage, 1);
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301198 if (ret != 0) {
1199 ALOGE("%s Graphics metadata init failed", __FUNCTION__);
1200 *size = 0;
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -07001201 return -EINVAL;
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301202 }
1203 // Call adreno api with the metadata blob to get buffer size
1204 *size = adreno_mem_info->AdrenoGetAlignedGpuBufferSize(graphics_metadata->data);
Ramkumar Radhakrishnan30ea0f02018-10-11 19:25:10 -07001205 return 0;
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301206}
1207
Saurabh Dubey52eb7a62018-06-15 16:31:23 +05301208bool CanUseAdrenoForSize(int buffer_type, uint64_t usage) {
1209 if (buffer_type == BUFFER_TYPE_VIDEO || !GetAdrenoSizeAPIStatus()) {
1210 return false;
1211 }
1212
1213 if ((usage & BufferUsage::PROTECTED) && ((usage & BufferUsage::CAMERA_OUTPUT) ||
1214 (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY))) {
1215 return false;
1216 }
1217
1218 return true;
1219}
1220
Saurabh Dubeyb28b82b2018-05-29 09:46:41 +05301221bool GetAdrenoSizeAPIStatus() {
1222 AdrenoMemInfo* adreno_mem_info = AdrenoMemInfo::GetInstance();
1223 if (adreno_mem_info) {
1224 return adreno_mem_info->AdrenoSizeAPIAvaliable();
1225 }
1226 return false;
1227}
1228
Saurabh Dubey48b757d2018-05-24 19:13:53 +05301229bool UseUncached(int format, uint64_t usage) {
1230 if ((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) || (usage & BufferUsage::PROTECTED)) {
1231 return true;
1232 }
1233
1234 // CPU read rarely
1235 if ((usage & BufferUsage::CPU_READ_MASK) == static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY)) {
1236 return true;
1237 }
1238
1239 // CPU write rarely
1240 if ((usage & BufferUsage::CPU_WRITE_MASK) ==
1241 static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY)) {
1242 return true;
1243 }
1244
1245 if ((usage & BufferUsage::SENSOR_DIRECT_DATA) || (usage & BufferUsage::GPU_DATA_BUFFER)) {
1246 return true;
1247 }
1248
1249 if (format && IsUBwcEnabled(format, usage)) {
1250 return true;
1251 }
1252
1253 return false;
1254}
1255
1256uint64_t GetHandleFlags(int format, uint64_t usage) {
1257 uint64_t priv_flags = 0;
1258
1259 if (usage & BufferUsage::VIDEO_ENCODER) {
1260 priv_flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
1261 }
1262
1263 if (usage & BufferUsage::CAMERA_OUTPUT) {
1264 priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
1265 }
1266
1267 if (usage & BufferUsage::CAMERA_INPUT) {
1268 priv_flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
1269 }
1270
1271 if (usage & BufferUsage::COMPOSER_OVERLAY) {
1272 priv_flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
1273 }
1274
1275 if (usage & BufferUsage::GPU_TEXTURE) {
1276 priv_flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
1277 }
1278
1279 if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
1280 priv_flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
1281 }
1282
1283 if (IsUBwcEnabled(format, usage)) {
1284 if (IsUBwcPISupported(format, usage)) {
1285 priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI;
1286 } else {
1287 priv_flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
1288 }
1289 }
1290
1291 if (usage & (BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK)) {
1292 priv_flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
1293 }
1294
1295 if ((usage & (BufferUsage::VIDEO_ENCODER | BufferUsage::VIDEO_DECODER |
1296 BufferUsage::CAMERA_OUTPUT | BufferUsage::GPU_RENDER_TARGET))) {
1297 priv_flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
1298 }
1299
1300 if (!UseUncached(format, usage)) {
1301 priv_flags |= private_handle_t::PRIV_FLAGS_CACHED;
1302 }
1303
1304 return priv_flags;
1305}
1306
1307int GetImplDefinedFormat(uint64_t usage, int format) {
1308 int gr_format = format;
1309
1310 // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
1311 // the usage bits, gralloc assigns a format.
1312 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
1313 format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
Mathew Joseph Karimpanal71517182018-08-14 16:40:34 +05301314 if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC || usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC_PI)
1315 && format != HAL_PIXEL_FORMAT_YCbCr_420_888) {
Saurabh Dubey81aef932018-06-27 09:41:31 +05301316 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
Saurabh Dubey48b757d2018-05-24 19:13:53 +05301317 } else if (usage & BufferUsage::VIDEO_ENCODER) {
1318 if (usage & GRALLOC_USAGE_PRIVATE_VIDEO_NV21_ENCODER) {
1319 gr_format = HAL_PIXEL_FORMAT_NV21_ENCODEABLE; // NV21
Manikanta Kanamarlapudidfa32e82019-03-26 14:06:47 +05301320 } else if (usage & GRALLOC_USAGE_PRIVATE_HEIF) {
1321 gr_format = HAL_PIXEL_FORMAT_NV12_HEIF;
Mathew Joseph Karimpanal71517182018-08-14 16:40:34 +05301322 } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1323 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;
Saurabh Dubey48b757d2018-05-24 19:13:53 +05301324 } else {
1325 gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; // NV12
1326 }
1327 } else if (usage & BufferUsage::CAMERA_INPUT) {
1328 if (usage & BufferUsage::CAMERA_OUTPUT) {
1329 // Assumed ZSL if both producer and consumer camera flags set
1330 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
1331 } else {
1332 gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; // NV21
1333 }
1334 } else if (usage & BufferUsage::CAMERA_OUTPUT) {
1335 if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1336 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21
1337 } else {
1338 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; // NV12 preview
1339 }
1340 } else if (usage & BufferUsage::COMPOSER_OVERLAY) {
1341 // XXX: If we still haven't set a format, default to RGBA8888
1342 gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
1343 } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
1344 // If no other usage flags are detected, default the
1345 // flexible YUV format to NV21_ZSL
1346 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
1347 }
1348 }
1349
1350 return gr_format;
1351}
1352
1353int GetCustomFormatFlags(int format, uint64_t usage,
1354 int *custom_format, uint64_t *priv_flags) {
1355 *custom_format = GetImplDefinedFormat(usage, format);
1356 *priv_flags = GetHandleFlags(*custom_format, usage);
1357
Saurabh Dubey81aef932018-06-27 09:41:31 +05301358 if (usage & GRALLOC_USAGE_PROTECTED) {
1359 *priv_flags |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
1360 }
1361
1362 *priv_flags |= private_handle_t::PRIV_FLAGS_USES_ION;
1363
Saurabh Dubey48b757d2018-05-24 19:13:53 +05301364 return 0;
1365}
1366
Saurabh Dubeyefd7f9e2018-06-15 18:00:02 +05301367int GetBufferType(int inputFormat) {
1368 return IsYuvFormat(inputFormat) ? BUFFER_TYPE_VIDEO : BUFFER_TYPE_UI;
1369}
1370
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301371int GetYUVPlaneInfo(const BufferInfo &info, int32_t format, int32_t width, int32_t height,
1372 int32_t flags, int *plane_count, PlaneLayoutInfo *plane_info) {
1373 int err = 0;
1374 unsigned int y_stride, c_stride, y_height, c_height, y_size, c_size;
1375 uint64_t yOffset, cOffset, crOffset, cbOffset;
1376 int h_subsampling = 0, v_subsampling = 0;
1377 switch (format) {
1378 // Semiplanar
1379 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1380 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1381 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1382 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
Ramakant Singh13596ae2020-01-06 20:12:34 +05301383 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301384 case HAL_PIXEL_FORMAT_NV12_HEIF: // Same as YCbCr_420_SP_VENUS
1385 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1386 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1387 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1388 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1389 case HAL_PIXEL_FORMAT_NV21_ZSL:
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301390 case HAL_PIXEL_FORMAT_Y16:
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301391 case HAL_PIXEL_FORMAT_Y8:
1392 *plane_count = 2;
1393 GetYuvSPPlaneInfo(info, format, width, height, 1, plane_info);
1394 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1395 plane_info[0].h_subsampling = 0;
1396 plane_info[0].v_subsampling = 0;
1397 plane_info[1].h_subsampling = h_subsampling;
1398 plane_info[1].v_subsampling = v_subsampling;
1399 break;
1400
Yichi Chen24d146c2020-05-27 20:16:13 +08001401 case HAL_PIXEL_FORMAT_RAW10:
1402 case HAL_PIXEL_FORMAT_RAW8:
1403 case HAL_PIXEL_FORMAT_RAW16:
1404 case HAL_PIXEL_FORMAT_RAW12:
1405 *plane_count = 1;
1406 GetRawPlaneInfo(format, info.width, info.height, plane_info);
1407 break;
1408
1409
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301410 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1411 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1412 if (flags & LAYOUT_INTERLACED_FLAG) {
1413 *plane_count = 8;
1414 GetYuvUbwcInterlacedSPPlaneInfo(width, height, plane_info);
1415 plane_info[0].step = plane_info[4].step = 1;
1416 plane_info[1].step = plane_info[5].step = 2;
1417 plane_info[0].h_subsampling = plane_info[4].h_subsampling = 0;
1418 plane_info[0].v_subsampling = plane_info[4].v_subsampling = 0;
1419 plane_info[1].h_subsampling = plane_info[5].h_subsampling = h_subsampling;
1420 plane_info[1].v_subsampling = plane_info[5].v_subsampling = v_subsampling;
1421 plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1422 plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1423 plane_info[2].step = plane_info[3].step = 0;
1424 plane_info[6].h_subsampling = plane_info[7].h_subsampling = 0;
1425 plane_info[6].v_subsampling = plane_info[7].v_subsampling = 0;
1426 plane_info[6].step = plane_info[7].step = 0;
1427 } else {
1428 *plane_count = 4;
1429 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_UBWC, plane_info);
1430 plane_info[0].h_subsampling = 0;
1431 plane_info[0].v_subsampling = 0;
1432 plane_info[0].step = 1;
1433 plane_info[1].h_subsampling = h_subsampling;
1434 plane_info[1].v_subsampling = v_subsampling;
1435 plane_info[1].step = 2;
1436 plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1437 plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1438 plane_info[2].step = plane_info[3].step = 0;
1439 }
1440 break;
1441
1442 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1443 *plane_count = 2;
1444 GetYuvSPPlaneInfo(info, format, width, height, 2, plane_info);
1445 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1446 plane_info[0].h_subsampling = 0;
1447 plane_info[0].v_subsampling = 0;
1448 plane_info[1].h_subsampling = h_subsampling;
1449 plane_info[1].v_subsampling = v_subsampling;
1450 break;
1451
1452 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1453 *plane_count = 4;
1454 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_NV12_BPP10_UBWC, plane_info);
1455 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1456 plane_info[0].h_subsampling = 0;
1457 plane_info[0].v_subsampling = 0;
1458 plane_info[1].step = 1;
1459 plane_info[1].h_subsampling = h_subsampling;
1460 plane_info[1].v_subsampling = v_subsampling;
1461 plane_info[1].step = 3;
1462 plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1463 plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1464 plane_info[2].step = plane_info[3].step = 0;
1465 break;
1466
1467 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1468 *plane_count = 4;
1469 GetYuvUbwcSPPlaneInfo(width, height, COLOR_FMT_P010_UBWC, plane_info);
1470 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1471 plane_info[0].h_subsampling = 0;
1472 plane_info[0].v_subsampling = 0;
1473 plane_info[1].step = 1;
1474 plane_info[1].h_subsampling = h_subsampling;
1475 plane_info[1].v_subsampling = v_subsampling;
1476 plane_info[1].step = 4;
1477 plane_info[2].h_subsampling = plane_info[3].h_subsampling = 0;
1478 plane_info[2].v_subsampling = plane_info[3].v_subsampling = 0;
1479 plane_info[2].step = plane_info[3].step = 0;
1480 break;
1481
1482 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1483 *plane_count = 2;
1484 y_stride = VENUS_Y_STRIDE(COLOR_FMT_P010, width);
1485 c_stride = VENUS_UV_STRIDE(COLOR_FMT_P010, width);
1486 y_height = VENUS_Y_SCANLINES(COLOR_FMT_P010, height);
1487 y_size = y_stride * y_height;
1488 yOffset = 0;
1489 cOffset = y_size;
1490 c_height = VENUS_UV_SCANLINES(COLOR_FMT_P010, INT(height));
1491 c_size = c_stride * c_height;
1492 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1493
1494 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
1495 plane_info[0].offset = (uint32_t)yOffset;
1496 plane_info[0].stride = static_cast<int32_t>(UINT(width));
1497 plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
1498 plane_info[0].scanlines = static_cast<int32_t>(y_height);
1499 plane_info[0].size = static_cast<uint32_t>(y_size);
1500 plane_info[0].step = 1;
1501 plane_info[0].h_subsampling = 0;
1502 plane_info[0].v_subsampling = 0;
1503
1504 plane_info[1].component = (PlaneComponent)(PLANE_COMPONENT_Cb | PLANE_COMPONENT_Cr);
1505 plane_info[1].offset = (uint32_t)cOffset;
1506 plane_info[1].stride = static_cast<int32_t>(UINT(width));
1507 plane_info[1].stride_bytes = static_cast<int32_t>(c_stride);
1508 plane_info[1].scanlines = static_cast<int32_t>(c_height);
1509 plane_info[1].size = static_cast<uint32_t>(c_size);
1510 plane_info[1].step = 4;
1511 plane_info[1].h_subsampling = h_subsampling;
1512 plane_info[1].v_subsampling = v_subsampling;
1513 break;
1514
1515 // Planar
1516 case HAL_PIXEL_FORMAT_YV12:
1517 if ((info.width & 1) || (info.height & 1)) {
1518 ALOGE("w or h is odd for the YV12 format");
1519 err = -EINVAL;
1520 return err;
1521 }
1522 *plane_count = 3;
1523 y_stride = width;
1524 c_stride = ALIGN(width / 2, 16);
1525 y_height = UINT(height);
1526 y_size = (y_stride * y_height);
1527 height = height >> 1;
1528 c_height = UINT(height);
1529 c_size = (c_stride * c_height);
1530 yOffset = 0;
1531 crOffset = y_size;
1532 cbOffset = (y_size + c_size);
1533 GetYuvSubSamplingFactor(format, &h_subsampling, &v_subsampling);
1534
1535 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
1536 plane_info[0].offset = (uint32_t)yOffset;
1537 plane_info[0].stride = static_cast<int32_t>(UINT(width));
1538 plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
1539 plane_info[0].scanlines = static_cast<int32_t>(y_height);
1540 plane_info[0].size = static_cast<uint32_t>(y_size);
1541 plane_info[0].step = 1;
1542 plane_info[0].h_subsampling = 0;
1543 plane_info[0].v_subsampling = 0;
1544
1545 plane_info[1].component = (PlaneComponent)PLANE_COMPONENT_Cb;
1546 plane_info[1].offset = (uint32_t)cbOffset;
1547 plane_info[2].component = (PlaneComponent)PLANE_COMPONENT_Cr;
1548 plane_info[2].offset = (uint32_t)crOffset;
1549 for (int i = 1; i < 3; i++) {
1550 plane_info[i].stride = static_cast<int32_t>(UINT(width));
1551 plane_info[i].stride_bytes = static_cast<int32_t>(c_stride);
1552 plane_info[i].scanlines = static_cast<int32_t>(c_height);
1553 plane_info[i].size = static_cast<uint32_t>(c_size);
1554 plane_info[i].step = 1;
1555 plane_info[i].h_subsampling = h_subsampling;
1556 plane_info[i].v_subsampling = v_subsampling;
1557 }
1558 break;
1559 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1560 if (info.width & 1) {
1561 ALOGE("width is odd for the YUV422_SP format");
1562 err = -EINVAL;
1563 return err;
1564 }
1565 *plane_count = 1;
1566 y_stride = width * 2;
1567 y_height = UINT(height);
1568 y_size = y_stride * y_height;
1569 yOffset = 0;
1570 plane_info[0].component = (PlaneComponent)PLANE_COMPONENT_Y;
1571 plane_info[0].offset = (uint32_t)yOffset;
1572 plane_info[0].stride = static_cast<int32_t>(UINT(width));
1573 plane_info[0].stride_bytes = static_cast<int32_t>(y_stride);
1574 plane_info[0].scanlines = static_cast<int32_t>(y_height);
1575 plane_info[0].size = static_cast<uint32_t>(y_size);
1576 plane_info[0].step = 1;
1577 plane_info[0].h_subsampling = 0;
1578 plane_info[0].v_subsampling = 0;
1579 break;
1580
1581 // Unsupported formats
1582 case HAL_PIXEL_FORMAT_YCbCr_422_I:
1583 case HAL_PIXEL_FORMAT_YCrCb_422_I:
1584 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
1585 default:
1586 *plane_count = 0;
1587 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
1588 err = -EINVAL;
1589 }
1590 return err;
1591}
1592
1593void GetYuvSubSamplingFactor(int32_t format, int *h_subsampling, int *v_subsampling) {
1594 switch (format) {
1595 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1596 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1597 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1598 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1599 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1600 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1601 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1602 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
1603 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1604 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1605 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS
Ramakant Singh13596ae2020-01-06 20:12:34 +05301606 case HAL_PIXEL_FORMAT_NV21_ENCODEABLE:
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301607 case HAL_PIXEL_FORMAT_NV21_ZSL:
1608 case HAL_PIXEL_FORMAT_YV12:
1609 *h_subsampling = 1;
1610 *v_subsampling = 1;
1611 break;
1612 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1613 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
1614 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
1615 *h_subsampling = 1;
1616 *v_subsampling = 0;
1617 break;
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301618 case HAL_PIXEL_FORMAT_Y16:
Ashish Kumarb9392ff2019-03-27 18:30:39 +05301619 case HAL_PIXEL_FORMAT_Y8:
1620 case HAL_PIXEL_FORMAT_BLOB:
1621 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1622 case HAL_PIXEL_FORMAT_NV12_HEIF:
1623 default:
1624 *h_subsampling = 0;
1625 *v_subsampling = 0;
1626 break;
1627 }
1628}
1629
1630void CopyPlaneLayoutInfotoAndroidYcbcr(uint64_t base, int plane_count, PlaneLayoutInfo *plane_info,
1631 struct android_ycbcr *ycbcr) {
1632 ycbcr->y = reinterpret_cast<void *>(base + plane_info[0].offset);
1633 ycbcr->ystride = plane_info[0].stride_bytes;
1634 if (plane_count == 1) {
1635 ycbcr->cb = NULL;
1636 ycbcr->cr = NULL;
1637 ycbcr->cstride = 0;
1638 ycbcr->chroma_step = 0;
1639 } else if (plane_count == 2 || plane_count == 4 || plane_count == 8) {
1640 /* For YUV semiplanar :-
1641 * - In progressive & linear case plane count is 2 and plane_info[0] will
1642 * contain info about Y plane and plane_info[1] will contain info about UV plane.
1643 * - In progressive & compressed case plane count is 4 then plane_info[0] will
1644 * contain info about Y plane and plane_info[1] will contain info about UV plane.
1645 * Remaining two plane (plane_info[2] & plane_info[3]) contain info about the
1646 * Y_Meta_Plane and UV_Meta_Plane.
1647 * - In interlaced & compressed case plane count is 8 then plane_info[0], plane_info[1],
1648 * plane_info[4] & plane_info[5] will contain info about Y_plane, UV_plane, Y_plane
1649 * & UV_plane. Remaining plane will contain info about the meta planes. As in this case
1650 * this API is called twice through GetYUVPlaneInfo() with address of plane_info[0] &
1651 * plane_info[4], so this will calculate the information accordingly and will fill the
1652 * ycbcr structure with interlaced plane info only.
1653 */
1654 ycbcr->cb = reinterpret_cast<void *>(base + plane_info[1].offset);
1655 ycbcr->cr = reinterpret_cast<void *>(base + plane_info[1].offset + 1);
1656 ycbcr->cstride = plane_info[1].stride_bytes;
1657 ycbcr->chroma_step = plane_info[1].step;
1658 } else if (plane_count == 3) {
1659 /* For YUV planar :-
1660 * Plane size is 3 and plane_info[0], plane_info[1], plane_info[2] will
1661 * contain info about y_plane, cb_plane and cr_plane accordingly.
1662 */
1663 ycbcr->cb = reinterpret_cast<void *>(base + plane_info[1].offset);
1664 ycbcr->cr = reinterpret_cast<void *>(base + plane_info[2].offset);
1665 ycbcr->cstride = plane_info[1].stride_bytes;
1666 ycbcr->chroma_step = plane_info[1].step;
1667 }
1668}
1669
Ashish Kumar8a1b56e2019-11-15 18:15:22 +05301670bool HasAlphaComponent(int32_t format) {
1671 switch (format) {
1672 case HAL_PIXEL_FORMAT_RGBA_8888:
1673 case HAL_PIXEL_FORMAT_BGRA_8888:
1674 case HAL_PIXEL_FORMAT_RGBA_5551:
1675 case HAL_PIXEL_FORMAT_RGBA_4444:
1676 case HAL_PIXEL_FORMAT_RGBA_1010102:
1677 case HAL_PIXEL_FORMAT_ARGB_2101010:
1678 case HAL_PIXEL_FORMAT_BGRA_1010102:
1679 case HAL_PIXEL_FORMAT_ABGR_2101010:
1680 case HAL_PIXEL_FORMAT_RGBA_FP16:
1681 return true;
1682 default:
1683 return false;
1684 }
1685}
1686
1687void GetRGBPlaneInfo(const BufferInfo &info, int32_t format, int32_t width, int32_t height,
1688 int32_t /* flags */, int *plane_count, PlaneLayoutInfo *plane_info) {
1689 uint64_t usage = info.usage;
1690 *plane_count = 1;
1691 uint32_t bpp = 0;
1692 if (IsUncompressedRGBFormat(format)) {
1693 bpp = GetBppForUncompressedRGB(format);
1694 }
1695 plane_info->component =
1696 (PlaneComponent)(PLANE_COMPONENT_R | PLANE_COMPONENT_G | PLANE_COMPONENT_B);
1697 if (HasAlphaComponent(format)) {
1698 plane_info->component = (PlaneComponent)(plane_info->component | PLANE_COMPONENT_A);
1699 }
1700 plane_info->size = GetSize(info, width, height);
1701 plane_info->step = bpp;
1702 plane_info->offset = GetRgbMetaSize(format, width, height, usage);
1703 plane_info->h_subsampling = 0;
1704 plane_info->v_subsampling = 0;
1705 plane_info->stride = width;
1706 plane_info->stride_bytes = width * plane_info->step;
1707 plane_info->scanlines = height;
1708}
1709
Tharaga Balachandran74ab1112020-01-08 17:17:56 -05001710// TODO(tbalacha): tile vs ubwc -- may need to find a diff way to differentiate
1711void GetDRMFormat(uint32_t format, uint32_t flags, uint32_t *drm_format,
1712 uint64_t *drm_format_modifier) {
1713 bool compressed = (flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) ? true : false;
1714 switch (format) {
1715 case HAL_PIXEL_FORMAT_RGBA_8888:
1716 *drm_format = DRM_FORMAT_ABGR8888;
1717 break;
1718 case HAL_PIXEL_FORMAT_RGBA_5551:
1719 *drm_format = DRM_FORMAT_ABGR1555;
1720 break;
1721 case HAL_PIXEL_FORMAT_RGBA_4444:
1722 *drm_format = DRM_FORMAT_ABGR4444;
1723 break;
1724 case HAL_PIXEL_FORMAT_BGRA_8888:
1725 *drm_format = DRM_FORMAT_ARGB8888;
1726 break;
1727 case HAL_PIXEL_FORMAT_RGBX_8888:
1728 *drm_format = DRM_FORMAT_XBGR8888;
1729 if (compressed)
1730 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1731 break;
1732 case HAL_PIXEL_FORMAT_BGRX_8888:
1733 *drm_format = DRM_FORMAT_XRGB8888;
1734 break;
1735 case HAL_PIXEL_FORMAT_RGB_888:
1736 *drm_format = DRM_FORMAT_BGR888;
1737 break;
1738 case HAL_PIXEL_FORMAT_RGB_565:
1739 *drm_format = DRM_FORMAT_BGR565;
1740 break;
1741 case HAL_PIXEL_FORMAT_BGR_565:
1742 *drm_format = DRM_FORMAT_BGR565;
1743 if (compressed)
1744 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1745 break;
1746 case HAL_PIXEL_FORMAT_RGBA_1010102:
1747 *drm_format = DRM_FORMAT_ABGR2101010;
1748 if (compressed)
1749 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1750 break;
1751 case HAL_PIXEL_FORMAT_ARGB_2101010:
1752 *drm_format = DRM_FORMAT_BGRA1010102;
1753 break;
1754 case HAL_PIXEL_FORMAT_RGBX_1010102:
1755 *drm_format = DRM_FORMAT_XBGR2101010;
1756 if (compressed)
1757 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1758 break;
1759 case HAL_PIXEL_FORMAT_XRGB_2101010:
1760 *drm_format = DRM_FORMAT_BGRX1010102;
1761 break;
1762 case HAL_PIXEL_FORMAT_BGRA_1010102:
1763 *drm_format = DRM_FORMAT_ARGB2101010;
1764 break;
1765 case HAL_PIXEL_FORMAT_ABGR_2101010:
1766 *drm_format = DRM_FORMAT_RGBA1010102;
1767 break;
1768 case HAL_PIXEL_FORMAT_BGRX_1010102:
1769 *drm_format = DRM_FORMAT_XRGB2101010;
1770 break;
1771 case HAL_PIXEL_FORMAT_XBGR_2101010:
1772 *drm_format = DRM_FORMAT_RGBX1010102;
1773 break;
1774 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
1775 *drm_format = DRM_FORMAT_NV12;
1776 break;
1777 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
1778 *drm_format = DRM_FORMAT_NV12;
1779 if (compressed) {
1780 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED;
1781 } else {
1782 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE;
1783 }
1784 break;
1785 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1786 *drm_format = DRM_FORMAT_NV21;
1787 break;
1788 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
1789 *drm_format = DRM_FORMAT_NV21;
1790 break;
1791 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
1792 case HAL_PIXEL_FORMAT_YCbCr_420_P010_VENUS:
1793 *drm_format = DRM_FORMAT_NV12;
1794 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_DX;
1795 break;
1796 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
1797 *drm_format = DRM_FORMAT_NV12;
1798 if (compressed) {
1799 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_COMPRESSED | DRM_FORMAT_MOD_QCOM_DX;
1800 } else {
1801 *drm_format_modifier = DRM_FORMAT_MOD_QCOM_TILE | DRM_FORMAT_MOD_QCOM_DX;
1802 }
1803 break;
1804 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
1805 *drm_format = DRM_FORMAT_NV12;
1806 if (compressed) {
1807 *drm_format_modifier =
1808 DRM_FORMAT_MOD_QCOM_COMPRESSED | DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
1809 } else {
1810 *drm_format_modifier =
1811 DRM_FORMAT_MOD_QCOM_TILE | DRM_FORMAT_MOD_QCOM_DX | DRM_FORMAT_MOD_QCOM_TIGHT;
1812 }
1813 break;
1814 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
1815 *drm_format = DRM_FORMAT_NV16;
1816 break;
1817 /*
1818 TODO: No HAL_PIXEL_FORMAT equivalent?
1819 case kFormatYCrCb422H2V1SemiPlanar:
1820 *drm_format = DRM_FORMAT_NV61;
1821 break;*/
1822 case HAL_PIXEL_FORMAT_YV12:
1823 *drm_format = DRM_FORMAT_YVU420;
1824 break;
1825 default:
1826 ALOGE("Unsupported format %d", format);
1827 }
1828}
1829
Naseer Ahmede36f2242017-12-01 15:33:56 -05001830} // namespace gralloc