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