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