1 /* 2 * Copyright (c) 2011-2014, 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 "comptype.h" 39 #include "mdp_version.h" 40 41 #ifdef VENUS_COLOR_FORMAT 42 #include <media/msm_media_info.h> 43 #else 44 #define VENUS_Y_STRIDE(args...) 0 45 #define VENUS_Y_SCANLINES(args...) 0 46 #define VENUS_BUFFER_SIZE(args...) 0 47 #endif 48 49 #define ASTC_BLOCK_SIZE 16 50 51 using namespace gralloc; 52 using namespace qdutils; 53 54 ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo); 55 56 static void getUBwcWidthAndHeight(int, int, int, int&, int&); 57 static unsigned int getUBwcSize(int, int, int, const int, const int); 58 59 //Common functions 60 static bool canFallback(int usage, bool triedSystem) 61 { 62 // Fallback to system heap when alloc fails unless 63 // 1. Composition type is MDP 64 // 2. Alloc from system heap was already tried 65 // 3. The heap type is requsted explicitly 66 // 4. The heap type is protected 67 // 5. The buffer is meant for external display only 68 69 if(QCCompositionType::getInstance().getCompositionType() & 70 COMPOSITION_TYPE_MDP) 71 return false; 72 if(triedSystem) 73 return false; 74 if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED)) 75 return false; 76 if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY)) 77 return false; 78 //Return true by default 79 return true; 80 } 81 82 /* The default policy is to return cached buffers unless the client explicity 83 * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely 84 * read or written in software. Any combination with a _RARELY_ flag will be 85 * treated as uncached. */ 86 static bool useUncached(const int& usage) { 87 if ((usage & GRALLOC_USAGE_PROTECTED) or 88 (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or 89 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or 90 ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_RARELY)) 91 return true; 92 93 return false; 94 } 95 96 //-------------- AdrenoMemInfo-----------------------// 97 AdrenoMemInfo::AdrenoMemInfo() 98 { 99 LINK_adreno_compute_aligned_width_and_height = NULL; 100 LINK_adreno_compute_padding = NULL; 101 LINK_adreno_isMacroTilingSupportedByGpu = NULL; 102 LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL; 103 LINK_adreno_isUBWCSupportedByGpu = NULL; 104 105 libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW); 106 if (libadreno_utils) { 107 *(void **)&LINK_adreno_compute_aligned_width_and_height = 108 ::dlsym(libadreno_utils, "compute_aligned_width_and_height"); 109 *(void **)&LINK_adreno_compute_padding = 110 ::dlsym(libadreno_utils, "compute_surface_padding"); 111 *(void **)&LINK_adreno_isMacroTilingSupportedByGpu = 112 ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu"); 113 *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height = 114 ::dlsym(libadreno_utils, 115 "compute_compressedfmt_aligned_width_and_height"); 116 *(void **)&LINK_adreno_isUBWCSupportedByGpu = 117 ::dlsym(libadreno_utils, "isUBWCSupportedByGpu"); 118 } 119 } 120 121 AdrenoMemInfo::~AdrenoMemInfo() 122 { 123 if (libadreno_utils) { 124 ::dlclose(libadreno_utils); 125 } 126 } 127 128 int AdrenoMemInfo::isMacroTilingSupportedByGPU() 129 { 130 if ((libadreno_utils)) { 131 if(LINK_adreno_isMacroTilingSupportedByGpu) { 132 return LINK_adreno_isMacroTilingSupportedByGpu(); 133 } 134 } 135 return 0; 136 } 137 138 139 bool isUncompressedRgbFormat(int format) 140 { 141 bool is_rgb_format = false; 142 143 switch (format) 144 { 145 case HAL_PIXEL_FORMAT_RGBA_8888: 146 case HAL_PIXEL_FORMAT_RGBX_8888: 147 case HAL_PIXEL_FORMAT_RGB_888: 148 case HAL_PIXEL_FORMAT_RGB_565: 149 case HAL_PIXEL_FORMAT_BGRA_8888: 150 case HAL_PIXEL_FORMAT_RGBA_5551: 151 case HAL_PIXEL_FORMAT_RGBA_4444: 152 case HAL_PIXEL_FORMAT_R_8: 153 case HAL_PIXEL_FORMAT_RG_88: 154 case HAL_PIXEL_FORMAT_BGRX_8888: // Intentional fallthrough 155 is_rgb_format = true; 156 break; 157 default: 158 break; 159 } 160 161 return is_rgb_format; 162 } 163 164 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format, 165 int usage, int& aligned_w, int& aligned_h) 166 { 167 168 // Currently surface padding is only computed for RGB* surfaces. 169 if (isUncompressedRgbFormat(format) == true) { 170 int tileEnabled = isMacroTileEnabled(format, usage); 171 AdrenoMemInfo::getInstance().getGpuAlignedWidthHeight(width, 172 height, format, tileEnabled, aligned_w, aligned_h); 173 return; 174 } 175 176 if (isUBwcEnabled(format, usage)) { 177 getUBwcWidthAndHeight(width, height, format, aligned_w, aligned_h); 178 return; 179 } 180 181 aligned_w = width; 182 aligned_h = height; 183 switch (format) 184 { 185 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 186 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 187 aligned_w = ALIGN(width, 32); 188 break; 189 case HAL_PIXEL_FORMAT_RAW16: 190 aligned_w = ALIGN(width, 16); 191 break; 192 case HAL_PIXEL_FORMAT_RAW10: 193 aligned_w = ALIGN(width * 10 /8, 8); 194 break; 195 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 196 aligned_w = ALIGN(width, 128); 197 break; 198 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 199 case HAL_PIXEL_FORMAT_YV12: 200 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 201 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 202 case HAL_PIXEL_FORMAT_YCbCr_422_I: 203 case HAL_PIXEL_FORMAT_YCrCb_422_I: 204 aligned_w = ALIGN(width, 16); 205 break; 206 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 207 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 208 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width); 209 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height); 210 break; 211 case HAL_PIXEL_FORMAT_BLOB: 212 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 213 break; 214 case HAL_PIXEL_FORMAT_NV21_ZSL: 215 aligned_w = ALIGN(width, 64); 216 aligned_h = ALIGN(height, 64); 217 break; 218 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR: 219 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: 220 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR: 221 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: 222 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR: 223 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: 224 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR: 225 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: 226 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR: 227 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: 228 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR: 229 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: 230 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR: 231 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: 232 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR: 233 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: 234 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR: 235 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: 236 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR: 237 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: 238 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR: 239 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: 240 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR: 241 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: 242 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR: 243 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: 244 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR: 245 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: 246 if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) { 247 int bytesPerPixel = 0; 248 int raster_mode = 0; //Adreno unknown raster mode. 249 int padding_threshold = 512; //Threshold for padding 250 //surfaces. 251 252 LINK_adreno_compute_compressedfmt_aligned_width_and_height( 253 width, height, format, 0,raster_mode, padding_threshold, 254 &aligned_w, &aligned_h, &bytesPerPixel); 255 } else { 256 ALOGW("%s: Warning!! Symbols" \ 257 " compute_compressedfmt_aligned_width_and_height" \ 258 " not found", __FUNCTION__); 259 } 260 break; 261 default: break; 262 } 263 } 264 265 void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format, 266 int tile_enabled, int& aligned_w, int& aligned_h) 267 { 268 aligned_w = ALIGN(width, 32); 269 aligned_h = ALIGN(height, 32); 270 271 // Don't add any additional padding if debug.gralloc.map_fb_memory 272 // is enabled 273 char property[PROPERTY_VALUE_MAX]; 274 if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) && 275 (!strncmp(property, "1", PROPERTY_VALUE_MAX ) || 276 (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) { 277 return; 278 } 279 280 int bpp = 4; 281 switch(format) 282 { 283 case HAL_PIXEL_FORMAT_RGB_888: 284 bpp = 3; 285 break; 286 case HAL_PIXEL_FORMAT_RGB_565: 287 case HAL_PIXEL_FORMAT_RGBA_5551: 288 case HAL_PIXEL_FORMAT_RGBA_4444: 289 bpp = 2; 290 break; 291 default: break; 292 } 293 294 if (libadreno_utils) { 295 int raster_mode = 0; // Adreno unknown raster mode. 296 int padding_threshold = 512; // Threshold for padding surfaces. 297 // the function below computes aligned width and aligned height 298 // based on linear or macro tile mode selected. 299 if(LINK_adreno_compute_aligned_width_and_height) { 300 LINK_adreno_compute_aligned_width_and_height(width, 301 height, bpp, tile_enabled, 302 raster_mode, padding_threshold, 303 &aligned_w, &aligned_h); 304 305 } else if(LINK_adreno_compute_padding) { 306 int surface_tile_height = 1; // Linear surface 307 aligned_w = LINK_adreno_compute_padding(width, bpp, 308 surface_tile_height, raster_mode, 309 padding_threshold); 310 ALOGW("%s: Warning!! Old GFX API is used to calculate stride", 311 __FUNCTION__); 312 } else { 313 ALOGW("%s: Warning!! Symbols compute_surface_padding and " \ 314 "compute_aligned_width_and_height not found", __FUNCTION__); 315 } 316 } 317 } 318 319 int AdrenoMemInfo::isUBWCSupportedByGPU(int format) 320 { 321 if (libadreno_utils) { 322 if (LINK_adreno_isUBWCSupportedByGpu) { 323 ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format); 324 return LINK_adreno_isUBWCSupportedByGpu(gpu_format); 325 } 326 } 327 return 0; 328 } 329 330 ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format) 331 { 332 switch (hal_format) { 333 case HAL_PIXEL_FORMAT_RGBA_8888: 334 return ADRENO_PIXELFORMAT_R8G8B8A8; 335 case HAL_PIXEL_FORMAT_RGB_565: 336 return ADRENO_PIXELFORMAT_B5G6R5; 337 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 338 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 339 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 340 return ADRENO_PIXELFORMAT_NV12; 341 default: 342 ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format); 343 break; 344 } 345 return ADRENO_PIXELFORMAT_UNKNOWN; 346 } 347 348 //-------------- IAllocController-----------------------// 349 IAllocController* IAllocController::sController = NULL; 350 IAllocController* IAllocController::getInstance(void) 351 { 352 if(sController == NULL) { 353 sController = new IonController(); 354 } 355 return sController; 356 } 357 358 359 //-------------- IonController-----------------------// 360 IonController::IonController() 361 { 362 allocateIonMem(); 363 } 364 365 void IonController::allocateIonMem() 366 { 367 mIonAlloc = new IonAlloc(); 368 } 369 370 int IonController::allocate(alloc_data& data, int usage) 371 { 372 int ionFlags = 0; 373 int ret; 374 375 data.uncached = useUncached(usage); 376 data.allocType = 0; 377 378 if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP) 379 ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID); 380 381 if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP) 382 ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID); 383 384 if(usage & GRALLOC_USAGE_PROTECTED) { 385 ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID); 386 ionFlags |= ION_SECURE; 387 #ifdef ION_FLAG_ALLOW_NON_CONTIG 388 if (!(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) { 389 ionFlags |= ION_FLAG_ALLOW_NON_CONTIG; 390 } 391 #endif 392 } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) { 393 //MM Heap is exclusively a secure heap. 394 //If it is used for non secure cases, fallback to IOMMU heap 395 ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \ 396 cannot be used as an insecure heap!\ 397 trying to use IOMMU instead !!"); 398 ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID); 399 } 400 401 if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP) 402 ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID); 403 404 if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP) 405 ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID); 406 407 if(ionFlags & ION_SECURE) 408 data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER; 409 410 // if no flags are set, default to 411 // SF + IOMMU heaps, so that bypass can work 412 // we can fall back to system heap if 413 // we run out. 414 if(!ionFlags) 415 ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID); 416 417 data.flags = ionFlags; 418 ret = mIonAlloc->alloc_buffer(data); 419 420 // Fallback 421 if(ret < 0 && canFallback(usage, 422 (ionFlags & ION_SYSTEM_HEAP_ID))) 423 { 424 ALOGW("Falling back to system heap"); 425 data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID); 426 ret = mIonAlloc->alloc_buffer(data); 427 } 428 429 if(ret >= 0 ) { 430 data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION; 431 } 432 433 return ret; 434 } 435 436 IMemAlloc* IonController::getAllocator(int flags) 437 { 438 IMemAlloc* memalloc = NULL; 439 if (flags & private_handle_t::PRIV_FLAGS_USES_ION) { 440 memalloc = mIonAlloc; 441 } else { 442 ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags); 443 } 444 445 return memalloc; 446 } 447 448 bool isMacroTileEnabled(int format, int usage) 449 { 450 bool tileEnabled = false; 451 452 // Check whether GPU & MDSS supports MacroTiling feature 453 if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() && 454 qdutils::MDPVersion::getInstance().supportsMacroTile()) 455 { 456 // check the format 457 switch(format) 458 { 459 case HAL_PIXEL_FORMAT_RGBA_8888: 460 case HAL_PIXEL_FORMAT_RGBX_8888: 461 case HAL_PIXEL_FORMAT_BGRA_8888: 462 case HAL_PIXEL_FORMAT_RGB_565: 463 { 464 tileEnabled = true; 465 // check the usage flags 466 if (usage & (GRALLOC_USAGE_SW_READ_MASK | 467 GRALLOC_USAGE_SW_WRITE_MASK)) { 468 // Application intends to use CPU for rendering 469 tileEnabled = false; 470 } 471 break; 472 } 473 default: 474 break; 475 } 476 } 477 return tileEnabled; 478 } 479 480 // helper function 481 unsigned int getSize(int format, int width, int height, int usage, 482 const int alignedw, const int alignedh) { 483 484 if (isUBwcEnabled(format, usage)) { 485 return getUBwcSize(width, height, format, alignedw, alignedh); 486 } 487 488 unsigned int size = 0; 489 switch (format) { 490 case HAL_PIXEL_FORMAT_RGBA_8888: 491 case HAL_PIXEL_FORMAT_RGBX_8888: 492 case HAL_PIXEL_FORMAT_BGRA_8888: 493 size = alignedw * alignedh * 4; 494 break; 495 case HAL_PIXEL_FORMAT_RGB_888: 496 size = alignedw * alignedh * 3; 497 break; 498 case HAL_PIXEL_FORMAT_RGB_565: 499 case HAL_PIXEL_FORMAT_RGBA_5551: 500 case HAL_PIXEL_FORMAT_RGBA_4444: 501 case HAL_PIXEL_FORMAT_RAW16: 502 size = alignedw * alignedh * 2; 503 break; 504 case HAL_PIXEL_FORMAT_RAW10: 505 size = ALIGN(alignedw * alignedh, 4096); 506 break; 507 // adreno formats 508 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21 509 size = ALIGN(alignedw*alignedh, 4096); 510 size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096); 511 break; 512 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12 513 // The chroma plane is subsampled, 514 // but the pitch in bytes is unchanged 515 // The GPU needs 4K alignment, but the video decoder needs 8K 516 size = ALIGN( alignedw * alignedh, 8192); 517 size += ALIGN( alignedw * ALIGN(height/2, 32), 8192); 518 break; 519 case HAL_PIXEL_FORMAT_YV12: 520 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) { 521 ALOGE("w or h is odd for the YV12 format"); 522 return 0; 523 } 524 size = alignedw*alignedh + 525 (ALIGN(alignedw/2, 16) * (alignedh/2))*2; 526 size = ALIGN(size, (unsigned int)4096); 527 break; 528 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 529 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 530 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096); 531 break; 532 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 533 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 534 case HAL_PIXEL_FORMAT_YCbCr_422_I: 535 case HAL_PIXEL_FORMAT_YCrCb_422_I: 536 if(width & 1) { 537 ALOGE("width is odd for the YUV422_SP format"); 538 return 0; 539 } 540 size = ALIGN(alignedw * alignedh * 2, 4096); 541 break; 542 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 543 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 544 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height); 545 break; 546 case HAL_PIXEL_FORMAT_BLOB: 547 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 548 if(height != 1) { 549 ALOGE("%s: Buffers with RAW_OPAQUE/blob formats \ 550 must have height==1 ", __FUNCTION__); 551 return 0; 552 } 553 size = width; 554 break; 555 case HAL_PIXEL_FORMAT_NV21_ZSL: 556 size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096); 557 break; 558 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR: 559 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR: 560 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR: 561 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR: 562 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR: 563 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR: 564 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR: 565 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR: 566 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR: 567 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR: 568 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR: 569 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR: 570 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR: 571 case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR: 572 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: 573 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: 574 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: 575 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: 576 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: 577 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: 578 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: 579 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: 580 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: 581 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: 582 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: 583 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: 584 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: 585 case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: 586 size = alignedw * alignedh * ASTC_BLOCK_SIZE; 587 break; 588 default: 589 ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format); 590 return 0; 591 } 592 return size; 593 } 594 595 unsigned int getBufferSizeAndDimensions(int width, int height, int format, 596 int& alignedw, int &alignedh) 597 { 598 unsigned int size; 599 600 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, 601 height, 602 format, 603 0, 604 alignedw, 605 alignedh); 606 607 size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh); 608 609 return size; 610 } 611 612 613 unsigned int getBufferSizeAndDimensions(int width, int height, int format, 614 int usage, int& alignedw, int &alignedh) 615 { 616 unsigned int size; 617 618 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, 619 height, 620 format, 621 usage, 622 alignedw, 623 alignedh); 624 625 size = getSize(format, width, height, usage, alignedw, alignedh); 626 627 return size; 628 } 629 630 631 void getBufferAttributes(int width, int height, int format, int usage, 632 int& alignedw, int &alignedh, int& tileEnabled, unsigned int& size) 633 { 634 tileEnabled = isMacroTileEnabled(format, usage); 635 636 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width, 637 height, 638 format, 639 usage, 640 alignedw, 641 alignedh); 642 size = getSize(format, width, height, usage, alignedw, alignedh); 643 } 644 645 int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr) 646 { 647 int err = 0; 648 unsigned int ystride, cstride; 649 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); 650 651 // Get the chroma offsets from the handle width/height. We take advantage 652 // of the fact the width _is_ the stride 653 switch (hnd->format) { 654 //Semiplanar 655 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 656 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 657 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 658 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS 659 ystride = cstride = hnd->width; 660 ycbcr->y = (void*)hnd->base; 661 ycbcr->cb = (void*)(hnd->base + ystride * hnd->height); 662 ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1); 663 ycbcr->ystride = ystride; 664 ycbcr->cstride = cstride; 665 ycbcr->chroma_step = 2; 666 break; 667 668 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 669 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 670 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 671 case HAL_PIXEL_FORMAT_NV21_ZSL: 672 case HAL_PIXEL_FORMAT_RAW10: 673 case HAL_PIXEL_FORMAT_RAW16: 674 ystride = cstride = hnd->width; 675 ycbcr->y = (void*)hnd->base; 676 ycbcr->cr = (void*)(hnd->base + ystride * hnd->height); 677 ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1); 678 ycbcr->ystride = ystride; 679 ycbcr->cstride = cstride; 680 ycbcr->chroma_step = 2; 681 break; 682 683 //Planar 684 case HAL_PIXEL_FORMAT_YV12: 685 ystride = hnd->width; 686 cstride = ALIGN(hnd->width/2, 16); 687 ycbcr->y = (void*)hnd->base; 688 ycbcr->cr = (void*)(hnd->base + ystride * hnd->height); 689 ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 690 cstride * hnd->height/2); 691 ycbcr->ystride = ystride; 692 ycbcr->cstride = cstride; 693 ycbcr->chroma_step = 1; 694 695 break; 696 //Unsupported formats 697 case HAL_PIXEL_FORMAT_YCbCr_422_I: 698 case HAL_PIXEL_FORMAT_YCrCb_422_I: 699 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 700 default: 701 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, 702 hnd->format); 703 err = -EINVAL; 704 } 705 return err; 706 707 } 708 709 710 711 // Allocate buffer from width, height and format into a 712 // private_handle_t. It is the responsibility of the caller 713 // to free the buffer using the free_buffer function 714 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage) 715 { 716 alloc_data data; 717 int alignedw, alignedh; 718 gralloc::IAllocController* sAlloc = 719 gralloc::IAllocController::getInstance(); 720 data.base = 0; 721 data.fd = -1; 722 data.offset = 0; 723 data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw, 724 alignedh); 725 726 data.align = getpagesize(); 727 data.uncached = useUncached(usage); 728 int allocFlags = usage; 729 730 int err = sAlloc->allocate(data, allocFlags); 731 if (0 != err) { 732 ALOGE("%s: allocate failed", __FUNCTION__); 733 return -ENOMEM; 734 } 735 736 private_handle_t* hnd = new private_handle_t(data.fd, data.size, 737 data.allocType, 0, format, 738 alignedw, alignedh); 739 hnd->base = (uint64_t) data.base; 740 hnd->offset = data.offset; 741 hnd->gpuaddr = 0; 742 *pHnd = hnd; 743 return 0; 744 } 745 746 void free_buffer(private_handle_t *hnd) 747 { 748 gralloc::IAllocController* sAlloc = 749 gralloc::IAllocController::getInstance(); 750 if (hnd && hnd->fd > 0) { 751 IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags); 752 memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd); 753 } 754 if(hnd) 755 delete hnd; 756 757 } 758 759 // UBWC helper functions 760 static bool isUBwcFormat(int format) 761 { 762 // Explicitly defined UBWC formats 763 switch(format) 764 { 765 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 766 return true; 767 default: 768 return false; 769 } 770 } 771 772 static bool isUBwcSupported(int format) 773 { 774 // Existing HAL formats with UBWC support 775 switch(format) 776 { 777 case HAL_PIXEL_FORMAT_RGB_565: 778 case HAL_PIXEL_FORMAT_RGBA_8888: 779 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 780 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 781 return true; 782 default: 783 return false; 784 } 785 } 786 787 bool isUBwcEnabled(int format, int usage) 788 { 789 if (isUBwcFormat(format) || 790 ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format))) 791 { 792 // Allow UBWC, only if GPU supports it and CPU usage flags are not set 793 if (AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format) && 794 !(usage & (GRALLOC_USAGE_SW_READ_MASK | 795 GRALLOC_USAGE_SW_WRITE_MASK))) { 796 return true; 797 } 798 } 799 return false; 800 } 801 802 static void getUBwcWidthAndHeight(int width, int height, int format, 803 int& aligned_w, int& aligned_h) 804 { 805 switch (format) 806 { 807 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 808 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 809 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 810 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width); 811 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height); 812 break; 813 default: 814 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); 815 aligned_w = 0; 816 aligned_h = 0; 817 break; 818 } 819 } 820 821 static void getUBwcBlockSize(int bpp, int& block_width, int& block_height) 822 { 823 block_width = 0; 824 block_height = 0; 825 826 switch(bpp) 827 { 828 case 2: 829 case 4: 830 block_width = 16; 831 block_height = 4; 832 break; 833 case 8: 834 block_width = 8; 835 block_height = 4; 836 break; 837 case 16: 838 block_width = 4; 839 block_height = 4; 840 break; 841 default: 842 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); 843 break; 844 } 845 } 846 847 static unsigned int getUBwcMetaBufferSize(int width, int height, int bpp) 848 { 849 unsigned int size = 0; 850 int meta_width, meta_height; 851 int block_width, block_height; 852 853 getUBwcBlockSize(bpp, block_width, block_height); 854 855 if (!block_width || !block_height) { 856 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); 857 return size; 858 } 859 860 // Align meta buffer height to 16 blocks 861 meta_height = ALIGN(((height + block_height - 1) / block_height), 16); 862 863 // Align meta buffer width to 64 blocks 864 meta_width = ALIGN(((width + block_width - 1) / block_width), 64); 865 866 // Align meta buffer size to 4K 867 size = ((meta_width * meta_height), 4096); 868 return size; 869 } 870 871 static unsigned int getUBwcSize(int width, int height, int format, 872 const int alignedw, const int alignedh) { 873 874 unsigned int size = 0; 875 switch (format) { 876 case HAL_PIXEL_FORMAT_RGB_565: 877 size = alignedw * alignedh * 2; 878 size += getUBwcMetaBufferSize(width, height, 2); 879 break; 880 case HAL_PIXEL_FORMAT_RGBA_8888: 881 size = alignedw * alignedh * 4; 882 size += getUBwcMetaBufferSize(width, height, 4); 883 break; 884 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 885 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 886 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 887 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height); 888 break; 889 default: 890 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); 891 break; 892 } 893 return size; 894 } 895