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