1 /* 2 * Copyright (C) 2016 ARM Limited. All rights reserved. 3 * 4 * Copyright (C) 2008 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #include <string.h> 20 #include <dlfcn.h> 21 #include <hardware/gralloc.h> 22 #include <inttypes.h> 23 #include <cutils/log.h> 24 25 #include "mali_gralloc_formats.h" 26 #include "gralloc_priv.h" 27 28 static mali_gralloc_format_caps dpu_runtime_caps; 29 static mali_gralloc_format_caps vpu_runtime_caps; 30 static mali_gralloc_format_caps gpu_runtime_caps; 31 static mali_gralloc_format_caps cam_runtime_caps; 32 static pthread_mutex_t caps_init_mutex = PTHREAD_MUTEX_INITIALIZER; 33 static bool runtime_caps_read = false; 34 35 #define MALI_GRALLOC_GPU_LIB_NAME "libGLES_mali.so" 36 #if defined(__LP64__) 37 #define MALI_GRALLOC_GPU_LIBRARY_PATH1 "/vendor/lib64/egl/" 38 #define MALI_GRALLOC_GPU_LIBRARY_PATH2 "/system/lib64/egl/" 39 #else 40 #define MALI_GRALLOC_GPU_LIBRARY_PATH1 "/vendor/lib/egl/" 41 #define MALI_GRALLOC_GPU_LIBRARY_PATH2 "/system/lib/egl/" 42 #endif 43 44 static bool get_block_capabilities(bool hal_module, const char *name, mali_gralloc_format_caps *block_caps) 45 { 46 void *dso_handle = NULL; 47 bool rval = false; 48 49 /* Look for MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR symbol in user-space drivers 50 * to determine hw format capabilities. 51 */ 52 if(!hal_module) 53 { 54 dso_handle = dlopen(name, RTLD_LAZY); 55 } 56 else 57 { 58 /* libhardware does some heuristics to find hal modules 59 * and then stores the dso handle internally. Use this. 60 */ 61 const struct hw_module_t *module = {NULL}; 62 63 if(hw_get_module(name, &module) >= 0) 64 { 65 dso_handle = module->dso; 66 } 67 } 68 69 if(dso_handle) 70 { 71 void *sym = dlsym(dso_handle, MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR); 72 73 if(sym) 74 { 75 memcpy((void*) block_caps, sym, sizeof(mali_gralloc_format_caps)); 76 rval = true; 77 } 78 79 if(!hal_module) 80 { 81 dlclose(dso_handle); 82 } 83 } 84 85 return rval; 86 } 87 88 static int map_flex_formats(int req_format, uint64_t *producer_runtime_mask) 89 { 90 /* Map Android flexible formats to internal base formats */ 91 if(req_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED || 92 req_format == HAL_PIXEL_FORMAT_YCbCr_420_888) 93 { 94 req_format = MALI_GRALLOC_FORMAT_INTERNAL_NV12; 95 96 /* 97 * We disable AFBC for NV12 since neither VPU or DPU DDKs support 98 * them currently. 99 */ 100 *producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 101 } 102 return req_format; 103 } 104 105 static bool is_afbc_supported(int req_format_mapped) 106 { 107 bool rval = true; 108 109 /* These base formats we currently don't support with compression */ 110 switch(req_format_mapped) 111 { 112 case MALI_GRALLOC_FORMAT_INTERNAL_RAW16: 113 case MALI_GRALLOC_FORMAT_INTERNAL_RAW12: 114 case MALI_GRALLOC_FORMAT_INTERNAL_RAW10: 115 case MALI_GRALLOC_FORMAT_INTERNAL_BLOB: 116 case MALI_GRALLOC_FORMAT_INTERNAL_P010: 117 case MALI_GRALLOC_FORMAT_INTERNAL_P210: 118 case MALI_GRALLOC_FORMAT_INTERNAL_Y410: 119 case HAL_PIXEL_FORMAT_YCbCr_422_I: 120 rval = false; 121 break; 122 } 123 return rval; 124 } 125 126 static bool is_android_yuv_format(int req_format) 127 { 128 bool rval = false; 129 130 switch(req_format) 131 { 132 case HAL_PIXEL_FORMAT_YV12: 133 case HAL_PIXEL_FORMAT_Y8: 134 case HAL_PIXEL_FORMAT_Y16: 135 case HAL_PIXEL_FORMAT_YCbCr_420_888: 136 case HAL_PIXEL_FORMAT_YCbCr_422_888: 137 case HAL_PIXEL_FORMAT_YCbCr_444_888: 138 rval = true; 139 break; 140 } 141 return rval; 142 } 143 144 static bool is_afbc_allowed(int buffer_size) 145 { 146 bool afbc_allowed = false; 147 148 (void) buffer_size; 149 150 #if GRALLOC_DISP_W != 0 && GRALLOC_DISP_H != 0 151 afbc_allowed = ((buffer_size*100) / (GRALLOC_DISP_W*GRALLOC_DISP_H)) >= GRALLOC_AFBC_MIN_SIZE; 152 153 #else 154 /* If display size is not valid then always allow AFBC */ 155 afbc_allowed = true; 156 157 #endif 158 159 return afbc_allowed; 160 } 161 162 static bool is_afbc_format(uint64_t internal_format) 163 { 164 return (internal_format & MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK) != 0; 165 } 166 167 static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type producer, mali_gralloc_consumer_type consumer, 168 uint64_t producer_runtime_mask, uint64_t consumer_runtime_mask) 169 { 170 /* Default is to return the requested format */ 171 uint64_t internal_format = req_format; 172 uint64_t dpu_mask = dpu_runtime_caps.caps_mask; 173 uint64_t gpu_mask = gpu_runtime_caps.caps_mask; 174 uint64_t vpu_mask = vpu_runtime_caps.caps_mask; 175 uint64_t cam_mask = cam_runtime_caps.caps_mask; 176 177 if(producer == MALI_GRALLOC_PRODUCER_GPU && gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) 178 { 179 gpu_mask &= producer_runtime_mask; 180 181 if(consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY) 182 { 183 gpu_mask &= consumer_runtime_mask; 184 dpu_mask &= consumer_runtime_mask; 185 186 if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK && 187 dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK) 188 { 189 internal_format |= MALI_GRALLOC_INTFMT_AFBC_SPLITBLK; 190 } 191 else if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC && 192 dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) 193 { 194 internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC; 195 196 if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS && 197 dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) 198 { 199 internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; 200 } 201 } 202 } 203 else if(consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL) 204 { 205 gpu_mask &= consumer_runtime_mask; 206 207 /* When GPU acts as both producer and consumer it prefers 16x16 superblocks */ 208 if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) 209 { 210 internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC; 211 } 212 213 if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) 214 { 215 internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; 216 } 217 } 218 else if(consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER) 219 { 220 vpu_mask &= consumer_runtime_mask; 221 222 if(req_format == HAL_PIXEL_FORMAT_YV12) 223 { 224 if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC && 225 vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) 226 { 227 internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC; 228 } 229 230 if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS && 231 vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) 232 { 233 internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; 234 } 235 } 236 } 237 } 238 else if(producer == MALI_GRALLOC_PRODUCER_VIDEO_DECODER && vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) 239 { 240 vpu_mask &= producer_runtime_mask; 241 242 if(consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY) 243 { 244 gpu_mask &= consumer_runtime_mask; 245 dpu_mask &= consumer_runtime_mask; 246 247 if(internal_format == HAL_PIXEL_FORMAT_YV12) 248 { 249 if(vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC && 250 gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC && 251 dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) 252 { 253 internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC; 254 } 255 256 if(vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS && 257 gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS && 258 dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) 259 { 260 internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; 261 } 262 } 263 } 264 else if(consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL) 265 { 266 gpu_mask &= consumer_runtime_mask; 267 268 if(internal_format == HAL_PIXEL_FORMAT_YV12) 269 { 270 if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC && 271 vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC) 272 { 273 internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC; 274 } 275 276 if(gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS && 277 vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS) 278 { 279 internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS; 280 } 281 } 282 } 283 else if(consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER) 284 { 285 /* Fall-through. To be decided.*/ 286 } 287 } 288 else if(producer == MALI_GRALLOC_PRODUCER_CAMERA && cam_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) 289 { 290 if(consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY) 291 { 292 /* Fall-through. To be decided.*/ 293 } 294 else if(consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL) 295 { 296 /* Fall-through. To be decided.*/ 297 } 298 else if(consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER) 299 { 300 /* Fall-through. To be decided.*/ 301 } 302 } 303 return internal_format; 304 } 305 306 static uint64_t decode_internal_format(int req_format) 307 { 308 uint64_t internal_format, me_mask, base_format, mapped_base_format; 309 uint64_t ignore_mask; 310 311 internal_format = GRALLOC_PRIVATE_FORMAT_UNWRAP(req_format); 312 313 me_mask = internal_format & MALI_GRALLOC_INTFMT_ME_EXT_MASK; 314 if(me_mask > 0 && ((me_mask - 1) & me_mask) != 0) 315 { 316 ALOGE("Internal format contains multiple mutually exclusive modifier bits: %" PRIx64, internal_format); 317 internal_format = 0; 318 goto out; 319 } 320 321 base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK; 322 323 /* Even though private format allocations are intended to be for specific 324 * formats, certain test cases uses the flexible formats that needs to be mapped 325 * to internal ones. 326 */ 327 mapped_base_format = map_flex_formats((uint32_t ) base_format, &ignore_mask); 328 329 /* Validate the internal base format passed in */ 330 switch(mapped_base_format) 331 { 332 case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888: 333 case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888: 334 case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888: 335 case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565: 336 case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888: 337 case MALI_GRALLOC_FORMAT_INTERNAL_YV12: 338 case MALI_GRALLOC_FORMAT_INTERNAL_Y8: 339 case MALI_GRALLOC_FORMAT_INTERNAL_Y16: 340 case MALI_GRALLOC_FORMAT_INTERNAL_RAW16: 341 case MALI_GRALLOC_FORMAT_INTERNAL_RAW12: 342 case MALI_GRALLOC_FORMAT_INTERNAL_RAW10: 343 case MALI_GRALLOC_FORMAT_INTERNAL_BLOB: 344 case MALI_GRALLOC_FORMAT_INTERNAL_NV12: 345 case MALI_GRALLOC_FORMAT_INTERNAL_NV21: 346 case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT: 347 case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2: 348 case MALI_GRALLOC_FORMAT_INTERNAL_P010: 349 case MALI_GRALLOC_FORMAT_INTERNAL_P210: 350 case MALI_GRALLOC_FORMAT_INTERNAL_Y210: 351 case MALI_GRALLOC_FORMAT_INTERNAL_Y410: 352 if(mapped_base_format != base_format) 353 { 354 internal_format = (internal_format & MALI_GRALLOC_INTFMT_EXT_MASK) | mapped_base_format; 355 } 356 break; 357 358 default: 359 ALOGE("Internal base format requested is unrecognized: %" PRIx64 ,internal_format); 360 internal_format = 0; 361 break; 362 } 363 out: 364 return internal_format; 365 } 366 367 static bool determine_producer(mali_gralloc_producer_type *producer, uint64_t *producer_runtime_mask, int req_format, int usage) 368 { 369 bool rval = true; 370 371 /* Default to GPU */ 372 *producer = MALI_GRALLOC_PRODUCER_GPU; 373 374 if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) 375 { 376 rval = false; 377 } 378 else if(usage & GRALLOC_USAGE_HW_RENDER) 379 { 380 if(is_android_yuv_format(req_format)) 381 { 382 if(gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE) 383 { 384 *producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 385 } 386 else 387 { 388 /* All GPUs that can write YUV AFBC can only do it in 16x16, optionally with tiled */ 389 *producer_runtime_mask &= ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK); 390 } 391 } 392 *producer = MALI_GRALLOC_PRODUCER_GPU; 393 } 394 else if(usage & GRALLOC_USAGE_HW_CAMERA_MASK) 395 { 396 *producer = MALI_GRALLOC_PRODUCER_CAMERA; 397 } 398 /* HW_TEXTURE+HW_COMPOSER+EXTERNAL_DISP is a definition set by 399 * stagefright for "video decoder". We check for it here. 400 */ 401 else if((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP)) == 402 (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP)) 403 { 404 *producer = MALI_GRALLOC_PRODUCER_VIDEO_DECODER; 405 } 406 407 return rval; 408 } 409 410 static bool determine_consumer(mali_gralloc_consumer_type *consumer, uint64_t *consumer_runtime_mask, int req_format, int usage) 411 { 412 bool rval = true; 413 414 /* Default to GPU */ 415 *consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL; 416 417 if(usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) 418 { 419 rval = false; 420 } 421 /* When usage explicitly targets a consumer, as it does with GRALLOC_USAGE_HW_FB, 422 * we pick DPU even if there are no runtime capabilities present. 423 */ 424 else if( usage & GRALLOC_USAGE_HW_FB ) 425 { 426 *consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY; 427 } 428 else if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) 429 { 430 if((vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD) && 431 is_android_yuv_format(req_format)) 432 { 433 *consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 434 } 435 *consumer = MALI_GRALLOC_CONSUMER_VIDEO_ENCODER; 436 } 437 /* GRALLOC_USAGE_HW_COMPOSER is by default applied by SurfaceFlinger so we can't exclusively rely on it 438 * to determine consumer. When a buffer is targeted for either we reject the DPU when it lacks 439 * runtime capabilities, in favor of the more capable GPU. 440 */ 441 else if((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER )) == (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER ) && 442 dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) 443 { 444 *consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY; 445 } 446 else if(usage & GRALLOC_USAGE_HW_TEXTURE) 447 { 448 *consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL; 449 } 450 return rval; 451 } 452 453 /* 454 * Here we determine format capabilities for the 4 IPs we support. 455 * For now these are controlled by build defines, but in the future 456 * they should be read out from each user-space driver. 457 */ 458 static void determine_format_capabilities() 459 { 460 /* Loading libraries can take some time and 461 * we may see many allocations at boot. 462 */ 463 pthread_mutex_lock(&caps_init_mutex); 464 465 if(runtime_caps_read) 466 { 467 goto already_init; 468 } 469 470 memset((void*) &dpu_runtime_caps,0,sizeof(dpu_runtime_caps)); 471 memset((void*) &vpu_runtime_caps,0,sizeof(vpu_runtime_caps)); 472 memset((void*) &gpu_runtime_caps,0,sizeof(gpu_runtime_caps)); 473 memset((void*) &cam_runtime_caps,0,sizeof(cam_runtime_caps)); 474 475 /* Determine DPU format capabilities */ 476 if(!get_block_capabilities(true, "hwcomposer", &dpu_runtime_caps)) 477 { 478 #if MALI_DISPLAY_VERSION >= 500 479 dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; 480 dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; 481 482 #if MALI_DISPLAY_VERSION >= 550 483 dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; 484 #endif 485 #endif 486 } 487 488 /* Determine GPU format capabilities */ 489 if(access(MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME,R_OK) == 0) 490 { 491 get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps); 492 } 493 else if(access(MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME,R_OK) == 0) 494 { 495 get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps); 496 } 497 498 if((gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) == 0) 499 { 500 ALOGW("Failed to find GPU block configuration in %s. Using static build configuration.", MALI_GRALLOC_GPU_LIB_NAME); 501 502 #if MALI_GPU_SUPPORT_AFBC_BASIC == 1 503 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; 504 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; 505 506 /* Need to verify when to remove this */ 507 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE; 508 509 #if MALI_SUPPORT_AFBC_SPLITBLK == 1 510 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; 511 #endif 512 513 #if MALI_SUPPORT_AFBC_WIDEBLK == 1 514 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; 515 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK; 516 #endif 517 518 #if MALI_USE_YUV_AFBC_WIDEBLK != 1 519 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK_YUV_DISABLE; 520 #endif 521 522 #if MALI_SUPPORT_AFBC_TILED_HEADERS == 1 523 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK; 524 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK; 525 gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS; 526 #endif 527 #endif /* MALI_GPU_SUPPORT_AFBC_BASIC == 1 */ 528 } 529 530 /* Determine VPU format capabilities */ 531 #if MALI_VIDEO_VERSION == 500 || MALI_VIDEO_VERSION == 550 532 vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; 533 vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; 534 vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD; 535 #endif 536 537 #if MALI_VIDEO_VERSION == 61 538 vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT; 539 vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC; 540 vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS; 541 #endif 542 543 544 /* Build specific capability changes */ 545 #if GRALLOC_ARM_NO_EXTERNAL_AFBC == 1 546 { 547 dpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 548 gpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 549 vpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 550 cam_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 551 } 552 #endif 553 554 runtime_caps_read = true; 555 556 already_init: 557 pthread_mutex_unlock(&caps_init_mutex); 558 559 ALOGV("GPU format capabilities 0x%" PRIx64 , gpu_runtime_caps.caps_mask); 560 ALOGV("DPU format capabilities 0x%" PRIx64 , dpu_runtime_caps.caps_mask); 561 ALOGV("VPU format capabilities 0x%" PRIx64 , vpu_runtime_caps.caps_mask); 562 ALOGV("CAM format capabilities 0x%" PRIx64 , cam_runtime_caps.caps_mask); 563 } 564 565 uint64_t mali_gralloc_select_format(int req_format, int usage, int buffer_size) 566 { 567 uint64_t internal_format = 0; 568 mali_gralloc_consumer_type consumer; 569 mali_gralloc_producer_type producer; 570 uint64_t producer_runtime_mask = ~(0ULL); 571 uint64_t consumer_runtime_mask = ~(0ULL); 572 int req_format_mapped=0; 573 574 if(!runtime_caps_read) 575 { 576 /* 577 * It is better to initialize these when needed because 578 * not all processes allocates memory. 579 */ 580 determine_format_capabilities(); 581 } 582 583 /* A unique usage specifies that an internal format is in req_format */ 584 if(usage & MALI_GRALLOC_USAGE_PRIVATE_FORMAT) 585 { 586 internal_format = decode_internal_format(req_format); 587 goto out; 588 } 589 590 /* Re-map special Android formats */ 591 req_format_mapped = map_flex_formats(req_format, &producer_runtime_mask); 592 593 /* Determine producer/consumer */ 594 if(!determine_producer(&producer, &producer_runtime_mask, req_format, usage) || 595 !determine_consumer(&consumer, &consumer_runtime_mask, req_format, usage)) 596 { 597 /* Failing to determine producer/consumer usually means 598 * client has requested sw rendering. 599 */ 600 internal_format = req_format_mapped; 601 goto out; 602 } 603 604 /* 605 * Determine runtime capability limitations 606 */ 607 608 /* Disable AFBC based on unique usage */ 609 if ((usage & MALI_GRALLOC_USAGE_NO_AFBC) == MALI_GRALLOC_USAGE_NO_AFBC) 610 { 611 if(is_android_yuv_format(req_format_mapped)) 612 { 613 ALOGE("It is invalid to specify NO_AFBC usage flags when allocating YUV formats.\ 614 Requested fmt: 0x%08X Re-Mapped fmt: 0x%08X",req_format,req_format_mapped); 615 internal_format = 0; 616 goto out; 617 } 618 producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 619 } 620 /* Disable AFBC based on buffer dimensions */ 621 else if(!is_afbc_allowed(buffer_size)) 622 { 623 producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 624 } 625 else if(!is_afbc_supported(req_format_mapped)) 626 { 627 producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK; 628 } 629 630 /* Automatically select format in case producer/consumer identified */ 631 internal_format = determine_best_format(req_format_mapped, producer, consumer, producer_runtime_mask, consumer_runtime_mask); 632 633 out: 634 ALOGV("mali_gralloc_select_format: req_format=0x%08X req_fmt_mapped=0x%08X internal_format=0x%" PRIx64 " usage=0x%08X",req_format, req_format_mapped, internal_format, usage); 635 636 return internal_format; 637 } 638 639 extern "C" 640 { 641 void mali_gralloc_get_gpu_caps(struct mali_gralloc_format_caps *gpu_caps) 642 { 643 if(gpu_caps != NULL) 644 { 645 if(!runtime_caps_read) 646 { 647 determine_format_capabilities(); 648 } 649 memcpy(gpu_caps,(void*) &gpu_runtime_caps,sizeof(struct mali_gralloc_format_caps)); 650 } 651 } 652 } 653