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