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 <cutils/log.h> 31 #include <fcntl.h> 32 #include <dlfcn.h> 33 #include <media/msm_media_info.h> 34 #include <qdMetaData.h> 35 #include <utils/Singleton.h> 36 #include <utils/Mutex.h> 37 #include <algorithm> 38 39 #include "gralloc_priv.h" 40 #include "alloc_controller.h" 41 #include "memalloc.h" 42 #include "ionalloc.h" 43 #include "gr.h" 44 #include "qd_utils.h" 45 46 #define ASTC_BLOCK_SIZE 16 47 48 #ifndef ION_FLAG_CP_PIXEL 49 #define ION_FLAG_CP_PIXEL 0 50 #endif 51 52 #ifndef ION_FLAG_ALLOW_NON_CONTIG 53 #define ION_FLAG_ALLOW_NON_CONTIG 0 54 #endif 55 56 #ifndef ION_FLAG_CP_CAMERA_PREVIEW 57 #define ION_FLAG_CP_CAMERA_PREVIEW 0 58 #endif 59 60 #ifdef MASTER_SIDE_CP 61 #define CP_HEAP_ID ION_SECURE_HEAP_ID 62 #define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID 63 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL) 64 #define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY) 65 #define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA) 66 #define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW) 67 #else // SLAVE_SIDE_CP 68 #define CP_HEAP_ID ION_CP_MM_HEAP_ID 69 #define SD_HEAP_ID CP_HEAP_ID 70 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG) 71 #define ION_SD_FLAGS ION_SECURE 72 #define ION_SC_FLAGS ION_SECURE 73 #define ION_SC_PREVIEW_FLAGS ION_SECURE 74 #endif 75 76 #ifndef COLOR_FMT_P010_UBWC 77 #define COLOR_FMT_P010_UBWC 9 78 #endif 79 80 using namespace gralloc; 81 using namespace qdutils; 82 using namespace android; 83 84 ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo); 85 ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo); 86 87 static void getYuvUBwcWidthHeight(int, int, int, int&, int&); 88 static unsigned int getUBwcSize(int, int, int, const int, const int); 89 90 //Common functions 91 92 /* The default policy is to return cached buffers unless the client explicity 93 * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely 94 * read or written in software. Any combination with a _RARELY_ flag will be 95 * treated as uncached. */ 96 static bool useUncached(const int& usage) { 97 if ((usage & GRALLOC_USAGE_PROTECTED) or 98 (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or 99 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or 100 ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY)) 101 return true; 102 103 return false; 104 } 105 106 //------------- MDPCapabilityInfo-----------------------// 107 MDPCapabilityInfo :: MDPCapabilityInfo() { 108 qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported); 109 qdutils::querySDEInfo(HAS_WB_UBWC, &isWBUBWCSupported); 110 } 111 112 //------------- AdrenoMemInfo-----------------------// 113 AdrenoMemInfo::AdrenoMemInfo() 114 { 115 LINK_adreno_compute_aligned_width_and_height = NULL; 116 LINK_adreno_compute_padding = NULL; 117 LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL; 118 LINK_adreno_isUBWCSupportedByGpu = NULL; 119 LINK_adreno_get_gpu_pixel_alignment = NULL; 120 121 libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW); 122 if (libadreno_utils) { 123 *(void **)&LINK_adreno_compute_aligned_width_and_height = 124 ::dlsym(libadreno_utils, "compute_aligned_width_and_height"); 125 *(void **)&LINK_adreno_compute_padding = 126 ::dlsym(libadreno_utils, "compute_surface_padding"); 127 *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height = 128 ::dlsym(libadreno_utils, 129 "compute_compressedfmt_aligned_width_and_height"); 130 *(void **)&LINK_adreno_isUBWCSupportedByGpu = 131 ::dlsym(libadreno_utils, "isUBWCSupportedByGpu"); 132 *(void **)&LINK_adreno_get_gpu_pixel_alignment = 133 ::dlsym(libadreno_utils, "get_gpu_pixel_alignment"); 134 } 135 136 // Check if the overriding property debug.gralloc.gfx_ubwc_disable 137 // that disables UBWC allocations for the graphics stack is set 138 gfx_ubwc_disable = 0; 139 char property[PROPERTY_VALUE_MAX]; 140 property_get("debug.gralloc.gfx_ubwc_disable", property, "0"); 141 if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) || 142 !(strncmp(property, "true", PROPERTY_VALUE_MAX))) { 143 gfx_ubwc_disable = 1; 144 } 145 } 146 147 AdrenoMemInfo::~AdrenoMemInfo() 148 { 149 if (libadreno_utils) { 150 ::dlclose(libadreno_utils); 151 } 152 } 153 154 void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w, 155 int& aligned_h) { 156 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 157 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { 158 int w = metadata->bufferDim.sliceWidth; 159 int h = metadata->bufferDim.sliceHeight; 160 int f = hnd->format; 161 int usage = 0; 162 163 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 164 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 165 } 166 167 getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h); 168 } else { 169 aligned_w = hnd->width; 170 aligned_h = hnd->height; 171 } 172 173 } 174 175 void AdrenoMemInfo::getUnalignedWidthAndHeight(const private_handle_t *hnd, int& unaligned_w, 176 int& unaligned_h) { 177 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 178 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { 179 unaligned_w = metadata->bufferDim.sliceWidth; 180 unaligned_h = metadata->bufferDim.sliceHeight; 181 } else { 182 unaligned_w = hnd->unaligned_width; 183 unaligned_h = hnd->unaligned_height; 184 } 185 } 186 187 bool isUncompressedRgbFormat(int format) 188 { 189 bool is_rgb_format = false; 190 191 switch (format) 192 { 193 case HAL_PIXEL_FORMAT_RGBA_8888: 194 case HAL_PIXEL_FORMAT_RGBX_8888: 195 case HAL_PIXEL_FORMAT_RGB_888: 196 case HAL_PIXEL_FORMAT_RGB_565: 197 case HAL_PIXEL_FORMAT_BGR_565: 198 case HAL_PIXEL_FORMAT_BGRA_8888: 199 case HAL_PIXEL_FORMAT_RGBA_5551: 200 case HAL_PIXEL_FORMAT_RGBA_4444: 201 case HAL_PIXEL_FORMAT_R_8: 202 case HAL_PIXEL_FORMAT_RG_88: 203 case HAL_PIXEL_FORMAT_BGRX_8888: 204 case HAL_PIXEL_FORMAT_BGR_888: 205 case HAL_PIXEL_FORMAT_RGBA_1010102: 206 case HAL_PIXEL_FORMAT_ARGB_2101010: 207 case HAL_PIXEL_FORMAT_RGBX_1010102: 208 case HAL_PIXEL_FORMAT_XRGB_2101010: 209 case HAL_PIXEL_FORMAT_BGRA_1010102: 210 case HAL_PIXEL_FORMAT_ABGR_2101010: 211 case HAL_PIXEL_FORMAT_BGRX_1010102: 212 case HAL_PIXEL_FORMAT_XBGR_2101010: // Intentional fallthrough 213 is_rgb_format = true; 214 break; 215 default: 216 break; 217 } 218 219 return is_rgb_format; 220 } 221 222 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format, 223 int usage, int& aligned_w, int& aligned_h) 224 { 225 bool ubwc_enabled = isUBwcEnabled(format, usage); 226 227 // Currently surface padding is only computed for RGB* surfaces. 228 if (isUncompressedRgbFormat(format) == true) { 229 int tileEnabled = ubwc_enabled; 230 getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h); 231 } else if (ubwc_enabled) { 232 getYuvUBwcWidthHeight(width, height, format, aligned_w, aligned_h); 233 } else { 234 aligned_w = width; 235 aligned_h = height; 236 int alignment = 32; 237 switch (format) 238 { 239 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 240 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 241 if (LINK_adreno_get_gpu_pixel_alignment) { 242 alignment = LINK_adreno_get_gpu_pixel_alignment(); 243 } 244 aligned_w = ALIGN(width, alignment); 245 break; 246 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 247 aligned_w = ALIGN(width, alignment); 248 break; 249 case HAL_PIXEL_FORMAT_RAW16: 250 case HAL_PIXEL_FORMAT_Y16: 251 case HAL_PIXEL_FORMAT_Y8: 252 aligned_w = ALIGN(width, 16); 253 break; 254 case HAL_PIXEL_FORMAT_RAW12: 255 aligned_w = ALIGN(width * 12 / 8, 8); 256 break; 257 case HAL_PIXEL_FORMAT_RAW10: 258 aligned_w = ALIGN(width * 10 / 8, 8); 259 break; 260 case HAL_PIXEL_FORMAT_RAW8: 261 aligned_w = ALIGN(width, 8); 262 break; 263 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 264 aligned_w = ALIGN(width, 128); 265 break; 266 case HAL_PIXEL_FORMAT_YV12: 267 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 268 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 269 case HAL_PIXEL_FORMAT_YCbCr_422_I: 270 case HAL_PIXEL_FORMAT_YCrCb_422_I: 271 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 272 case HAL_PIXEL_FORMAT_CbYCrY_422_I: 273 aligned_w = ALIGN(width, 16); 274 break; 275 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 276 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 277 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width); 278 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height); 279 break; 280 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 281 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width); 282 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height); 283 break; 284 case HAL_PIXEL_FORMAT_BLOB: 285 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 286 break; 287 case HAL_PIXEL_FORMAT_NV21_ZSL: 288 aligned_w = ALIGN(width, 64); 289 aligned_h = ALIGN(height, 64); 290 break; 291 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR: 292 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: 293 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR: 294 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: 295 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR: 296 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: 297 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR: 298 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: 299 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR: 300 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: 301 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR: 302 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: 303 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR: 304 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: 305 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR: 306 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: 307 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR: 308 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: 309 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR: 310 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: 311 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR: 312 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: 313 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR: 314 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: 315 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR: 316 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: 317 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR: 318 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: 319 if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) { 320 int bytesPerPixel = 0; 321 int raster_mode = 0; //Adreno unknown raster mode. 322 int padding_threshold = 512; //Threshold for padding 323 //surfaces. 324 325 LINK_adreno_compute_compressedfmt_aligned_width_and_height( 326 width, height, format, 0,raster_mode, padding_threshold, 327 &aligned_w, &aligned_h, &bytesPerPixel); 328 } else { 329 ALOGW("%s: Warning!! Symbols" \ 330 " compute_compressedfmt_aligned_width_and_height" \ 331 " not found", __FUNCTION__); 332 } 333 break; 334 default: break; 335 } 336 } 337 } 338 339 void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format, 340 int tile_enabled, int& aligned_w, int& aligned_h) 341 { 342 aligned_w = ALIGN(width, 32); 343 aligned_h = ALIGN(height, 32); 344 345 // Don't add any additional padding if debug.gralloc.map_fb_memory 346 // is enabled 347 char property[PROPERTY_VALUE_MAX]; 348 if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) && 349 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || 350 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { 351 return; 352 } 353 354 int bpp = 4; 355 switch(format) 356 { 357 case HAL_PIXEL_FORMAT_RGB_888: 358 bpp = 3; 359 break; 360 case HAL_PIXEL_FORMAT_RGB_565: 361 case HAL_PIXEL_FORMAT_BGR_565: 362 case HAL_PIXEL_FORMAT_RGBA_5551: 363 case HAL_PIXEL_FORMAT_RGBA_4444: 364 bpp = 2; 365 break; 366 default: break; 367 } 368 369 if (libadreno_utils) { 370 int raster_mode = 0; // Adreno unknown raster mode. 371 int padding_threshold = 512; // Threshold for padding surfaces. 372 // the function below computes aligned width and aligned height 373 // based on linear or macro tile mode selected. 374 if(LINK_adreno_compute_aligned_width_and_height) { 375 LINK_adreno_compute_aligned_width_and_height(width, 376 height, bpp, tile_enabled, 377 raster_mode, padding_threshold, 378 &aligned_w, &aligned_h); 379 380 } else if(LINK_adreno_compute_padding) { 381 int surface_tile_height = 1; // Linear surface 382 aligned_w = LINK_adreno_compute_padding(width, bpp, 383 surface_tile_height, raster_mode, 384 padding_threshold); 385 ALOGW("%s: Warning!! Old GFX API is used to calculate stride", 386 __FUNCTION__); 387 } else { 388 ALOGW("%s: Warning!! Symbols compute_surface_padding and " \ 389 "compute_aligned_width_and_height not found", __FUNCTION__); 390 } 391 } 392 } 393 394 int AdrenoMemInfo::isUBWCSupportedByGPU(int format) 395 { 396 if (!gfx_ubwc_disable && libadreno_utils) { 397 if (LINK_adreno_isUBWCSupportedByGpu) { 398 ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format); 399 return LINK_adreno_isUBWCSupportedByGpu(gpu_format); 400 } 401 } 402 return 0; 403 } 404 405 ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format) 406 { 407 switch (hal_format) { 408 case HAL_PIXEL_FORMAT_RGBA_8888: 409 return ADRENO_PIXELFORMAT_R8G8B8A8; 410 case HAL_PIXEL_FORMAT_RGBX_8888: 411 return ADRENO_PIXELFORMAT_R8G8B8X8; 412 case HAL_PIXEL_FORMAT_RGB_565: 413 return ADRENO_PIXELFORMAT_B5G6R5; 414 case HAL_PIXEL_FORMAT_BGR_565: 415 return ADRENO_PIXELFORMAT_R5G6B5; 416 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 417 return ADRENO_PIXELFORMAT_NV12; 418 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 419 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 420 return ADRENO_PIXELFORMAT_NV12_EXT; 421 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 422 return ADRENO_PIXELFORMAT_TP10; 423 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 424 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 425 return ADRENO_PIXELFORMAT_P010; 426 case HAL_PIXEL_FORMAT_RGBA_1010102: 427 return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM; 428 case HAL_PIXEL_FORMAT_RGBX_1010102: 429 return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM; 430 case HAL_PIXEL_FORMAT_ABGR_2101010: 431 return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM; 432 default: 433 ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format); 434 break; 435 } 436 return ADRENO_PIXELFORMAT_UNKNOWN; 437 } 438 439 //-------------- IAllocController-----------------------// 440 IAllocController* IAllocController::sController = NULL; 441 IAllocController* IAllocController::getInstance(void) 442 { 443 if(sController == NULL) { 444 sController = new IonController(); 445 } 446 return sController; 447 } 448 449 450 //-------------- IonController-----------------------// 451 IonController::IonController() 452 { 453 allocateIonMem(); 454 455 char property[PROPERTY_VALUE_MAX]; 456 property_get("video.disable.ubwc", property, "0"); 457 mDisableUBWCForEncode = atoi(property); 458 } 459 460 void IonController::allocateIonMem() 461 { 462 mIonAlloc = new IonAlloc(); 463 } 464 465 int IonController::allocate(alloc_data& data, int usage) 466 { 467 int ionFlags = 0; 468 int ionHeapId = 0; 469 int ret; 470 471 data.uncached = useUncached(usage); 472 data.allocType = 0; 473 474 if(usage & GRALLOC_USAGE_PROTECTED) { 475 if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) { 476 ionHeapId = ION_HEAP(SD_HEAP_ID); 477 /* 478 * There is currently no flag in ION for Secure Display 479 * VM. Please add it to the define once available. 480 */ 481 ionFlags |= ION_SD_FLAGS; 482 } else if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) { 483 ionHeapId = ION_HEAP(SD_HEAP_ID); 484 ionFlags |= (usage & GRALLOC_USAGE_HW_COMPOSER) ? ION_SC_PREVIEW_FLAGS : ION_SC_FLAGS; 485 } else { 486 ionHeapId = ION_HEAP(CP_HEAP_ID); 487 ionFlags |= ION_CP_FLAGS; 488 } 489 } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) { 490 //MM Heap is exclusively a secure heap. 491 //If it is used for non secure cases, fallback to IOMMU heap 492 ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \ 493 cannot be used as an insecure heap!\ 494 trying to use system heap instead !!"); 495 ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID); 496 } 497 498 if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP) 499 ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID); 500 501 if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) 502 ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID); 503 504 if(ionFlags & ION_SECURE) 505 data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER; 506 507 // if no ion heap flags are set, default to system heap 508 if(!ionHeapId) 509 ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID); 510 511 //At this point we should have the right heap set, there is no fallback 512 data.flags = ionFlags; 513 data.heapId = ionHeapId; 514 ret = mIonAlloc->alloc_buffer(data); 515 516 if(ret >= 0 ) { 517 data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION; 518 } else { 519 ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", 520 __FUNCTION__, ionHeapId, ionFlags); 521 } 522 523 return ret; 524 } 525 526 IMemAlloc* IonController::getAllocator(int flags) 527 { 528 IMemAlloc* memalloc = NULL; 529 if (flags & private_handle_t::PRIV_FLAGS_USES_ION) { 530 memalloc = mIonAlloc; 531 } else { 532 ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags); 533 } 534 535 return memalloc; 536 } 537 538 // helper function 539 unsigned int getSize(int format, int width, int height, int usage, 540 const int alignedw, const int alignedh) { 541 542 if (isUBwcEnabled(format, usage)) { 543 return getUBwcSize(width, height, format, alignedw, alignedh); 544 } 545 546 unsigned int size = 0; 547 switch (format) { 548 case HAL_PIXEL_FORMAT_RGBA_8888: 549 case HAL_PIXEL_FORMAT_RGBX_8888: 550 case HAL_PIXEL_FORMAT_BGRA_8888: 551 case HAL_PIXEL_FORMAT_RGBA_1010102: 552 case HAL_PIXEL_FORMAT_ARGB_2101010: 553 case HAL_PIXEL_FORMAT_RGBX_1010102: 554 case HAL_PIXEL_FORMAT_XRGB_2101010: 555 case HAL_PIXEL_FORMAT_BGRA_1010102: 556 case HAL_PIXEL_FORMAT_ABGR_2101010: 557 case HAL_PIXEL_FORMAT_BGRX_1010102: 558 case HAL_PIXEL_FORMAT_XBGR_2101010: 559 size = alignedw * alignedh * 4; 560 break; 561 case HAL_PIXEL_FORMAT_RGB_888: 562 size = alignedw * alignedh * 3; 563 break; 564 case HAL_PIXEL_FORMAT_RGB_565: 565 case HAL_PIXEL_FORMAT_BGR_565: 566 case HAL_PIXEL_FORMAT_RGBA_5551: 567 case HAL_PIXEL_FORMAT_RGBA_4444: 568 case HAL_PIXEL_FORMAT_RAW16: 569 case HAL_PIXEL_FORMAT_Y16: 570 size = alignedw * alignedh * 2; 571 break; 572 case HAL_PIXEL_FORMAT_RAW12: 573 size = ALIGN(alignedw * alignedh, 4096); 574 break; 575 case HAL_PIXEL_FORMAT_RAW10: 576 size = ALIGN(alignedw * alignedh, 4096); 577 break; 578 case HAL_PIXEL_FORMAT_RAW8: 579 case HAL_PIXEL_FORMAT_Y8: 580 size = alignedw * alignedh; 581 break; 582 // adreno formats 583 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21 584 size = ALIGN(alignedw*alignedh, 4096); 585 size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096); 586 break; 587 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12 588 // The chroma plane is subsampled, 589 // but the pitch in bytes is unchanged 590 // The GPU needs 4K alignment, but the video decoder needs 8K 591 size = ALIGN( alignedw * alignedh, 8192); 592 size += ALIGN( alignedw * ALIGN(height/2, 32), 8192); 593 break; 594 case HAL_PIXEL_FORMAT_YV12: 595 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) { 596 ALOGE("w or h is odd for the YV12 format"); 597 return 0; 598 } 599 size = alignedw*alignedh + 600 (ALIGN(alignedw/2, 16) * (alignedh/2))*2; 601 size = ALIGN(size, (unsigned int)4096); 602 break; 603 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 604 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 605 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096); 606 break; 607 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 608 size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, 4096); 609 break; 610 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 611 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 612 case HAL_PIXEL_FORMAT_YCbCr_422_I: 613 case HAL_PIXEL_FORMAT_YCrCb_422_I: 614 case HAL_PIXEL_FORMAT_CbYCrY_422_I: 615 if(width & 1) { 616 ALOGE("width is odd for the YUV422_SP format"); 617 return 0; 618 } 619 size = ALIGN(alignedw * alignedh * 2, 4096); 620 break; 621 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 622 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 623 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height); 624 break; 625 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 626 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height); 627 break; 628 case HAL_PIXEL_FORMAT_BLOB: 629 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 630 if(height != 1) { 631 ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \ 632 must have height==1 ", __FUNCTION__); 633 return 0; 634 } 635 size = width; 636 break; 637 case HAL_PIXEL_FORMAT_NV21_ZSL: 638 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096); 639 break; 640 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR: 641 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR: 642 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR: 643 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR: 644 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR: 645 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR: 646 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR: 647 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR: 648 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR: 649 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR: 650 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR: 651 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR: 652 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR: 653 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR: 654 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: 655 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: 656 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: 657 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: 658 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: 659 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: 660 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: 661 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: 662 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: 663 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: 664 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: 665 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: 666 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: 667 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: 668 size = alignedw * alignedh * ASTC_BLOCK_SIZE; 669 break; 670 default: 671 ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format); 672 return 0; 673 } 674 return size; 675 } 676 677 unsigned int getBufferSizeAndDimensions(int width, int height, int format, 678 int& alignedw, int &alignedh) 679 { 680 unsigned int size; 681 682 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, 683 height, 684 format, 685 0, 686 alignedw, 687 alignedh); 688 689 size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh); 690 691 return size; 692 } 693 694 695 unsigned int getBufferSizeAndDimensions(int width, int height, int format, 696 int usage, int& alignedw, int &alignedh) 697 { 698 unsigned int size; 699 700 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, 701 height, 702 format, 703 usage, 704 alignedw, 705 alignedh); 706 707 size = getSize(format, width, height, usage, alignedw, alignedh); 708 709 return size; 710 } 711 712 void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int height, 713 int color_format, struct android_ycbcr* ycbcr) 714 { 715 // UBWC buffer has these 4 planes in the following sequence: 716 // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane 717 unsigned int y_meta_stride, y_meta_height, y_meta_size; 718 unsigned int y_stride, y_height, y_size; 719 unsigned int c_meta_stride, c_meta_height, c_meta_size; 720 unsigned int alignment = 4096; 721 722 y_meta_stride = VENUS_Y_META_STRIDE(color_format, width); 723 y_meta_height = VENUS_Y_META_SCANLINES(color_format, height); 724 y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment); 725 726 y_stride = VENUS_Y_STRIDE(color_format, width); 727 y_height = VENUS_Y_SCANLINES(color_format, height); 728 y_size = ALIGN((y_stride * y_height), alignment); 729 730 c_meta_stride = VENUS_UV_META_STRIDE(color_format, width); 731 c_meta_height = VENUS_UV_META_SCANLINES(color_format, height); 732 c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment); 733 734 ycbcr->y = (void*)(base + y_meta_size); 735 ycbcr->cb = (void*)(base + y_meta_size + y_size + c_meta_size); 736 ycbcr->cr = (void*)(base + y_meta_size + y_size + 737 c_meta_size + 1); 738 ycbcr->ystride = y_stride; 739 ycbcr->cstride = VENUS_UV_STRIDE(color_format, width); 740 } 741 742 void getYuvSPPlaneInfo(uint64_t base, int width, int height, int bpp, 743 struct android_ycbcr* ycbcr) 744 { 745 unsigned int ystride, cstride; 746 747 ystride = cstride = width * bpp; 748 ycbcr->y = (void*)base; 749 ycbcr->cb = (void*)(base + ystride * height); 750 ycbcr->cr = (void*)(base + ystride * height + 1); 751 ycbcr->ystride = ystride; 752 ycbcr->cstride = cstride; 753 ycbcr->chroma_step = 2 * bpp; 754 } 755 756 int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr) 757 { 758 int err = 0; 759 int width = hnd->width; 760 int height = hnd->height; 761 int format = hnd->format; 762 763 unsigned int ystride, cstride; 764 765 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); 766 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata; 767 768 // Check if UBWC buffer has been rendered in linear format. 769 if (metadata && (metadata->operation & LINEAR_FORMAT)) { 770 format = metadata->linearFormat; 771 } 772 773 // Check metadata if the geometry has been updated. 774 if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { 775 int usage = 0; 776 777 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 778 usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC; 779 } 780 781 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth, 782 metadata->bufferDim.sliceHeight, format, usage, width, height); 783 } 784 785 // Get the chroma offsets from the handle width/height. We take advantage 786 // of the fact the width _is_ the stride 787 switch (format) { 788 //Semiplanar 789 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 790 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 791 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 792 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS 793 getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr); 794 break; 795 796 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 797 getYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr); 798 break; 799 800 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 801 getYuvUbwcSPPlaneInfo(hnd->base, width, height, 802 COLOR_FMT_NV12_UBWC, ycbcr); 803 ycbcr->chroma_step = 2; 804 break; 805 806 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 807 getYuvUbwcSPPlaneInfo(hnd->base, width, height, 808 COLOR_FMT_NV12_BPP10_UBWC, ycbcr); 809 ycbcr->chroma_step = 3; 810 break; 811 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 812 getYuvUbwcSPPlaneInfo(hnd->base, width, height, 813 COLOR_FMT_P010_UBWC, ycbcr); 814 ycbcr->chroma_step = 4; 815 break; 816 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 817 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 818 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 819 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 820 case HAL_PIXEL_FORMAT_NV21_ZSL: 821 case HAL_PIXEL_FORMAT_RAW16: 822 case HAL_PIXEL_FORMAT_Y16: 823 case HAL_PIXEL_FORMAT_RAW12: 824 case HAL_PIXEL_FORMAT_RAW10: 825 case HAL_PIXEL_FORMAT_RAW8: 826 case HAL_PIXEL_FORMAT_Y8: 827 getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr); 828 std::swap(ycbcr->cb, ycbcr->cr); 829 break; 830 831 //Planar 832 case HAL_PIXEL_FORMAT_YV12: 833 ystride = width; 834 cstride = ALIGN(width/2, 16); 835 ycbcr->y = (void*)hnd->base; 836 ycbcr->cr = (void*)(hnd->base + ystride * height); 837 ycbcr->cb = (void*)(hnd->base + ystride * height + 838 cstride * height/2); 839 ycbcr->ystride = ystride; 840 ycbcr->cstride = cstride; 841 ycbcr->chroma_step = 1; 842 break; 843 case HAL_PIXEL_FORMAT_CbYCrY_422_I: 844 ystride = width * 2; 845 cstride = 0; 846 ycbcr->y = (void*)hnd->base; 847 ycbcr->cr = NULL; 848 ycbcr->cb = NULL; 849 ycbcr->ystride = ystride; 850 ycbcr->cstride = 0; 851 ycbcr->chroma_step = 0; 852 break; 853 //Unsupported formats 854 case HAL_PIXEL_FORMAT_YCbCr_422_I: 855 case HAL_PIXEL_FORMAT_YCrCb_422_I: 856 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 857 default: 858 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format); 859 err = -EINVAL; 860 } 861 return err; 862 863 } 864 865 866 867 // Allocate buffer from width, height and format into a 868 // private_handle_t. It is the responsibility of the caller 869 // to free the buffer using the free_buffer function 870 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage) 871 { 872 alloc_data data; 873 int alignedw, alignedh; 874 gralloc::IAllocController* sAlloc = 875 gralloc::IAllocController::getInstance(); 876 data.base = 0; 877 data.fd = -1; 878 data.offset = 0; 879 data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw, 880 alignedh); 881 882 data.align = getpagesize(); 883 data.uncached = useUncached(usage); 884 int allocFlags = usage; 885 886 int err = sAlloc->allocate(data, allocFlags); 887 if (0 != err) { 888 ALOGE("%s: allocate failed", __FUNCTION__); 889 return -ENOMEM; 890 } 891 892 if(isUBwcEnabled(format, usage)) { 893 data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 894 } 895 896 private_handle_t* hnd = new private_handle_t(data.fd, data.size, 897 data.allocType, 0, format, 898 alignedw, alignedh, -1, 0, 0, w, h); 899 hnd->base = (uint64_t) data.base; 900 hnd->offset = data.offset; 901 hnd->gpuaddr = 0; 902 *pHnd = hnd; 903 return 0; 904 } 905 906 void free_buffer(private_handle_t *hnd) 907 { 908 gralloc::IAllocController* sAlloc = 909 gralloc::IAllocController::getInstance(); 910 if (hnd && hnd->fd > 0) { 911 IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags); 912 memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd); 913 } 914 if(hnd) 915 delete hnd; 916 917 } 918 919 // UBWC helper functions 920 static bool isUBwcFormat(int format) 921 { 922 // Explicitly defined UBWC formats 923 switch(format) 924 { 925 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 926 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 927 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 928 return true; 929 default: 930 return false; 931 } 932 } 933 934 static bool isUBwcSupported(int format) 935 { 936 if (MDPCapabilityInfo::getInstance().isUBwcSupportedByMDP()) { 937 // Existing HAL formats with UBWC support 938 switch(format) 939 { 940 case HAL_PIXEL_FORMAT_BGR_565: 941 case HAL_PIXEL_FORMAT_RGBA_8888: 942 case HAL_PIXEL_FORMAT_RGBX_8888: 943 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 944 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 945 case HAL_PIXEL_FORMAT_RGBA_1010102: 946 case HAL_PIXEL_FORMAT_RGBX_1010102: 947 return true; 948 default: 949 break; 950 } 951 } 952 return false; 953 } 954 955 bool isUBwcEnabled(int format, int usage) 956 { 957 // Allow UBWC, if client is using an explicitly defined UBWC pixel format. 958 if (isUBwcFormat(format)) 959 return true; 960 961 if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && 962 gralloc::IAllocController::getInstance()->isDisableUBWCForEncoder()) { 963 return false; 964 } 965 966 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP 967 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC 968 // usage flag and MDP supports the format. 969 if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) { 970 bool enable = true; 971 // Query GPU for UBWC only if buffer is intended to be used by GPU. 972 if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) { 973 enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format); 974 } 975 // Allow UBWC, only if CPU usage flags are not set 976 if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK | 977 GRALLOC_USAGE_SW_WRITE_MASK))) { 978 return true; 979 } 980 } 981 return false; 982 } 983 984 static void getYuvUBwcWidthHeight(int width, int height, int format, 985 int& aligned_w, int& aligned_h) 986 { 987 switch (format) 988 { 989 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 990 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 991 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 992 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width); 993 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height); 994 break; 995 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 996 // The macro returns the stride which is 4/3 times the width, hence * 3/4 997 aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4; 998 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height); 999 break; 1000 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 1001 // The macro returns the stride which is 2 times the width, hence / 2 1002 aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2); 1003 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height); 1004 break; 1005 default: 1006 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); 1007 aligned_w = 0; 1008 aligned_h = 0; 1009 break; 1010 } 1011 } 1012 1013 static void getRgbUBwcBlockSize(int bpp, int& block_width, int& block_height) 1014 { 1015 block_width = 0; 1016 block_height = 0; 1017 1018 switch(bpp) 1019 { 1020 case 2: 1021 case 4: 1022 block_width = 16; 1023 block_height = 4; 1024 break; 1025 case 8: 1026 block_width = 8; 1027 block_height = 4; 1028 break; 1029 case 16: 1030 block_width = 4; 1031 block_height = 4; 1032 break; 1033 default: 1034 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); 1035 break; 1036 } 1037 } 1038 1039 static unsigned int getRgbUBwcMetaBufferSize(int width, int height, int bpp) 1040 { 1041 unsigned int size = 0; 1042 int meta_width, meta_height; 1043 int block_width, block_height; 1044 1045 getRgbUBwcBlockSize(bpp, block_width, block_height); 1046 1047 if (!block_width || !block_height) { 1048 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); 1049 return size; 1050 } 1051 1052 // Align meta buffer height to 16 blocks 1053 meta_height = ALIGN(((height + block_height - 1) / block_height), 16); 1054 1055 // Align meta buffer width to 64 blocks 1056 meta_width = ALIGN(((width + block_width - 1) / block_width), 64); 1057 1058 // Align meta buffer size to 4K 1059 size = ALIGN((meta_width * meta_height), 4096); 1060 return size; 1061 } 1062 1063 static unsigned int getUBwcSize(int width, int height, int format, 1064 const int alignedw, const int alignedh) { 1065 1066 unsigned int size = 0; 1067 switch (format) { 1068 case HAL_PIXEL_FORMAT_BGR_565: 1069 size = alignedw * alignedh * 2; 1070 size += getRgbUBwcMetaBufferSize(width, height, 2); 1071 break; 1072 case HAL_PIXEL_FORMAT_RGBA_8888: 1073 case HAL_PIXEL_FORMAT_RGBX_8888: 1074 case HAL_PIXEL_FORMAT_RGBA_1010102: 1075 case HAL_PIXEL_FORMAT_RGBX_1010102: 1076 size = alignedw * alignedh * 4; 1077 size += getRgbUBwcMetaBufferSize(width, height, 4); 1078 break; 1079 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 1080 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 1081 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 1082 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height); 1083 break; 1084 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 1085 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height); 1086 break; 1087 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 1088 size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height); 1089 break; 1090 default: 1091 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); 1092 break; 1093 } 1094 return size; 1095 } 1096 1097 int getRgbDataAddress(private_handle_t* hnd, void** rgb_data) 1098 { 1099 int err = 0; 1100 1101 // This api is for RGB* formats 1102 if (!isUncompressedRgbFormat(hnd->format)) { 1103 return -EINVAL; 1104 } 1105 1106 // linear buffer 1107 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) { 1108 *rgb_data = (void*)hnd->base; 1109 return err; 1110 } 1111 1112 // Ubwc buffers 1113 unsigned int meta_size = 0; 1114 switch (hnd->format) { 1115 case HAL_PIXEL_FORMAT_BGR_565: 1116 meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 2); 1117 break; 1118 case HAL_PIXEL_FORMAT_RGBA_8888: 1119 case HAL_PIXEL_FORMAT_RGBX_8888: 1120 case HAL_PIXEL_FORMAT_RGBA_1010102: 1121 case HAL_PIXEL_FORMAT_RGBX_1010102: 1122 meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 4); 1123 break; 1124 default: 1125 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format); 1126 err = -EINVAL; 1127 break; 1128 } 1129 1130 *rgb_data = (void*)(hnd->base + meta_size); 1131 return err; 1132 } 1133 1134 int getBufferLayout(private_handle_t *hnd, uint32_t stride[4], 1135 uint32_t offset[4], uint32_t *num_planes) { 1136 if (!hnd || !stride || !offset || !num_planes) { 1137 return -EINVAL; 1138 } 1139 1140 struct android_ycbcr yuvInfo = {}; 1141 *num_planes = 1; 1142 stride[0] = 0; 1143 1144 switch (hnd->format) { 1145 case HAL_PIXEL_FORMAT_RGB_565: 1146 case HAL_PIXEL_FORMAT_BGR_565: 1147 case HAL_PIXEL_FORMAT_RGBA_5551: 1148 case HAL_PIXEL_FORMAT_RGBA_4444: 1149 stride[0] = hnd->width * 2; 1150 break; 1151 case HAL_PIXEL_FORMAT_RGB_888: 1152 stride[0] = hnd->width * 3; 1153 break; 1154 case HAL_PIXEL_FORMAT_RGBA_8888: 1155 case HAL_PIXEL_FORMAT_BGRA_8888: 1156 case HAL_PIXEL_FORMAT_RGBX_8888: 1157 case HAL_PIXEL_FORMAT_BGRX_8888: 1158 case HAL_PIXEL_FORMAT_RGBA_1010102: 1159 case HAL_PIXEL_FORMAT_ARGB_2101010: 1160 case HAL_PIXEL_FORMAT_RGBX_1010102: 1161 case HAL_PIXEL_FORMAT_XRGB_2101010: 1162 case HAL_PIXEL_FORMAT_BGRA_1010102: 1163 case HAL_PIXEL_FORMAT_ABGR_2101010: 1164 case HAL_PIXEL_FORMAT_BGRX_1010102: 1165 case HAL_PIXEL_FORMAT_XBGR_2101010: 1166 stride[0] = hnd->width * 4; 1167 break; 1168 } 1169 1170 // Format is RGB 1171 if (stride[0]) { 1172 return 0; 1173 } 1174 1175 (*num_planes)++; 1176 int ret = getYUVPlaneInfo(hnd, &yuvInfo); 1177 if (ret < 0) { 1178 ALOGE("%s failed", __FUNCTION__); 1179 return ret; 1180 } 1181 1182 stride[0] = static_cast<uint32_t>(yuvInfo.ystride); 1183 offset[0] = static_cast<uint32_t>( 1184 reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base); 1185 stride[1] = static_cast<uint32_t>(yuvInfo.cstride); 1186 switch (hnd->format) { 1187 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 1188 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 1189 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 1190 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 1191 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 1192 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 1193 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 1194 case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC: 1195 offset[1] = static_cast<uint32_t>( 1196 reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base); 1197 break; 1198 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 1199 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 1200 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 1201 offset[1] = static_cast<uint32_t>( 1202 reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base); 1203 break; 1204 case HAL_PIXEL_FORMAT_YV12: 1205 offset[1] = static_cast<uint32_t>( 1206 reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base); 1207 stride[2] = static_cast<uint32_t>(yuvInfo.cstride); 1208 offset[2] = static_cast<uint32_t>( 1209 reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base); 1210 (*num_planes)++; 1211 break; 1212 default: 1213 ALOGW("%s: Unsupported format %s", __FUNCTION__, 1214 qdutils::GetHALPixelFormatString(hnd->format)); 1215 ret = -EINVAL; 1216 } 1217 1218 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 1219 std::fill(offset, offset + 4, 0); 1220 } 1221 1222 return 0; 1223 } 1224