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