blob: 30afe4c3dc20c34ed6699f8c30089eb8c6686d8f [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
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700312void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
313 int color_format, struct android_ycbcr *ycbcr) {
314 unsigned int uv_stride, uv_height, uv_size;
315 unsigned int alignment = 4096;
316 uint64_t field_base;
317
318 // UBWC interlaced has top-bottom field layout with each field as
319 // 4-plane NV12_UBWC with width = image_width & height = image_height / 2.
320 // Client passed ycbcr argument is ptr to struct android_ycbcr[2].
321 // Plane info to be filled for each field separately.
322 height = (height + 1) >> 1;
323 uv_stride = VENUS_UV_STRIDE(color_format, INT(width));
324 uv_height = VENUS_UV_SCANLINES(color_format, INT(height));
325 uv_size = ALIGN((uv_stride * uv_height), alignment);
326
327 field_base = base;
328 GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
329
330 field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
331 GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
332}
333
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700334void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
335 struct android_ycbcr *ycbcr) {
336 unsigned int ystride, cstride;
337
338 ystride = cstride = UINT(width) * bpp;
339 ycbcr->y = reinterpret_cast<void *>(base);
340 ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
341 ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
342 ycbcr->ystride = ystride;
343 ycbcr->cstride = cstride;
344 ycbcr->chroma_step = 2 * bpp;
345}
346
347int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
348 int err = 0;
349 uint32_t width = UINT(hnd->width);
350 uint32_t height = UINT(hnd->height);
351 int format = hnd->format;
352 gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
353 gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
354 unsigned int ystride, cstride;
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700355 bool interlaced = false;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700356
357 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
358 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
359
360 // Check if UBWC buffer has been rendered in linear format.
361 if (metadata && (metadata->operation & LINEAR_FORMAT)) {
362 format = INT(metadata->linearFormat);
363 }
364
365 // Check metadata if the geometry has been updated.
366 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
367 int usage = 0;
368
369 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
370 usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
371 }
372
373 BufferInfo info(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
374 prod_usage, cons_usage);
375 GetAlignedWidthAndHeight(info, &width, &height);
376 }
377
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700378 // Check metadata for interlaced content.
379 if (metadata && (metadata->operation & PP_PARAM_INTERLACED)) {
380 interlaced = metadata->interlaced ? true : false;
381 }
382
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700383 // Get the chroma offsets from the handle width/height. We take advantage
384 // of the fact the width _is_ the stride
385 switch (format) {
386 // Semiplanar
387 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
388 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
389 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
390 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
391 // Same as YCbCr_420_SP_VENUS
392 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
393 break;
394
395 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
396 GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
397 break;
398
399 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700400 if (!interlaced) {
401 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
402 } else {
403 GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
404 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700405 ycbcr->chroma_step = 2;
406 break;
407
408 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
409 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
410 ycbcr->chroma_step = 3;
411 break;
412
413 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
414 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
415 ycbcr->chroma_step = 4;
416 break;
417
418 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
419 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
420 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
421 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
422 case HAL_PIXEL_FORMAT_NV21_ZSL:
423 case HAL_PIXEL_FORMAT_RAW16:
424 case HAL_PIXEL_FORMAT_RAW10:
425 case HAL_PIXEL_FORMAT_RAW8:
426 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
427 std::swap(ycbcr->cb, ycbcr->cr);
428 break;
429
430 // Planar
431 case HAL_PIXEL_FORMAT_YV12:
432 ystride = width;
433 cstride = ALIGN(width / 2, 16);
434 ycbcr->y = reinterpret_cast<void *>(hnd->base);
435 ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
436 ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
437 ycbcr->ystride = ystride;
438 ycbcr->cstride = cstride;
439 ycbcr->chroma_step = 1;
440 break;
Camus Wong5c5e6fb2017-03-21 17:02:48 -0400441 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
442 ystride = width * 2;
443 cstride = 0;
444 ycbcr->y = reinterpret_cast<void *>(hnd->base);
445 ycbcr->cr = NULL;
446 ycbcr->cb = NULL;
447 ycbcr->ystride = ystride;
448 ycbcr->cstride = 0;
449 ycbcr->chroma_step = 0;
450 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700451 // Unsupported formats
452 case HAL_PIXEL_FORMAT_YCbCr_422_I:
453 case HAL_PIXEL_FORMAT_YCrCb_422_I:
454 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
455 default:
456 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
457 err = -EINVAL;
458 }
459
460 return err;
461}
462
463// Explicitly defined UBWC formats
464bool IsUBwcFormat(int format) {
465 switch (format) {
466 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
467 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
468 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
469 return true;
470 default:
471 return false;
472 }
473}
474
475bool IsUBwcSupported(int format) {
476 // Existing HAL formats with UBWC support
477 switch (format) {
478 case HAL_PIXEL_FORMAT_BGR_565:
479 case HAL_PIXEL_FORMAT_RGBA_8888:
480 case HAL_PIXEL_FORMAT_RGBX_8888:
481 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
482 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
483 case HAL_PIXEL_FORMAT_RGBA_1010102:
484 case HAL_PIXEL_FORMAT_RGBX_1010102:
485 return true;
486 default:
487 break;
488 }
489
490 return false;
491}
492
493bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
494 gralloc1_consumer_usage_t cons_usage) {
495 // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
496 if (IsUBwcFormat(format)) {
497 return true;
498 }
499
500 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
501 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
502 // usage flag and MDP supports the format.
503 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
504 bool enable = true;
505 // Query GPU for UBWC only if buffer is intended to be used by GPU.
506 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
507 (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
508 enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
509 }
510
511 // Allow UBWC, only if CPU usage flags are not set
512 if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
513 return true;
514 }
515 }
516
517 return false;
518}
519
520void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
521 unsigned int *aligned_h) {
522 switch (format) {
523 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
524 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
525 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
526 *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
527 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
528 break;
529 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
530 // The macro returns the stride which is 4/3 times the width, hence * 3/4
531 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
532 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
533 break;
534 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
535 // The macro returns the stride which is 2 times the width, hence / 2
536 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
537 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
538 break;
539 default:
540 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
541 *aligned_w = 0;
542 *aligned_h = 0;
543 break;
544 }
545}
546
547void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
548 *block_width = 0;
549 *block_height = 0;
550
551 switch (bpp) {
552 case 2:
553 case 4:
554 *block_width = 16;
555 *block_height = 4;
556 break;
557 case 8:
558 *block_width = 8;
559 *block_height = 4;
560 break;
561 case 16:
562 *block_width = 4;
563 *block_height = 4;
564 break;
565 default:
566 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
567 break;
568 }
569}
570
571unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
572 unsigned int size = 0;
573 int meta_width, meta_height;
574 int block_width, block_height;
575
576 GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
577 if (!block_width || !block_height) {
578 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
579 return size;
580 }
581
582 // Align meta buffer height to 16 blocks
583 meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
584
585 // Align meta buffer width to 64 blocks
586 meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
587
588 // Align meta buffer size to 4K
589 size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
590
591 return size;
592}
593
594unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
595 unsigned int alignedh) {
596 unsigned int size = 0;
597 uint32_t bpp = 0;
598 switch (format) {
599 case HAL_PIXEL_FORMAT_BGR_565:
600 case HAL_PIXEL_FORMAT_RGBA_8888:
601 case HAL_PIXEL_FORMAT_RGBX_8888:
602 case HAL_PIXEL_FORMAT_RGBA_1010102:
603 case HAL_PIXEL_FORMAT_RGBX_1010102:
604 bpp = GetBppForUncompressedRGB(format);
605 size = alignedw * alignedh * bpp;
606 size += GetRgbUBwcMetaBufferSize(width, height, bpp);
607 break;
608 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
609 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
610 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
611 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
612 break;
613 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
614 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
615 break;
616 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
617 size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
618 break;
619 default:
620 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
621 break;
622 }
623
624 return size;
625}
626
627int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
628 int err = 0;
629
630 // This api is for RGB* formats
631 if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
632 return -EINVAL;
633 }
634
635 // linear buffer, nothing to do further
636 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
637 *rgb_data = reinterpret_cast<void *>(hnd->base);
638 return err;
639 }
640
641 unsigned int meta_size = 0;
642 uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
643 switch (hnd->format) {
644 case HAL_PIXEL_FORMAT_BGR_565:
645 case HAL_PIXEL_FORMAT_RGBA_8888:
646 case HAL_PIXEL_FORMAT_RGBX_8888:
647 case HAL_PIXEL_FORMAT_RGBA_1010102:
648 case HAL_PIXEL_FORMAT_RGBX_1010102:
649 meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
650 break;
651 default:
652 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
653 err = -EINVAL;
654 break;
655 }
656 *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
657
658 return err;
659}
660
661void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
662 unsigned int *alignedh) {
663 int width = info.width;
664 int height = info.height;
665 int format = info.format;
666 gralloc1_producer_usage_t prod_usage = info.prod_usage;
667 gralloc1_consumer_usage_t cons_usage = info.cons_usage;
668
669 // Currently surface padding is only computed for RGB* surfaces.
670 bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
671 int tile = ubwc_enabled;
672
673 if (IsUncompressedRGBFormat(format)) {
674 AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
675 alignedh);
676 return;
677 }
678
679 if (ubwc_enabled) {
680 GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
681 return;
682 }
683
684 if (IsCompressedRGBFormat(format)) {
685 AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
686 return;
687 }
688
689 int aligned_w = width;
690 int aligned_h = height;
691 unsigned int alignment = 32;
692
693 // Below should be only YUV family
694 switch (format) {
695 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
696 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
697 alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
698 aligned_w = ALIGN(width, alignment);
699 break;
700 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
701 aligned_w = ALIGN(width, alignment);
702 break;
703 case HAL_PIXEL_FORMAT_RAW16:
704 aligned_w = ALIGN(width, 16);
705 break;
706 case HAL_PIXEL_FORMAT_RAW12:
707 aligned_w = ALIGN(width * 12 / 8, 8);
708 break;
709 case HAL_PIXEL_FORMAT_RAW10:
710 aligned_w = ALIGN(width * 10 / 8, 8);
711 break;
712 case HAL_PIXEL_FORMAT_RAW8:
713 aligned_w = ALIGN(width, 8);
714 break;
715 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
716 aligned_w = ALIGN(width, 128);
717 break;
718 case HAL_PIXEL_FORMAT_YV12:
719 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
720 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
721 case HAL_PIXEL_FORMAT_YCbCr_422_I:
722 case HAL_PIXEL_FORMAT_YCrCb_422_I:
723 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
724 aligned_w = ALIGN(width, 16);
725 break;
726 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
727 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
728 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
729 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
730 break;
731 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
732 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
733 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
734 break;
735 case HAL_PIXEL_FORMAT_BLOB:
736 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
737 break;
738 case HAL_PIXEL_FORMAT_NV21_ZSL:
739 aligned_w = ALIGN(width, 64);
740 aligned_h = ALIGN(height, 64);
741 break;
742 default:
743 break;
744 }
745
746 *alignedw = (unsigned int)aligned_w;
747 *alignedh = (unsigned int)aligned_h;
748}
749
750int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4],
751 uint32_t offset[4], uint32_t *num_planes) {
752 if (!hnd || !stride || !offset || !num_planes) {
753 return -EINVAL;
754 }
755
756 struct android_ycbcr yuvInfo = {};
757 *num_planes = 1;
758 stride[0] = 0;
759
760 switch (hnd->format) {
761 case HAL_PIXEL_FORMAT_RGB_565:
762 case HAL_PIXEL_FORMAT_BGR_565:
763 case HAL_PIXEL_FORMAT_RGBA_5551:
764 case HAL_PIXEL_FORMAT_RGBA_4444:
765 stride[0] = static_cast<uint32_t>(hnd->width * 2);
766 break;
767 case HAL_PIXEL_FORMAT_RGB_888:
768 stride[0] = static_cast<uint32_t>(hnd->width * 3);
769 break;
770 case HAL_PIXEL_FORMAT_RGBA_8888:
771 case HAL_PIXEL_FORMAT_BGRA_8888:
772 case HAL_PIXEL_FORMAT_RGBX_8888:
773 case HAL_PIXEL_FORMAT_BGRX_8888:
774 case HAL_PIXEL_FORMAT_RGBA_1010102:
775 case HAL_PIXEL_FORMAT_ARGB_2101010:
776 case HAL_PIXEL_FORMAT_RGBX_1010102:
777 case HAL_PIXEL_FORMAT_XRGB_2101010:
778 case HAL_PIXEL_FORMAT_BGRA_1010102:
779 case HAL_PIXEL_FORMAT_ABGR_2101010:
780 case HAL_PIXEL_FORMAT_BGRX_1010102:
781 case HAL_PIXEL_FORMAT_XBGR_2101010:
782 stride[0] = static_cast<uint32_t>(hnd->width * 4);
783 break;
784 }
785
786 // Format is RGB
787 if (stride[0]) {
788 return 0;
789 }
790
791 (*num_planes)++;
792 int ret = GetYUVPlaneInfo(hnd, &yuvInfo);
793 if (ret < 0) {
794 ALOGE("%s failed", __FUNCTION__);
795 return ret;
796 }
797
798 stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
799 offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
800 stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
801 switch (hnd->format) {
802 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
803 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
804 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
805 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
806 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
807 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
808 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
809 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
810 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
811 break;
812 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
813 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
814 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
815 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
816 break;
817 case HAL_PIXEL_FORMAT_YV12:
818 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
819 stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
820 offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
821 (*num_planes)++;
822 break;
823 default:
824 ALOGW("%s: Unsupported format", __FUNCTION__);
825 ret = -EINVAL;
826 }
827
828 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
829 std::fill(offset, offset + 4, 0);
830 }
831
832 return 0;
833}
834
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530835} // namespace gralloc1