blob: d5ec426a271ec1659b5d9f2983a0e5a0534c2937 [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:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530202 case HAL_PIXEL_FORMAT_Y16:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700203 size = alignedw * alignedh * 2;
204 break;
205 case HAL_PIXEL_FORMAT_RAW10:
206 case HAL_PIXEL_FORMAT_RAW12:
207 size = ALIGN(alignedw * alignedh, SIZE_4K);
208 break;
209 case HAL_PIXEL_FORMAT_RAW8:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530210 case HAL_PIXEL_FORMAT_Y8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700211 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:
245 if (width & 1) {
246 ALOGE("width is odd for the YUV422_SP format");
247 return 0;
248 }
249 size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
250 break;
251 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
252 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
253 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
254 break;
255 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
256 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
257 break;
258 case HAL_PIXEL_FORMAT_BLOB:
259 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
260 if (height != 1) {
261 ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
262 return 0;
263 }
264 size = (unsigned int)width;
265 break;
266 case HAL_PIXEL_FORMAT_NV21_ZSL:
267 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
268 break;
269 default:
270 ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
271 return 0;
272 }
273
274 return size;
275}
276
277void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size,
278 unsigned int *alignedw, unsigned int *alignedh) {
279 GetAlignedWidthAndHeight(info, alignedw, alignedh);
280 *size = GetSize(info, *alignedw, *alignedh);
281}
282
283void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
284 int color_format, struct android_ycbcr *ycbcr) {
285 // UBWC buffer has these 4 planes in the following sequence:
286 // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
287 unsigned int y_meta_stride, y_meta_height, y_meta_size;
288 unsigned int y_stride, y_height, y_size;
289 unsigned int c_meta_stride, c_meta_height, c_meta_size;
290 unsigned int alignment = 4096;
291
292 y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
293 y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
294 y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
295
296 y_stride = VENUS_Y_STRIDE(color_format, INT(width));
297 y_height = VENUS_Y_SCANLINES(color_format, INT(height));
298 y_size = ALIGN((y_stride * y_height), alignment);
299
300 c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
301 c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
302 c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
303
304 ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
305 ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
306 ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
307 ycbcr->ystride = y_stride;
308 ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
309}
310
311void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
312 struct android_ycbcr *ycbcr) {
313 unsigned int ystride, cstride;
314
315 ystride = cstride = UINT(width) * bpp;
316 ycbcr->y = reinterpret_cast<void *>(base);
317 ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
318 ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
319 ycbcr->ystride = ystride;
320 ycbcr->cstride = cstride;
321 ycbcr->chroma_step = 2 * bpp;
322}
323
324int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
325 int err = 0;
326 uint32_t width = UINT(hnd->width);
327 uint32_t height = UINT(hnd->height);
328 int format = hnd->format;
329 gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
330 gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
331 unsigned int ystride, cstride;
332
333 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
334 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
335
336 // Check if UBWC buffer has been rendered in linear format.
337 if (metadata && (metadata->operation & LINEAR_FORMAT)) {
338 format = INT(metadata->linearFormat);
339 }
340
341 // Check metadata if the geometry has been updated.
342 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
343 int usage = 0;
344
345 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
346 usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
347 }
348
349 BufferInfo info(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
350 prod_usage, cons_usage);
351 GetAlignedWidthAndHeight(info, &width, &height);
352 }
353
354 // Get the chroma offsets from the handle width/height. We take advantage
355 // of the fact the width _is_ the stride
356 switch (format) {
357 // Semiplanar
358 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
359 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
360 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
361 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
362 // Same as YCbCr_420_SP_VENUS
363 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
364 break;
365
366 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
367 GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
368 break;
369
370 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
371 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
372 ycbcr->chroma_step = 2;
373 break;
374
375 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
376 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
377 ycbcr->chroma_step = 3;
378 break;
379
380 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
381 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
382 ycbcr->chroma_step = 4;
383 break;
384
385 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
386 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
387 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
388 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
389 case HAL_PIXEL_FORMAT_NV21_ZSL:
390 case HAL_PIXEL_FORMAT_RAW16:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530391 case HAL_PIXEL_FORMAT_Y16:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700392 case HAL_PIXEL_FORMAT_RAW10:
393 case HAL_PIXEL_FORMAT_RAW8:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530394 case HAL_PIXEL_FORMAT_Y8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700395 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
396 std::swap(ycbcr->cb, ycbcr->cr);
397 break;
398
399 // Planar
400 case HAL_PIXEL_FORMAT_YV12:
401 ystride = width;
402 cstride = ALIGN(width / 2, 16);
403 ycbcr->y = reinterpret_cast<void *>(hnd->base);
404 ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
405 ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
406 ycbcr->ystride = ystride;
407 ycbcr->cstride = cstride;
408 ycbcr->chroma_step = 1;
409 break;
410
411 // Unsupported formats
412 case HAL_PIXEL_FORMAT_YCbCr_422_I:
413 case HAL_PIXEL_FORMAT_YCrCb_422_I:
414 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
415 default:
416 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
417 err = -EINVAL;
418 }
419
420 return err;
421}
422
423// Explicitly defined UBWC formats
424bool IsUBwcFormat(int format) {
425 switch (format) {
426 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
427 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
428 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
429 return true;
430 default:
431 return false;
432 }
433}
434
435bool IsUBwcSupported(int format) {
436 // Existing HAL formats with UBWC support
437 switch (format) {
438 case HAL_PIXEL_FORMAT_BGR_565:
439 case HAL_PIXEL_FORMAT_RGBA_8888:
440 case HAL_PIXEL_FORMAT_RGBX_8888:
441 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
442 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
443 case HAL_PIXEL_FORMAT_RGBA_1010102:
444 case HAL_PIXEL_FORMAT_RGBX_1010102:
445 return true;
446 default:
447 break;
448 }
449
450 return false;
451}
452
453bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
454 gralloc1_consumer_usage_t cons_usage) {
455 // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
456 if (IsUBwcFormat(format)) {
457 return true;
458 }
459
460 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
461 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
462 // usage flag and MDP supports the format.
463 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
464 bool enable = true;
465 // Query GPU for UBWC only if buffer is intended to be used by GPU.
466 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
467 (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
468 enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
469 }
470
471 // Allow UBWC, only if CPU usage flags are not set
472 if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
473 return true;
474 }
475 }
476
477 return false;
478}
479
480void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
481 unsigned int *aligned_h) {
482 switch (format) {
483 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
484 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
485 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
486 *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
487 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
488 break;
489 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
490 // The macro returns the stride which is 4/3 times the width, hence * 3/4
491 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
492 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
493 break;
494 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
495 // The macro returns the stride which is 2 times the width, hence / 2
496 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
497 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
498 break;
499 default:
500 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
501 *aligned_w = 0;
502 *aligned_h = 0;
503 break;
504 }
505}
506
507void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
508 *block_width = 0;
509 *block_height = 0;
510
511 switch (bpp) {
512 case 2:
513 case 4:
514 *block_width = 16;
515 *block_height = 4;
516 break;
517 case 8:
518 *block_width = 8;
519 *block_height = 4;
520 break;
521 case 16:
522 *block_width = 4;
523 *block_height = 4;
524 break;
525 default:
526 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
527 break;
528 }
529}
530
531unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
532 unsigned int size = 0;
533 int meta_width, meta_height;
534 int block_width, block_height;
535
536 GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
537 if (!block_width || !block_height) {
538 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
539 return size;
540 }
541
542 // Align meta buffer height to 16 blocks
543 meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
544
545 // Align meta buffer width to 64 blocks
546 meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
547
548 // Align meta buffer size to 4K
549 size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
550
551 return size;
552}
553
554unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
555 unsigned int alignedh) {
556 unsigned int size = 0;
557 uint32_t bpp = 0;
558 switch (format) {
559 case HAL_PIXEL_FORMAT_BGR_565:
560 case HAL_PIXEL_FORMAT_RGBA_8888:
561 case HAL_PIXEL_FORMAT_RGBX_8888:
562 case HAL_PIXEL_FORMAT_RGBA_1010102:
563 case HAL_PIXEL_FORMAT_RGBX_1010102:
564 bpp = GetBppForUncompressedRGB(format);
565 size = alignedw * alignedh * bpp;
566 size += GetRgbUBwcMetaBufferSize(width, height, bpp);
567 break;
568 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
569 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
570 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
571 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
572 break;
573 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
574 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
575 break;
576 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
577 size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
578 break;
579 default:
580 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
581 break;
582 }
583
584 return size;
585}
586
587int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
588 int err = 0;
589
590 // This api is for RGB* formats
591 if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
592 return -EINVAL;
593 }
594
595 // linear buffer, nothing to do further
596 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
597 *rgb_data = reinterpret_cast<void *>(hnd->base);
598 return err;
599 }
600
601 unsigned int meta_size = 0;
602 uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
603 switch (hnd->format) {
604 case HAL_PIXEL_FORMAT_BGR_565:
605 case HAL_PIXEL_FORMAT_RGBA_8888:
606 case HAL_PIXEL_FORMAT_RGBX_8888:
607 case HAL_PIXEL_FORMAT_RGBA_1010102:
608 case HAL_PIXEL_FORMAT_RGBX_1010102:
609 meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
610 break;
611 default:
612 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
613 err = -EINVAL;
614 break;
615 }
616 *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
617
618 return err;
619}
620
621void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
622 unsigned int *alignedh) {
623 int width = info.width;
624 int height = info.height;
625 int format = info.format;
626 gralloc1_producer_usage_t prod_usage = info.prod_usage;
627 gralloc1_consumer_usage_t cons_usage = info.cons_usage;
628
629 // Currently surface padding is only computed for RGB* surfaces.
630 bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
631 int tile = ubwc_enabled;
632
633 if (IsUncompressedRGBFormat(format)) {
634 AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
635 alignedh);
636 return;
637 }
638
639 if (ubwc_enabled) {
640 GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
641 return;
642 }
643
644 if (IsCompressedRGBFormat(format)) {
645 AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
646 return;
647 }
648
649 int aligned_w = width;
650 int aligned_h = height;
651 unsigned int alignment = 32;
652
653 // Below should be only YUV family
654 switch (format) {
655 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
656 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
657 alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
658 aligned_w = ALIGN(width, alignment);
659 break;
660 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
661 aligned_w = ALIGN(width, alignment);
662 break;
663 case HAL_PIXEL_FORMAT_RAW16:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530664 case HAL_PIXEL_FORMAT_Y16:
665 case HAL_PIXEL_FORMAT_Y8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700666 aligned_w = ALIGN(width, 16);
667 break;
668 case HAL_PIXEL_FORMAT_RAW12:
669 aligned_w = ALIGN(width * 12 / 8, 8);
670 break;
671 case HAL_PIXEL_FORMAT_RAW10:
672 aligned_w = ALIGN(width * 10 / 8, 8);
673 break;
674 case HAL_PIXEL_FORMAT_RAW8:
675 aligned_w = ALIGN(width, 8);
676 break;
677 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
678 aligned_w = ALIGN(width, 128);
679 break;
680 case HAL_PIXEL_FORMAT_YV12:
681 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
682 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
683 case HAL_PIXEL_FORMAT_YCbCr_422_I:
684 case HAL_PIXEL_FORMAT_YCrCb_422_I:
685 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
686 aligned_w = ALIGN(width, 16);
687 break;
688 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
689 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
690 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
691 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
692 break;
693 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
694 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
695 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
696 break;
697 case HAL_PIXEL_FORMAT_BLOB:
698 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
699 break;
700 case HAL_PIXEL_FORMAT_NV21_ZSL:
701 aligned_w = ALIGN(width, 64);
702 aligned_h = ALIGN(height, 64);
703 break;
704 default:
705 break;
706 }
707
708 *alignedw = (unsigned int)aligned_w;
709 *alignedh = (unsigned int)aligned_h;
710}
711
712int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4],
713 uint32_t offset[4], uint32_t *num_planes) {
714 if (!hnd || !stride || !offset || !num_planes) {
715 return -EINVAL;
716 }
717
718 struct android_ycbcr yuvInfo = {};
719 *num_planes = 1;
720 stride[0] = 0;
721
722 switch (hnd->format) {
723 case HAL_PIXEL_FORMAT_RGB_565:
724 case HAL_PIXEL_FORMAT_BGR_565:
725 case HAL_PIXEL_FORMAT_RGBA_5551:
726 case HAL_PIXEL_FORMAT_RGBA_4444:
727 stride[0] = static_cast<uint32_t>(hnd->width * 2);
728 break;
729 case HAL_PIXEL_FORMAT_RGB_888:
730 stride[0] = static_cast<uint32_t>(hnd->width * 3);
731 break;
732 case HAL_PIXEL_FORMAT_RGBA_8888:
733 case HAL_PIXEL_FORMAT_BGRA_8888:
734 case HAL_PIXEL_FORMAT_RGBX_8888:
735 case HAL_PIXEL_FORMAT_BGRX_8888:
736 case HAL_PIXEL_FORMAT_RGBA_1010102:
737 case HAL_PIXEL_FORMAT_ARGB_2101010:
738 case HAL_PIXEL_FORMAT_RGBX_1010102:
739 case HAL_PIXEL_FORMAT_XRGB_2101010:
740 case HAL_PIXEL_FORMAT_BGRA_1010102:
741 case HAL_PIXEL_FORMAT_ABGR_2101010:
742 case HAL_PIXEL_FORMAT_BGRX_1010102:
743 case HAL_PIXEL_FORMAT_XBGR_2101010:
744 stride[0] = static_cast<uint32_t>(hnd->width * 4);
745 break;
746 }
747
748 // Format is RGB
749 if (stride[0]) {
750 return 0;
751 }
752
753 (*num_planes)++;
754 int ret = GetYUVPlaneInfo(hnd, &yuvInfo);
755 if (ret < 0) {
756 ALOGE("%s failed", __FUNCTION__);
757 return ret;
758 }
759
760 stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
761 offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
762 stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
763 switch (hnd->format) {
764 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
765 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
766 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
767 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
768 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
769 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
770 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
771 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
772 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
773 break;
774 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
775 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
776 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
777 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
778 break;
779 case HAL_PIXEL_FORMAT_YV12:
780 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
781 stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
782 offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
783 (*num_planes)++;
784 break;
785 default:
786 ALOGW("%s: Unsupported format", __FUNCTION__);
787 ret = -EINVAL;
788 }
789
790 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
791 std::fill(offset, offset + 4, 0);
792 }
793
794 return 0;
795}
796
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530797} // namespace gralloc1