1 /* 2 * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. 3 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above 10 * copyright notice, this list of conditions and the following 11 * disclaimer in the documentation and/or other materials provided 12 * with the distribution. 13 * * Neither the name of The Linux Foundation nor the names of its 14 * contributors may be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <cutils/log.h> 31 #include <algorithm> 32 33 #include "gr_utils.h" 34 #include "gr_allocator.h" 35 #include "gr_adreno_info.h" 36 #include "gralloc_priv.h" 37 38 #include "qd_utils.h" 39 #include "qdMetaData.h" 40 41 #define ASTC_BLOCK_SIZE 16 42 43 #ifndef ION_FLAG_CP_PIXEL 44 #define ION_FLAG_CP_PIXEL 0 45 #endif 46 47 #ifndef ION_FLAG_ALLOW_NON_CONTIG 48 #define ION_FLAG_ALLOW_NON_CONTIG 0 49 #endif 50 51 #ifdef MASTER_SIDE_CP 52 #define CP_HEAP_ID ION_SECURE_HEAP_ID 53 #define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID 54 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL) 55 #define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY) 56 #else // SLAVE_SIDE_CP 57 #define CP_HEAP_ID ION_CP_MM_HEAP_ID 58 #define SD_HEAP_ID CP_HEAP_ID 59 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG) 60 #define ION_SD_FLAGS ION_SECURE 61 #endif 62 63 namespace gralloc1 { 64 65 Allocator::Allocator() : ion_allocator_(NULL), adreno_helper_(NULL) { 66 } 67 68 bool Allocator::Init() { 69 ion_allocator_ = new IonAlloc(); 70 if (!ion_allocator_->Init()) { 71 return false; 72 } 73 74 adreno_helper_ = new AdrenoMemInfo(); 75 if (!adreno_helper_->Init()) { 76 return false; 77 } 78 79 gpu_support_macrotile = adreno_helper_->IsMacroTilingSupportedByGPU(); 80 int supports_macrotile = 0; 81 qdutils::querySDEInfo(qdutils::HAS_MACRO_TILE, &supports_macrotile); 82 display_support_macrotile = !!supports_macrotile; 83 84 return true; 85 } 86 87 Allocator::~Allocator() { 88 if (ion_allocator_) { 89 delete ion_allocator_; 90 } 91 92 if (adreno_helper_) { 93 delete adreno_helper_; 94 } 95 } 96 97 int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage, 98 gralloc1_consumer_usage_t cons_usage) { 99 int ret; 100 alloc_data->uncached = UseUncached(prod_usage); 101 102 // After this point we should have the right heap set, there is no fallback 103 GetIonHeapInfo(prod_usage, cons_usage, &alloc_data->heap_id, &alloc_data->alloc_type, 104 &alloc_data->flags); 105 106 ret = ion_allocator_->AllocBuffer(alloc_data); 107 if (ret >= 0) { 108 alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION; 109 } else { 110 ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__, 111 alloc_data->heap_id, alloc_data->flags); 112 } 113 114 return ret; 115 } 116 117 // Allocates buffer from width, height and format into a 118 // private_handle_t. It is the responsibility of the caller 119 // to free the buffer using the FreeBuffer function 120 int Allocator::AllocateBuffer(const BufferDescriptor &descriptor, private_handle_t **pHnd) { 121 AllocData data; 122 unsigned int aligned_w, aligned_h; 123 data.base = 0; 124 data.fd = -1; 125 data.offset = 0; 126 data.align = (unsigned int)getpagesize(); 127 int format = descriptor.GetFormat(); 128 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage(); 129 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage(); 130 GetBufferSizeAndDimensions(descriptor, &data.size, &aligned_w, &aligned_h); 131 132 int err = AllocateMem(&data, prod_usage, cons_usage); 133 if (0 != err) { 134 ALOGE("%s: allocate failed", __FUNCTION__); 135 return -ENOMEM; 136 } 137 138 if (IsUBwcEnabled(format, prod_usage, cons_usage)) { 139 data.alloc_type |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 140 } 141 142 // Metadata is not allocated. would be empty 143 private_handle_t *hnd = new private_handle_t( 144 data.fd, data.size, INT(data.alloc_type), 0, INT(format), INT(aligned_w), INT(aligned_h), -1, 145 0, 0, descriptor.GetWidth(), descriptor.GetHeight(), prod_usage, cons_usage); 146 hnd->base = (uint64_t)data.base; 147 hnd->offset = data.offset; 148 hnd->gpuaddr = 0; 149 *pHnd = hnd; 150 151 return 0; 152 } 153 154 int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) { 155 if (ion_allocator_) { 156 return ion_allocator_->MapBuffer(base, size, offset, fd); 157 } 158 159 return -EINVAL; 160 } 161 162 int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd) { 163 if (ion_allocator_) { 164 return ion_allocator_->FreeBuffer(base, size, offset, fd); 165 } 166 167 return -EINVAL; 168 } 169 170 int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) { 171 if (ion_allocator_) { 172 return ion_allocator_->CleanBuffer(base, size, offset, fd, op); 173 } 174 175 return -EINVAL; 176 } 177 178 bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors, 179 int *max_index) { 180 unsigned int cur_heap_id = 0, prev_heap_id = 0; 181 unsigned int cur_alloc_type = 0, prev_alloc_type = 0; 182 unsigned int cur_ion_flags = 0, prev_ion_flags = 0; 183 bool cur_uncached = false, prev_uncached = false; 184 unsigned int alignedw, alignedh; 185 unsigned int max_size = 0; 186 187 *max_index = -1; 188 for (uint32_t i = 0; i < num_descriptors; i++) { 189 // Check Cached vs non-cached and all the ION flags 190 cur_uncached = UseUncached(descriptors[i].GetProducerUsage()); 191 GetIonHeapInfo(descriptors[i].GetProducerUsage(), descriptors[i].GetConsumerUsage(), 192 &cur_heap_id, &cur_alloc_type, &cur_ion_flags); 193 194 if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type || 195 cur_ion_flags != prev_ion_flags)) { 196 return false; 197 } 198 199 // For same format type, find the descriptor with bigger size 200 GetAlignedWidthAndHeight(descriptors[i], &alignedw, &alignedh); 201 unsigned int size = GetSize(descriptors[i], alignedw, alignedh); 202 if (max_size < size) { 203 *max_index = INT(i); 204 max_size = size; 205 } 206 207 prev_heap_id = cur_heap_id; 208 prev_uncached = cur_uncached; 209 prev_ion_flags = cur_ion_flags; 210 prev_alloc_type = cur_alloc_type; 211 } 212 213 return true; 214 } 215 216 bool Allocator::IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage, 217 gralloc1_consumer_usage_t cons_usage) { 218 bool tile_enabled = false; 219 220 // Check whether GPU & MDSS supports MacroTiling feature 221 if (!adreno_helper_->IsMacroTilingSupportedByGPU() || !display_support_macrotile) { 222 return tile_enabled; 223 } 224 225 // check the format 226 switch (format) { 227 case HAL_PIXEL_FORMAT_RGBA_8888: 228 case HAL_PIXEL_FORMAT_RGBX_8888: 229 case HAL_PIXEL_FORMAT_BGRA_8888: 230 case HAL_PIXEL_FORMAT_RGB_565: 231 case HAL_PIXEL_FORMAT_BGR_565: 232 if (!CpuCanAccess(prod_usage, cons_usage)) { 233 // not touched by CPU 234 tile_enabled = true; 235 } 236 break; 237 default: 238 break; 239 } 240 241 return tile_enabled; 242 } 243 244 // helper function 245 unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int alignedw, 246 unsigned int alignedh) { 247 unsigned int size = 0; 248 int format = descriptor.GetFormat(); 249 int width = descriptor.GetWidth(); 250 int height = descriptor.GetHeight(); 251 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage(); 252 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage(); 253 254 if (IsUBwcEnabled(format, prod_usage, cons_usage)) { 255 return GetUBwcSize(width, height, format, alignedw, alignedh); 256 } 257 258 if (IsUncompressedRGBFormat(format)) { 259 uint32_t bpp = GetBppForUncompressedRGB(format); 260 size = alignedw * alignedh * bpp; 261 return size; 262 } 263 264 if (IsCompressedRGBFormat(format)) { 265 size = alignedw * alignedh * ASTC_BLOCK_SIZE; 266 return size; 267 } 268 269 // Below switch should be for only YUV/custom formats 270 switch (format) { 271 case HAL_PIXEL_FORMAT_RAW16: 272 size = alignedw * alignedh * 2; 273 break; 274 case HAL_PIXEL_FORMAT_RAW10: 275 size = ALIGN(alignedw * alignedh, SIZE_4K); 276 break; 277 278 // adreno formats 279 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: // NV21 280 size = ALIGN(alignedw * alignedh, SIZE_4K); 281 size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K); 282 break; 283 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: // NV12 284 // The chroma plane is subsampled, 285 // but the pitch in bytes is unchanged 286 // The GPU needs 4K alignment, but the video decoder needs 8K 287 size = ALIGN(alignedw * alignedh, SIZE_8K); 288 size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K); 289 break; 290 case HAL_PIXEL_FORMAT_YV12: 291 if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) { 292 ALOGE("w or h is odd for the YV12 format"); 293 return 0; 294 } 295 size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2; 296 size = ALIGN(size, (unsigned int)SIZE_4K); 297 break; 298 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 299 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 300 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K); 301 break; 302 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 303 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 304 case HAL_PIXEL_FORMAT_YCbCr_422_I: 305 case HAL_PIXEL_FORMAT_YCrCb_422_I: 306 if (width & 1) { 307 ALOGE("width is odd for the YUV422_SP format"); 308 return 0; 309 } 310 size = ALIGN(alignedw * alignedh * 2, SIZE_4K); 311 break; 312 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 313 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 314 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height); 315 break; 316 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 317 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height); 318 break; 319 case HAL_PIXEL_FORMAT_BLOB: 320 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 321 if (height != 1) { 322 ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__); 323 return 0; 324 } 325 size = (unsigned int)width; 326 break; 327 case HAL_PIXEL_FORMAT_NV21_ZSL: 328 size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K); 329 break; 330 default: 331 ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format); 332 return 0; 333 } 334 335 return size; 336 } 337 338 void Allocator::GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size, 339 unsigned int *alignedw, unsigned int *alignedh) { 340 BufferDescriptor descriptor = BufferDescriptor(width, height, format); 341 GetAlignedWidthAndHeight(descriptor, alignedw, alignedh); 342 343 *size = GetSize(descriptor, *alignedw, *alignedh); 344 } 345 346 void Allocator::GetBufferSizeAndDimensions(const BufferDescriptor &descriptor, unsigned int *size, 347 unsigned int *alignedw, unsigned int *alignedh) { 348 GetAlignedWidthAndHeight(descriptor, alignedw, alignedh); 349 350 *size = GetSize(descriptor, *alignedw, *alignedh); 351 } 352 353 void Allocator::GetBufferAttributes(const BufferDescriptor &descriptor, unsigned int *alignedw, 354 unsigned int *alignedh, int *tiled, unsigned int *size) { 355 int format = descriptor.GetFormat(); 356 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage(); 357 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage(); 358 359 *tiled = false; 360 if (IsUBwcEnabled(format, prod_usage, cons_usage) || 361 IsMacroTileEnabled(format, prod_usage, cons_usage)) { 362 *tiled = true; 363 } 364 365 GetAlignedWidthAndHeight(descriptor, alignedw, alignedh); 366 *size = GetSize(descriptor, *alignedw, *alignedh); 367 } 368 369 void Allocator::GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, 370 int color_format, struct android_ycbcr *ycbcr) { 371 // UBWC buffer has these 4 planes in the following sequence: 372 // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane 373 unsigned int y_meta_stride, y_meta_height, y_meta_size; 374 unsigned int y_stride, y_height, y_size; 375 unsigned int c_meta_stride, c_meta_height, c_meta_size; 376 unsigned int alignment = 4096; 377 378 y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width)); 379 y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height)); 380 y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment); 381 382 y_stride = VENUS_Y_STRIDE(color_format, INT(width)); 383 y_height = VENUS_Y_SCANLINES(color_format, INT(height)); 384 y_size = ALIGN((y_stride * y_height), alignment); 385 386 c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width)); 387 c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height)); 388 c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment); 389 390 ycbcr->y = reinterpret_cast<void *>(base + y_meta_size); 391 ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size); 392 ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1); 393 ycbcr->ystride = y_stride; 394 ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width)); 395 } 396 397 void Allocator::GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp, 398 struct android_ycbcr *ycbcr) { 399 unsigned int ystride, cstride; 400 401 ystride = cstride = UINT(width) * bpp; 402 ycbcr->y = reinterpret_cast<void *>(base); 403 ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height)); 404 ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1); 405 ycbcr->ystride = ystride; 406 ycbcr->cstride = cstride; 407 ycbcr->chroma_step = 2 * bpp; 408 } 409 410 int Allocator::GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) { 411 int err = 0; 412 uint32_t width = UINT(hnd->width); 413 uint32_t height = UINT(hnd->height); 414 int format = hnd->format; 415 gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage(); 416 gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage(); 417 unsigned int ystride, cstride; 418 419 memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); 420 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata); 421 422 // Check if UBWC buffer has been rendered in linear format. 423 if (metadata && (metadata->operation & LINEAR_FORMAT)) { 424 format = INT(metadata->linearFormat); 425 } 426 427 // Check metadata if the geometry has been updated. 428 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { 429 int usage = 0; 430 431 if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) { 432 usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC; 433 } 434 435 BufferDescriptor descriptor = 436 BufferDescriptor(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format, 437 prod_usage, cons_usage); 438 GetAlignedWidthAndHeight(descriptor, &width, &height); 439 } 440 441 // Get the chroma offsets from the handle width/height. We take advantage 442 // of the fact the width _is_ the stride 443 switch (format) { 444 // Semiplanar 445 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 446 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 447 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 448 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 449 // Same as YCbCr_420_SP_VENUS 450 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr); 451 break; 452 453 case HAL_PIXEL_FORMAT_YCbCr_420_P010: 454 GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr); 455 break; 456 457 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 458 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr); 459 ycbcr->chroma_step = 2; 460 break; 461 462 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 463 GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr); 464 ycbcr->chroma_step = 3; 465 break; 466 467 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 468 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 469 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 470 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 471 case HAL_PIXEL_FORMAT_NV21_ZSL: 472 case HAL_PIXEL_FORMAT_RAW16: 473 case HAL_PIXEL_FORMAT_RAW10: 474 GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr); 475 std::swap(ycbcr->cb, ycbcr->cr); 476 break; 477 478 // Planar 479 case HAL_PIXEL_FORMAT_YV12: 480 ystride = width; 481 cstride = ALIGN(width / 2, 16); 482 ycbcr->y = reinterpret_cast<void *>(hnd->base); 483 ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height); 484 ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2); 485 ycbcr->ystride = ystride; 486 ycbcr->cstride = cstride; 487 ycbcr->chroma_step = 1; 488 break; 489 490 // Unsupported formats 491 case HAL_PIXEL_FORMAT_YCbCr_422_I: 492 case HAL_PIXEL_FORMAT_YCrCb_422_I: 493 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 494 default: 495 ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format); 496 err = -EINVAL; 497 } 498 499 return err; 500 } 501 502 int Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage, 503 gralloc1_consumer_usage_t cons_usage, int format) { 504 int gr_format = format; 505 506 // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on 507 // the usage bits, gralloc assigns a format. 508 if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED || 509 format == HAL_PIXEL_FORMAT_YCbCr_420_888) { 510 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) { 511 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC; 512 } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) { 513 gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; // NV12 514 } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL) { 515 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21 ZSL 516 } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) { 517 gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; // NV21 518 } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) { 519 if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { 520 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; // NV21 521 } else { 522 gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS; // NV12 preview 523 } 524 } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) { 525 // XXX: If we still haven't set a format, default to RGBA8888 526 gr_format = HAL_PIXEL_FORMAT_RGBA_8888; 527 } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) { 528 // If no other usage flags are detected, default the 529 // flexible YUV format to NV21_ZSL 530 gr_format = HAL_PIXEL_FORMAT_NV21_ZSL; 531 } 532 } 533 534 return gr_format; 535 } 536 537 // Explicitly defined UBWC formats 538 bool Allocator::IsUBwcFormat(int format) { 539 switch (format) { 540 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 541 return true; 542 default: 543 return false; 544 } 545 } 546 547 bool Allocator::IsUBwcSupported(int format) { 548 // Existing HAL formats with UBWC support 549 switch (format) { 550 case HAL_PIXEL_FORMAT_BGR_565: 551 case HAL_PIXEL_FORMAT_RGBA_8888: 552 case HAL_PIXEL_FORMAT_RGBX_8888: 553 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 554 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 555 return true; 556 default: 557 break; 558 } 559 560 return false; 561 } 562 563 /* The default policy is to return cached buffers unless the client explicity 564 * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely 565 * read or written in software. */ 566 // TODO(user) : As of now relying only on producer usage 567 bool Allocator::UseUncached(gralloc1_producer_usage_t usage) { 568 if ((usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED) || 569 (usage & GRALLOC1_PRODUCER_USAGE_PROTECTED)) { 570 return true; 571 } 572 573 // CPU read rarely 574 if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) && 575 !(usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)) { 576 return true; 577 } 578 579 // CPU write rarely 580 if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) && 581 !(usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) { 582 return true; 583 } 584 585 return false; 586 } 587 588 void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage, 589 gralloc1_consumer_usage_t cons_usage, unsigned int *ion_heap_id, 590 unsigned int *alloc_type, unsigned int *ion_flags) { 591 unsigned int heap_id = 0; 592 unsigned int type = 0; 593 int flags = 0; 594 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) { 595 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) { 596 heap_id = ION_HEAP(SD_HEAP_ID); 597 /* 598 * There is currently no flag in ION for Secure Display 599 * VM. Please add it to the define once available. 600 */ 601 flags |= ION_SD_FLAGS; 602 } else { 603 heap_id = ION_HEAP(CP_HEAP_ID); 604 flags |= ION_CP_FLAGS; 605 } 606 } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP) { 607 // MM Heap is exclusively a secure heap. 608 // If it is used for non secure cases, fallback to IOMMU heap 609 ALOGW("MM_HEAP cannot be used as an insecure heap. Using system heap instead!!"); 610 heap_id |= ION_HEAP(ION_SYSTEM_HEAP_ID); 611 } 612 613 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP) { 614 heap_id |= ION_HEAP(ION_CAMERA_HEAP_ID); 615 } 616 617 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP) { 618 heap_id |= ION_HEAP(ION_ADSP_HEAP_ID); 619 } 620 621 if (flags & ION_SECURE) { 622 type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER; 623 } 624 625 // if no ion heap flags are set, default to system heap 626 if (!heap_id) { 627 heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID); 628 } 629 630 *alloc_type = type; 631 *ion_flags = (unsigned int)flags; 632 *ion_heap_id = heap_id; 633 634 return; 635 } 636 637 bool Allocator::IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage, 638 gralloc1_consumer_usage_t cons_usage) { 639 // Allow UBWC, if client is using an explicitly defined UBWC pixel format. 640 if (IsUBwcFormat(format)) { 641 return true; 642 } 643 644 // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP 645 // support the format. OR if a non-OpenGL client like Rotator, sets UBWC 646 // usage flag and MDP supports the format. 647 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) { 648 bool enable = true; 649 // Query GPU for UBWC only if buffer is intended to be used by GPU. 650 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) || 651 (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) { 652 enable = adreno_helper_->IsUBWCSupportedByGPU(format); 653 } 654 655 // Allow UBWC, only if CPU usage flags are not set 656 if (enable && !(CpuCanAccess(prod_usage, cons_usage))) { 657 return true; 658 } 659 } 660 661 return false; 662 } 663 664 void Allocator::GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w, 665 unsigned int *aligned_h) { 666 switch (format) { 667 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 668 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 669 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 670 *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width); 671 *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height); 672 break; 673 default: 674 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); 675 *aligned_w = 0; 676 *aligned_h = 0; 677 break; 678 } 679 } 680 681 void Allocator::GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) { 682 *block_width = 0; 683 *block_height = 0; 684 685 switch (bpp) { 686 case 2: 687 case 4: 688 *block_width = 16; 689 *block_height = 4; 690 break; 691 case 8: 692 *block_width = 8; 693 *block_height = 4; 694 break; 695 case 16: 696 *block_width = 4; 697 *block_height = 4; 698 break; 699 default: 700 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); 701 break; 702 } 703 } 704 705 unsigned int Allocator::GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) { 706 unsigned int size = 0; 707 int meta_width, meta_height; 708 int block_width, block_height; 709 710 GetRgbUBwcBlockSize(bpp, &block_width, &block_height); 711 if (!block_width || !block_height) { 712 ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp); 713 return size; 714 } 715 716 // Align meta buffer height to 16 blocks 717 meta_height = ALIGN(((height + block_height - 1) / block_height), 16); 718 719 // Align meta buffer width to 64 blocks 720 meta_width = ALIGN(((width + block_width - 1) / block_width), 64); 721 722 // Align meta buffer size to 4K 723 size = (unsigned int)ALIGN((meta_width * meta_height), 4096); 724 725 return size; 726 } 727 728 unsigned int Allocator::GetUBwcSize(int width, int height, int format, unsigned int alignedw, 729 unsigned int alignedh) { 730 unsigned int size = 0; 731 uint32_t bpp = 0; 732 switch (format) { 733 case HAL_PIXEL_FORMAT_BGR_565: 734 case HAL_PIXEL_FORMAT_RGBA_8888: 735 case HAL_PIXEL_FORMAT_RGBX_8888: 736 case HAL_PIXEL_FORMAT_RGBA_1010102: 737 case HAL_PIXEL_FORMAT_RGBX_1010102: 738 bpp = GetBppForUncompressedRGB(format); 739 size = alignedw * alignedh * bpp; 740 size += GetRgbUBwcMetaBufferSize(width, height, bpp); 741 break; 742 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 743 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 744 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 745 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height); 746 break; 747 case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC: 748 size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height); 749 break; 750 default: 751 ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format); 752 break; 753 } 754 755 return size; 756 } 757 758 int Allocator::GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) { 759 int err = 0; 760 761 // This api is for RGB* formats 762 if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) { 763 return -EINVAL; 764 } 765 766 // linear buffer, nothing to do further 767 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) { 768 *rgb_data = reinterpret_cast<void *>(hnd->base); 769 return err; 770 } 771 772 unsigned int meta_size = 0; 773 uint32_t bpp = GetBppForUncompressedRGB(hnd->format); 774 switch (hnd->format) { 775 case HAL_PIXEL_FORMAT_BGR_565: 776 case HAL_PIXEL_FORMAT_RGBA_8888: 777 case HAL_PIXEL_FORMAT_RGBX_8888: 778 meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp); 779 break; 780 default: 781 ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format); 782 err = -EINVAL; 783 break; 784 } 785 *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size); 786 787 return err; 788 } 789 790 void Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, unsigned int *alignedw, 791 unsigned int *alignedh) { 792 int width = descriptor.GetWidth(); 793 int height = descriptor.GetHeight(); 794 int format = descriptor.GetFormat(); 795 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage(); 796 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage(); 797 798 // Currently surface padding is only computed for RGB* surfaces. 799 bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage); 800 int tile = ubwc_enabled || IsMacroTileEnabled(format, prod_usage, cons_usage); 801 802 if (IsUncompressedRGBFormat(format)) { 803 adreno_helper_->AlignUnCompressedRGB(width, height, format, tile, alignedw, alignedh); 804 return; 805 } 806 807 if (ubwc_enabled) { 808 GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh); 809 return; 810 } 811 812 if (IsCompressedRGBFormat(format)) { 813 adreno_helper_->AlignCompressedRGB(width, height, format, alignedw, alignedh); 814 return; 815 } 816 817 int aligned_w = width; 818 int aligned_h = height; 819 unsigned int alignment = 32; 820 821 // Below should be only YUV family 822 switch (format) { 823 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 824 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 825 alignment = adreno_helper_->GetGpuPixelAlignment(); 826 aligned_w = ALIGN(width, alignment); 827 break; 828 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 829 aligned_w = ALIGN(width, alignment); 830 break; 831 case HAL_PIXEL_FORMAT_RAW16: 832 aligned_w = ALIGN(width, 16); 833 break; 834 case HAL_PIXEL_FORMAT_RAW10: 835 aligned_w = ALIGN(width * 10 / 8, 16); 836 break; 837 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: 838 aligned_w = ALIGN(width, 128); 839 break; 840 case HAL_PIXEL_FORMAT_YV12: 841 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 842 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 843 case HAL_PIXEL_FORMAT_YCbCr_422_I: 844 case HAL_PIXEL_FORMAT_YCrCb_422_I: 845 aligned_w = ALIGN(width, 16); 846 break; 847 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 848 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 849 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width)); 850 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height)); 851 break; 852 case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS: 853 aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width)); 854 aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height)); 855 break; 856 case HAL_PIXEL_FORMAT_BLOB: 857 case HAL_PIXEL_FORMAT_RAW_OPAQUE: 858 break; 859 case HAL_PIXEL_FORMAT_NV21_ZSL: 860 aligned_w = ALIGN(width, 64); 861 aligned_h = ALIGN(height, 64); 862 break; 863 default: 864 break; 865 } 866 867 *alignedw = (unsigned int)aligned_w; 868 *alignedh = (unsigned int)aligned_h; 869 } 870 871 } // namespace gralloc1 872