blob: 560bb08c41d942c9f19dfc18d2dbe88739948271 [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:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530204 case HAL_PIXEL_FORMAT_Y16:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700205 size = alignedw * alignedh * 2;
206 break;
207 case HAL_PIXEL_FORMAT_RAW10:
208 case HAL_PIXEL_FORMAT_RAW12:
209 size = ALIGN(alignedw * alignedh, SIZE_4K);
210 break;
211 case HAL_PIXEL_FORMAT_RAW8:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530212 case HAL_PIXEL_FORMAT_Y8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700213 size = alignedw * alignedh * 1;
214 break;
215
216 // adreno formats
217 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21
218 size = ALIGN(alignedw * alignedh, SIZE_4K);
219 size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
220 break;
221 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12
222 // The chroma plane is subsampled,
223 // but the pitch in bytes is unchanged
224 // The GPU needs 4K alignment, but the video decoder needs 8K
225 size = ALIGN(alignedw * alignedh, SIZE_8K);
226 size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
227 break;
228 case HAL_PIXEL_FORMAT_YV12:
229 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
230 ALOGE("w or h is odd for the YV12 format");
231 return 0;
232 }
233 size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
234 size = ALIGN(size, (unsigned int)SIZE_4K);
235 break;
236 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
237 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
238 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
239 break;
240 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
241 size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
242 break;
243 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
244 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
245 case HAL_PIXEL_FORMAT_YCbCr_422_I:
246 case HAL_PIXEL_FORMAT_YCrCb_422_I:
Camus Wong5c5e6fb2017-03-21 17:02:48 -0400247 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700248 if (width & 1) {
249 ALOGE("width is odd for the YUV422_SP format");
250 return 0;
251 }
252 size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
253 break;
254 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
255 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
256 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
257 break;
258 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
259 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
260 break;
261 case HAL_PIXEL_FORMAT_BLOB:
262 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
263 if (height != 1) {
264 ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
265 return 0;
266 }
267 size = (unsigned int)width;
268 break;
269 case HAL_PIXEL_FORMAT_NV21_ZSL:
270 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
271 break;
272 default:
273 ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
274 return 0;
275 }
276
277 return size;
278}
279
280void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size,
281 unsigned int *alignedw, unsigned int *alignedh) {
282 GetAlignedWidthAndHeight(info, alignedw, alignedh);
283 *size = GetSize(info, *alignedw, *alignedh);
284}
285
286void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
287 int color_format, struct android_ycbcr *ycbcr) {
288 // UBWC buffer has these 4 planes in the following sequence:
289 // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
290 unsigned int y_meta_stride, y_meta_height, y_meta_size;
291 unsigned int y_stride, y_height, y_size;
292 unsigned int c_meta_stride, c_meta_height, c_meta_size;
293 unsigned int alignment = 4096;
294
295 y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
296 y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
297 y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
298
299 y_stride = VENUS_Y_STRIDE(color_format, INT(width));
300 y_height = VENUS_Y_SCANLINES(color_format, INT(height));
301 y_size = ALIGN((y_stride * y_height), alignment);
302
303 c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
304 c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
305 c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
306
307 ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
308 ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
309 ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
310 ycbcr->ystride = y_stride;
311 ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
312}
313
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700314void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
315 int color_format, struct android_ycbcr *ycbcr) {
316 unsigned int uv_stride, uv_height, uv_size;
317 unsigned int alignment = 4096;
318 uint64_t field_base;
319
320 // UBWC interlaced has top-bottom field layout with each field as
321 // 4-plane NV12_UBWC with width = image_width & height = image_height / 2.
322 // Client passed ycbcr argument is ptr to struct android_ycbcr[2].
323 // Plane info to be filled for each field separately.
324 height = (height + 1) >> 1;
325 uv_stride = VENUS_UV_STRIDE(color_format, INT(width));
326 uv_height = VENUS_UV_SCANLINES(color_format, INT(height));
327 uv_size = ALIGN((uv_stride * uv_height), alignment);
328
329 field_base = base;
330 GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
331
332 field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
333 GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
334}
335
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700336void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
337 struct android_ycbcr *ycbcr) {
338 unsigned int ystride, cstride;
339
340 ystride = cstride = UINT(width) * bpp;
341 ycbcr->y = reinterpret_cast<void *>(base);
342 ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
343 ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
344 ycbcr->ystride = ystride;
345 ycbcr->cstride = cstride;
346 ycbcr->chroma_step = 2 * bpp;
347}
348
349int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
350 int err = 0;
351 uint32_t width = UINT(hnd->width);
352 uint32_t height = UINT(hnd->height);
353 int format = hnd->format;
354 gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
355 gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
356 unsigned int ystride, cstride;
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700357 bool interlaced = false;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700358
359 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
360 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
361
362 // Check if UBWC buffer has been rendered in linear format.
363 if (metadata && (metadata->operation & LINEAR_FORMAT)) {
364 format = INT(metadata->linearFormat);
365 }
366
367 // Check metadata if the geometry has been updated.
368 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
369 int usage = 0;
370
371 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
372 usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
373 }
374
375 BufferInfo info(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
376 prod_usage, cons_usage);
377 GetAlignedWidthAndHeight(info, &width, &height);
378 }
379
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700380 // Check metadata for interlaced content.
381 if (metadata && (metadata->operation & PP_PARAM_INTERLACED)) {
382 interlaced = metadata->interlaced ? true : false;
383 }
384
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700385 // Get the chroma offsets from the handle width/height. We take advantage
386 // of the fact the width _is_ the stride
387 switch (format) {
388 // Semiplanar
389 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
390 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
391 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
392 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
393 // Same as YCbCr_420_SP_VENUS
394 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
395 break;
396
397 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
398 GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
399 break;
400
401 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
Rohit Kulkarnia152c312017-06-02 14:22:35 -0700402 if (!interlaced) {
403 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
404 } else {
405 GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
406 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700407 ycbcr->chroma_step = 2;
408 break;
409
410 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
411 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
412 ycbcr->chroma_step = 3;
413 break;
414
415 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
416 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
417 ycbcr->chroma_step = 4;
418 break;
419
420 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
421 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
422 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
423 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
424 case HAL_PIXEL_FORMAT_NV21_ZSL:
425 case HAL_PIXEL_FORMAT_RAW16:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530426 case HAL_PIXEL_FORMAT_Y16:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700427 case HAL_PIXEL_FORMAT_RAW10:
428 case HAL_PIXEL_FORMAT_RAW8:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530429 case HAL_PIXEL_FORMAT_Y8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700430 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
431 std::swap(ycbcr->cb, ycbcr->cr);
432 break;
433
434 // Planar
435 case HAL_PIXEL_FORMAT_YV12:
436 ystride = width;
437 cstride = ALIGN(width / 2, 16);
438 ycbcr->y = reinterpret_cast<void *>(hnd->base);
439 ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
440 ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
441 ycbcr->ystride = ystride;
442 ycbcr->cstride = cstride;
443 ycbcr->chroma_step = 1;
444 break;
Camus Wong5c5e6fb2017-03-21 17:02:48 -0400445 case HAL_PIXEL_FORMAT_CbYCrY_422_I:
446 ystride = width * 2;
447 cstride = 0;
448 ycbcr->y = reinterpret_cast<void *>(hnd->base);
449 ycbcr->cr = NULL;
450 ycbcr->cb = NULL;
451 ycbcr->ystride = ystride;
452 ycbcr->cstride = 0;
453 ycbcr->chroma_step = 0;
454 break;
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700455 // Unsupported formats
456 case HAL_PIXEL_FORMAT_YCbCr_422_I:
457 case HAL_PIXEL_FORMAT_YCrCb_422_I:
458 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
459 default:
460 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
461 err = -EINVAL;
462 }
463
464 return err;
465}
466
467// Explicitly defined UBWC formats
468bool IsUBwcFormat(int format) {
469 switch (format) {
470 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
471 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
472 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
473 return true;
474 default:
475 return false;
476 }
477}
478
479bool IsUBwcSupported(int format) {
480 // Existing HAL formats with UBWC support
481 switch (format) {
482 case HAL_PIXEL_FORMAT_BGR_565:
483 case HAL_PIXEL_FORMAT_RGBA_8888:
484 case HAL_PIXEL_FORMAT_RGBX_8888:
485 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
486 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
487 case HAL_PIXEL_FORMAT_RGBA_1010102:
488 case HAL_PIXEL_FORMAT_RGBX_1010102:
489 return true;
490 default:
491 break;
492 }
493
494 return false;
495}
496
497bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
498 gralloc1_consumer_usage_t cons_usage) {
499 // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
500 if (IsUBwcFormat(format)) {
501 return true;
502 }
503
504 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
505 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
506 // usage flag and MDP supports the format.
507 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
508 bool enable = true;
509 // Query GPU for UBWC only if buffer is intended to be used by GPU.
510 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
511 (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530512 if (AdrenoMemInfo::GetInstance()) {
513 enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
514 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700515 }
516
517 // Allow UBWC, only if CPU usage flags are not set
518 if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
519 return true;
520 }
521 }
522
523 return false;
524}
525
526void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
527 unsigned int *aligned_h) {
528 switch (format) {
529 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
530 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
531 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
532 *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
533 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
534 break;
535 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
536 // The macro returns the stride which is 4/3 times the width, hence * 3/4
537 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
538 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
539 break;
540 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
541 // The macro returns the stride which is 2 times the width, hence / 2
542 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
543 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
544 break;
545 default:
546 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
547 *aligned_w = 0;
548 *aligned_h = 0;
549 break;
550 }
551}
552
553void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
554 *block_width = 0;
555 *block_height = 0;
556
557 switch (bpp) {
558 case 2:
559 case 4:
560 *block_width = 16;
561 *block_height = 4;
562 break;
563 case 8:
564 *block_width = 8;
565 *block_height = 4;
566 break;
567 case 16:
568 *block_width = 4;
569 *block_height = 4;
570 break;
571 default:
572 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
573 break;
574 }
575}
576
577unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
578 unsigned int size = 0;
579 int meta_width, meta_height;
580 int block_width, block_height;
581
582 GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
583 if (!block_width || !block_height) {
584 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
585 return size;
586 }
587
588 // Align meta buffer height to 16 blocks
589 meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
590
591 // Align meta buffer width to 64 blocks
592 meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
593
594 // Align meta buffer size to 4K
595 size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
596
597 return size;
598}
599
600unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
601 unsigned int alignedh) {
602 unsigned int size = 0;
603 uint32_t bpp = 0;
604 switch (format) {
605 case HAL_PIXEL_FORMAT_BGR_565:
606 case HAL_PIXEL_FORMAT_RGBA_8888:
607 case HAL_PIXEL_FORMAT_RGBX_8888:
608 case HAL_PIXEL_FORMAT_RGBA_1010102:
609 case HAL_PIXEL_FORMAT_RGBX_1010102:
610 bpp = GetBppForUncompressedRGB(format);
611 size = alignedw * alignedh * bpp;
612 size += GetRgbUBwcMetaBufferSize(width, height, bpp);
613 break;
614 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
615 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
616 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
617 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
618 break;
619 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
620 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
621 break;
622 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
623 size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
624 break;
625 default:
626 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
627 break;
628 }
629
630 return size;
631}
632
633int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
634 int err = 0;
635
636 // This api is for RGB* formats
637 if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
638 return -EINVAL;
639 }
640
641 // linear buffer, nothing to do further
642 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
643 *rgb_data = reinterpret_cast<void *>(hnd->base);
644 return err;
645 }
646
647 unsigned int meta_size = 0;
648 uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
649 switch (hnd->format) {
650 case HAL_PIXEL_FORMAT_BGR_565:
651 case HAL_PIXEL_FORMAT_RGBA_8888:
652 case HAL_PIXEL_FORMAT_RGBX_8888:
653 case HAL_PIXEL_FORMAT_RGBA_1010102:
654 case HAL_PIXEL_FORMAT_RGBX_1010102:
655 meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
656 break;
657 default:
658 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
659 err = -EINVAL;
660 break;
661 }
662 *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
663
664 return err;
665}
666
667void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
668 unsigned int *alignedh) {
669 int width = info.width;
670 int height = info.height;
671 int format = info.format;
672 gralloc1_producer_usage_t prod_usage = info.prod_usage;
673 gralloc1_consumer_usage_t cons_usage = info.cons_usage;
674
675 // Currently surface padding is only computed for RGB* surfaces.
676 bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
677 int tile = ubwc_enabled;
678
679 if (IsUncompressedRGBFormat(format)) {
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530680 if (AdrenoMemInfo::GetInstance()) {
681 AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
682 alignedh);
683 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700684 return;
685 }
686
687 if (ubwc_enabled) {
688 GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
689 return;
690 }
691
692 if (IsCompressedRGBFormat(format)) {
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530693 if (AdrenoMemInfo::GetInstance()) {
694 AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
695 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700696 return;
697 }
698
699 int aligned_w = width;
700 int aligned_h = height;
701 unsigned int alignment = 32;
702
703 // Below should be only YUV family
704 switch (format) {
705 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
706 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
Pramodh Kumar Mukunda927729d2017-06-15 16:18:51 +0530707 if (AdrenoMemInfo::GetInstance() == nullptr) {
708 return;
709 }
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700710 alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
711 aligned_w = ALIGN(width, alignment);
712 break;
713 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
714 aligned_w = ALIGN(width, alignment);
715 break;
716 case HAL_PIXEL_FORMAT_RAW16:
Anjaneya Prasad Musunurib1654142017-04-18 10:32:42 +0530717 case HAL_PIXEL_FORMAT_Y16:
718 case HAL_PIXEL_FORMAT_Y8:
Saurabh Shah14c8e5b2017-04-07 10:37:23 -0700719 aligned_w = ALIGN(width, 16);
720 break;
721 case HAL_PIXEL_FORMAT_RAW12:
722 aligned_w = ALIGN(width * 12 / 8, 8);
723 break;
724 case HAL_PIXEL_FORMAT_RAW10:
725 aligned_w = ALIGN(width * 10 / 8, 8);
726 break;
727 case HAL_PIXEL_FORMAT_RAW8:
728 aligned_w = ALIGN(width, 8);
729 break;
730 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
731 aligned_w = ALIGN(width, 128);
732 break;
733 case HAL_PIXEL_FORMAT_YV12:
734 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
735 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
736 case HAL_PIXEL_FORMAT_YCbCr_422_I:
737 case HAL_PIXEL_FORMAT_YCrCb_422_I:
738 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
739 aligned_w = ALIGN(width, 16);
740 break;
741 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
742 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
743 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
744 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
745 break;
746 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
747 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
748 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
749 break;
750 case HAL_PIXEL_FORMAT_BLOB:
751 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
752 break;
753 case HAL_PIXEL_FORMAT_NV21_ZSL:
754 aligned_w = ALIGN(width, 64);
755 aligned_h = ALIGN(height, 64);
756 break;
757 default:
758 break;
759 }
760
761 *alignedw = (unsigned int)aligned_w;
762 *alignedh = (unsigned int)aligned_h;
763}
764
765int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4],
766 uint32_t offset[4], uint32_t *num_planes) {
767 if (!hnd || !stride || !offset || !num_planes) {
768 return -EINVAL;
769 }
770
771 struct android_ycbcr yuvInfo = {};
772 *num_planes = 1;
773 stride[0] = 0;
774
775 switch (hnd->format) {
776 case HAL_PIXEL_FORMAT_RGB_565:
777 case HAL_PIXEL_FORMAT_BGR_565:
778 case HAL_PIXEL_FORMAT_RGBA_5551:
779 case HAL_PIXEL_FORMAT_RGBA_4444:
780 stride[0] = static_cast<uint32_t>(hnd->width * 2);
781 break;
782 case HAL_PIXEL_FORMAT_RGB_888:
783 stride[0] = static_cast<uint32_t>(hnd->width * 3);
784 break;
785 case HAL_PIXEL_FORMAT_RGBA_8888:
786 case HAL_PIXEL_FORMAT_BGRA_8888:
787 case HAL_PIXEL_FORMAT_RGBX_8888:
788 case HAL_PIXEL_FORMAT_BGRX_8888:
789 case HAL_PIXEL_FORMAT_RGBA_1010102:
790 case HAL_PIXEL_FORMAT_ARGB_2101010:
791 case HAL_PIXEL_FORMAT_RGBX_1010102:
792 case HAL_PIXEL_FORMAT_XRGB_2101010:
793 case HAL_PIXEL_FORMAT_BGRA_1010102:
794 case HAL_PIXEL_FORMAT_ABGR_2101010:
795 case HAL_PIXEL_FORMAT_BGRX_1010102:
796 case HAL_PIXEL_FORMAT_XBGR_2101010:
797 stride[0] = static_cast<uint32_t>(hnd->width * 4);
798 break;
799 }
800
801 // Format is RGB
802 if (stride[0]) {
803 return 0;
804 }
805
806 (*num_planes)++;
807 int ret = GetYUVPlaneInfo(hnd, &yuvInfo);
808 if (ret < 0) {
809 ALOGE("%s failed", __FUNCTION__);
810 return ret;
811 }
812
813 stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
814 offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
815 stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
816 switch (hnd->format) {
817 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
818 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
819 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
820 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
821 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
822 case HAL_PIXEL_FORMAT_YCbCr_420_P010:
823 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
824 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
825 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
826 break;
827 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
828 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
829 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
830 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
831 break;
832 case HAL_PIXEL_FORMAT_YV12:
833 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
834 stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
835 offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
836 (*num_planes)++;
837 break;
838 default:
839 ALOGW("%s: Unsupported format", __FUNCTION__);
840 ret = -EINVAL;
841 }
842
843 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
844 std::fill(offset, offset + 4, 0);
845 }
846
847 return 0;
848}
849
Prabhanjan Kandula96e92342016-03-24 21:03:35 +0530850} // namespace gralloc1