1 /* 2 * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. 3 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 30 #include <media/msm_media_info.h> 31 #include <algorithm> 32 33 #include "gr_utils.h" 34 #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 42 43 namespace gralloc1 { 44 45 bool 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: 66 case HAL_PIXEL_FORMAT_RGBA_FP16: 67 case HAL_PIXEL_FORMAT_BGR_888: 68 return true; 69 default: 70 break; 71 } 72 73 return false; 74 } 75 76 bool 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 114 uint32_t GetBppForUncompressedRGB(int format) { 115 uint32_t bpp = 0; 116 switch (format) { 117 case HAL_PIXEL_FORMAT_RGBA_FP16: 118 bpp = 8; 119 break; 120 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: 124 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: 132 bpp = 4; 133 break; 134 case HAL_PIXEL_FORMAT_RGB_888: 135 case HAL_PIXEL_FORMAT_BGR_888: 136 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: 145 ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format); 146 break; 147 } 148 149 return bpp; 150 } 151 152 bool 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 156 bool 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 168 bool 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 177 unsigned 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 case HAL_PIXEL_FORMAT_Y16: 205 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: 212 case HAL_PIXEL_FORMAT_Y8: 213 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: 247 case HAL_PIXEL_FORMAT_CbYCrY_422_I: 248 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 280 void 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 286 void 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 314 void 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 336 void 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 349 int 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; 357 bool interlaced = false; 358 359 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); 360 361 // Check if UBWC buffer has been rendered in linear format. 362 int linear_format = 0; 363 if (getMetaData(const_cast<private_handle_t *>(hnd), 364 GET_LINEAR_FORMAT, &linear_format) == 0) { 365 format = INT(linear_format); 366 } 367 368 // Check metadata if the geometry has been updated. 369 BufferDim_t buffer_dim; 370 if (getMetaData(const_cast<private_handle_t *>(hnd), 371 GET_BUFFER_GEOMETRY, &buffer_dim) == 0) { 372 int usage = 0; 373 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 374 usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC; 375 } 376 377 BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format, 378 prod_usage, cons_usage); 379 GetAlignedWidthAndHeight(info, &width, &height); 380 } 381 382 // Check metadata for interlaced content. 383 int interlace_flag = 0; 384 if (getMetaData(const_cast<private_handle_t *>(hnd), 385 GET_PP_PARAM_INTERLACED, &interlace_flag) != 0) { 386 interlaced = interlace_flag; 387 } 388 389 // Get the chroma offsets from the handle width/height. We take advantage 390 // of the fact the width _is_ the stride 391 switch (format) { 392 // Semiplanar 393 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 394 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 395 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 396 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 397 // Same as YCbCr_420_SP_VENUS 398 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr); 399 break; 400 401 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 402 GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr); 403 break; 404 405 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 406 if (!interlaced) { 407 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr); 408 } else { 409 GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr); 410 } 411 ycbcr->chroma_step = 2; 412 break; 413 414 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 415 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr); 416 ycbcr->chroma_step = 3; 417 break; 418 419 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 420 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr); 421 ycbcr->chroma_step = 4; 422 break; 423 424 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 425 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 426 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 427 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 428 case HAL_PIXEL_FORMAT_NV21_ZSL: 429 case HAL_PIXEL_FORMAT_RAW16: 430 case HAL_PIXEL_FORMAT_Y16: 431 case HAL_PIXEL_FORMAT_RAW10: 432 case HAL_PIXEL_FORMAT_RAW8: 433 case HAL_PIXEL_FORMAT_Y8: 434 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr); 435 std::swap(ycbcr->cb, ycbcr->cr); 436 break; 437 438 // Planar 439 case HAL_PIXEL_FORMAT_YV12: 440 ystride = width; 441 cstride = ALIGN(width / 2, 16); 442 ycbcr->y = reinterpret_cast<void *>(hnd->base); 443 ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height); 444 ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2); 445 ycbcr->ystride = ystride; 446 ycbcr->cstride = cstride; 447 ycbcr->chroma_step = 1; 448 break; 449 case HAL_PIXEL_FORMAT_CbYCrY_422_I: 450 ystride = width * 2; 451 cstride = 0; 452 ycbcr->y = reinterpret_cast<void *>(hnd->base); 453 ycbcr->cr = NULL; 454 ycbcr->cb = NULL; 455 ycbcr->ystride = ystride; 456 ycbcr->cstride = 0; 457 ycbcr->chroma_step = 0; 458 break; 459 // Unsupported formats 460 case HAL_PIXEL_FORMAT_YCbCr_422_I: 461 case HAL_PIXEL_FORMAT_YCrCb_422_I: 462 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 463 default: 464 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format); 465 err = -EINVAL; 466 } 467 468 return err; 469 } 470 471 // Explicitly defined UBWC formats 472 bool IsUBwcFormat(int format) { 473 switch (format) { 474 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 475 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 476 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 477 return true; 478 default: 479 return false; 480 } 481 } 482 483 bool IsUBwcSupported(int format) { 484 // Existing HAL formats with UBWC support 485 switch (format) { 486 case HAL_PIXEL_FORMAT_BGR_565: 487 case HAL_PIXEL_FORMAT_RGBA_8888: 488 case HAL_PIXEL_FORMAT_RGBX_8888: 489 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 490 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 491 case HAL_PIXEL_FORMAT_RGBA_1010102: 492 case HAL_PIXEL_FORMAT_RGBX_1010102: 493 return true; 494 default: 495 break; 496 } 497 498 return false; 499 } 500 501 bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage, 502 gralloc1_consumer_usage_t cons_usage) { 503 // Allow UBWC, if client is using an explicitly defined UBWC pixel format. 504 if (IsUBwcFormat(format)) { 505 return true; 506 } 507 508 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP 509 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC 510 // usage flag and MDP supports the format. 511 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) { 512 bool enable = true; 513 // Query GPU for UBWC only if buffer is intended to be used by GPU. 514 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) || 515 (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) { 516 if (AdrenoMemInfo::GetInstance()) { 517 enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format); 518 } 519 } 520 521 // Allow UBWC, only if CPU usage flags are not set 522 if (enable && !(CpuCanAccess(prod_usage, cons_usage))) { 523 return true; 524 } 525 } 526 527 return false; 528 } 529 530 void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w, 531 unsigned int *aligned_h) { 532 switch (format) { 533 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 534 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 535 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 536 *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width); 537 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height); 538 break; 539 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 540 // The macro returns the stride which is 4/3 times the width, hence * 3/4 541 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4; 542 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height); 543 break; 544 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 545 // The macro returns the stride which is 2 times the width, hence / 2 546 *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2); 547 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height); 548 break; 549 default: 550 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); 551 *aligned_w = 0; 552 *aligned_h = 0; 553 break; 554 } 555 } 556 557 void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) { 558 *block_width = 0; 559 *block_height = 0; 560 561 switch (bpp) { 562 case 2: 563 case 4: 564 *block_width = 16; 565 *block_height = 4; 566 break; 567 case 8: 568 *block_width = 8; 569 *block_height = 4; 570 break; 571 case 16: 572 *block_width = 4; 573 *block_height = 4; 574 break; 575 default: 576 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); 577 break; 578 } 579 } 580 581 unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) { 582 unsigned int size = 0; 583 int meta_width, meta_height; 584 int block_width, block_height; 585 586 GetRgbUBwcBlockSize(bpp, &block_width, &block_height); 587 if (!block_width || !block_height) { 588 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); 589 return size; 590 } 591 592 // Align meta buffer height to 16 blocks 593 meta_height = ALIGN(((height + block_height - 1) / block_height), 16); 594 595 // Align meta buffer width to 64 blocks 596 meta_width = ALIGN(((width + block_width - 1) / block_width), 64); 597 598 // Align meta buffer size to 4K 599 size = (unsigned int)ALIGN((meta_width * meta_height), 4096); 600 601 return size; 602 } 603 604 unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw, 605 unsigned int alignedh) { 606 unsigned int size = 0; 607 uint32_t bpp = 0; 608 switch (format) { 609 case HAL_PIXEL_FORMAT_BGR_565: 610 case HAL_PIXEL_FORMAT_RGBA_8888: 611 case HAL_PIXEL_FORMAT_RGBX_8888: 612 case HAL_PIXEL_FORMAT_RGBA_1010102: 613 case HAL_PIXEL_FORMAT_RGBX_1010102: 614 bpp = GetBppForUncompressedRGB(format); 615 size = alignedw * alignedh * bpp; 616 size += GetRgbUBwcMetaBufferSize(width, height, bpp); 617 break; 618 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 619 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 620 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 621 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height); 622 break; 623 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 624 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height); 625 break; 626 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 627 size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height); 628 break; 629 default: 630 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); 631 break; 632 } 633 634 return size; 635 } 636 637 int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) { 638 int err = 0; 639 640 // This api is for RGB* formats 641 if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) { 642 return -EINVAL; 643 } 644 645 // linear buffer, nothing to do further 646 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) { 647 *rgb_data = reinterpret_cast<void *>(hnd->base); 648 return err; 649 } 650 651 unsigned int meta_size = 0; 652 uint32_t bpp = GetBppForUncompressedRGB(hnd->format); 653 switch (hnd->format) { 654 case HAL_PIXEL_FORMAT_BGR_565: 655 case HAL_PIXEL_FORMAT_RGBA_8888: 656 case HAL_PIXEL_FORMAT_RGBX_8888: 657 case HAL_PIXEL_FORMAT_RGBA_1010102: 658 case HAL_PIXEL_FORMAT_RGBX_1010102: 659 meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp); 660 break; 661 default: 662 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format); 663 err = -EINVAL; 664 break; 665 } 666 *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size); 667 668 return err; 669 } 670 671 void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw, 672 unsigned int *alignedh) { 673 int width = info.width; 674 int height = info.height; 675 int format = info.format; 676 gralloc1_producer_usage_t prod_usage = info.prod_usage; 677 gralloc1_consumer_usage_t cons_usage = info.cons_usage; 678 679 // Currently surface padding is only computed for RGB* surfaces. 680 bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage); 681 int tile = ubwc_enabled; 682 683 if (IsUncompressedRGBFormat(format)) { 684 if (AdrenoMemInfo::GetInstance()) { 685 AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw, 686 alignedh); 687 } 688 return; 689 } 690 691 if (ubwc_enabled) { 692 GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh); 693 return; 694 } 695 696 if (IsCompressedRGBFormat(format)) { 697 if (AdrenoMemInfo::GetInstance()) { 698 AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh); 699 } 700 return; 701 } 702 703 int aligned_w = width; 704 int aligned_h = height; 705 unsigned int alignment = 32; 706 707 // Below should be only YUV family 708 switch (format) { 709 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 710 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 711 if (AdrenoMemInfo::GetInstance() == nullptr) { 712 return; 713 } 714 alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment(); 715 aligned_w = ALIGN(width, alignment); 716 break; 717 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 718 aligned_w = ALIGN(width, alignment); 719 break; 720 case HAL_PIXEL_FORMAT_RAW16: 721 case HAL_PIXEL_FORMAT_Y16: 722 case HAL_PIXEL_FORMAT_Y8: 723 aligned_w = ALIGN(width, 16); 724 break; 725 case HAL_PIXEL_FORMAT_RAW12: 726 aligned_w = ALIGN(width * 12 / 8, 8); 727 break; 728 case HAL_PIXEL_FORMAT_RAW10: 729 aligned_w = ALIGN(width * 10 / 8, 8); 730 break; 731 case HAL_PIXEL_FORMAT_RAW8: 732 aligned_w = ALIGN(width, 8); 733 break; 734 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 735 aligned_w = ALIGN(width, 128); 736 break; 737 case HAL_PIXEL_FORMAT_YV12: 738 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 739 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 740 case HAL_PIXEL_FORMAT_YCbCr_422_I: 741 case HAL_PIXEL_FORMAT_YCrCb_422_I: 742 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 743 aligned_w = ALIGN(width, 16); 744 break; 745 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 746 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 747 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width)); 748 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height)); 749 break; 750 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 751 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width)); 752 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height)); 753 break; 754 case HAL_PIXEL_FORMAT_BLOB: 755 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 756 break; 757 case HAL_PIXEL_FORMAT_NV21_ZSL: 758 aligned_w = ALIGN(width, 64); 759 aligned_h = ALIGN(height, 64); 760 break; 761 default: 762 break; 763 } 764 765 *alignedw = (unsigned int)aligned_w; 766 *alignedh = (unsigned int)aligned_h; 767 } 768 769 int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4], 770 uint32_t offset[4], uint32_t *num_planes) { 771 if (!hnd || !stride || !offset || !num_planes) { 772 return -EINVAL; 773 } 774 775 struct android_ycbcr yuvInfo = {}; 776 *num_planes = 1; 777 stride[0] = 0; 778 779 switch (hnd->format) { 780 case HAL_PIXEL_FORMAT_RGB_565: 781 case HAL_PIXEL_FORMAT_BGR_565: 782 case HAL_PIXEL_FORMAT_RGBA_5551: 783 case HAL_PIXEL_FORMAT_RGBA_4444: 784 stride[0] = static_cast<uint32_t>(hnd->width * 2); 785 break; 786 case HAL_PIXEL_FORMAT_RGB_888: 787 stride[0] = static_cast<uint32_t>(hnd->width * 3); 788 break; 789 case HAL_PIXEL_FORMAT_RGBA_8888: 790 case HAL_PIXEL_FORMAT_BGRA_8888: 791 case HAL_PIXEL_FORMAT_RGBX_8888: 792 case HAL_PIXEL_FORMAT_BGRX_8888: 793 case HAL_PIXEL_FORMAT_RGBA_1010102: 794 case HAL_PIXEL_FORMAT_ARGB_2101010: 795 case HAL_PIXEL_FORMAT_RGBX_1010102: 796 case HAL_PIXEL_FORMAT_XRGB_2101010: 797 case HAL_PIXEL_FORMAT_BGRA_1010102: 798 case HAL_PIXEL_FORMAT_ABGR_2101010: 799 case HAL_PIXEL_FORMAT_BGRX_1010102: 800 case HAL_PIXEL_FORMAT_XBGR_2101010: 801 stride[0] = static_cast<uint32_t>(hnd->width * 4); 802 break; 803 } 804 805 // Format is RGB 806 if (stride[0]) { 807 return 0; 808 } 809 810 (*num_planes)++; 811 int ret = GetYUVPlaneInfo(hnd, &yuvInfo); 812 if (ret < 0) { 813 ALOGE("%s failed", __FUNCTION__); 814 return ret; 815 } 816 817 stride[0] = static_cast<uint32_t>(yuvInfo.ystride); 818 offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base); 819 stride[1] = static_cast<uint32_t>(yuvInfo.cstride); 820 switch (hnd->format) { 821 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 822 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 823 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 824 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 825 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 826 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 827 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 828 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 829 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base); 830 break; 831 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 832 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 833 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 834 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base); 835 break; 836 case HAL_PIXEL_FORMAT_YV12: 837 offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base); 838 stride[2] = static_cast<uint32_t>(yuvInfo.cstride); 839 offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base); 840 (*num_planes)++; 841 break; 842 default: 843 ALOGW("%s: Unsupported format", __FUNCTION__); 844 ret = -EINVAL; 845 } 846 847 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 848 std::fill(offset, offset + 4, 0); 849 } 850 851 return 0; 852 } 853 854 } // namespace gralloc1 855