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