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