1/* 2 * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. 3 * Not a Contribution 4 * 5 * Copyright (C) 2010 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20#include <utility> 21#include <vector> 22 23#include "qd_utils.h" 24#include "gr_priv_handle.h" 25#include "gr_buf_descriptor.h" 26#include "gr_utils.h" 27#include "gr_buf_mgr.h" 28#include "qdMetaData.h" 29 30namespace gralloc1 { 31std::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1); 32 33BufferManager::BufferManager() : next_id_(0) { 34 char property[PROPERTY_VALUE_MAX]; 35 36 // Map framebuffer memory 37 if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) && 38 (!strncmp(property, "1", PROPERTY_VALUE_MAX) || 39 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) { 40 map_fb_mem_ = true; 41 } 42 43 // Enable UBWC for framebuffer 44 if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) && 45 (!strncmp(property, "1", PROPERTY_VALUE_MAX) || 46 (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) { 47 ubwc_for_fb_ = true; 48 } 49 50 handles_map_.clear(); 51 allocator_ = new Allocator(); 52 allocator_->Init(); 53} 54 55 56gralloc1_error_t BufferManager::CreateBufferDescriptor( 57 gralloc1_buffer_descriptor_t *descriptor_id) { 58 std::lock_guard<std::mutex> lock(locker_); 59 auto descriptor = std::make_shared<BufferDescriptor>(); 60 descriptors_map_.emplace(descriptor->GetId(), descriptor); 61 *descriptor_id = descriptor->GetId(); 62 return GRALLOC1_ERROR_NONE; 63} 64 65gralloc1_error_t BufferManager::DestroyBufferDescriptor( 66 gralloc1_buffer_descriptor_t descriptor_id) { 67 std::lock_guard<std::mutex> lock(locker_); 68 const auto descriptor = descriptors_map_.find(descriptor_id); 69 if (descriptor == descriptors_map_.end()) { 70 return GRALLOC1_ERROR_BAD_DESCRIPTOR; 71 } 72 descriptors_map_.erase(descriptor); 73 return GRALLOC1_ERROR_NONE; 74} 75 76BufferManager::~BufferManager() { 77 if (allocator_) { 78 delete allocator_; 79 } 80} 81 82gralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors, 83 const gralloc1_buffer_descriptor_t *descriptor_ids, 84 buffer_handle_t *out_buffers) { 85 bool shared = true; 86 gralloc1_error_t status = GRALLOC1_ERROR_NONE; 87 88 // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported 89 // client can ask to test the allocation by passing NULL out_buffers 90 bool test_allocate = !out_buffers; 91 92 // Validate descriptors 93 std::vector<std::shared_ptr<BufferDescriptor>> descriptors; 94 for (uint32_t i = 0; i < num_descriptors; i++) { 95 const auto map_descriptor = descriptors_map_.find(descriptor_ids[i]); 96 if (map_descriptor == descriptors_map_.end()) { 97 return GRALLOC1_ERROR_BAD_DESCRIPTOR; 98 } else { 99 descriptors.push_back(map_descriptor->second); 100 } 101 } 102 103 // Resolve implementation defined formats 104 for (auto &descriptor : descriptors) { 105 descriptor->SetColorFormat(allocator_->GetImplDefinedFormat(descriptor->GetProducerUsage(), 106 descriptor->GetConsumerUsage(), 107 descriptor->GetFormat())); 108 } 109 110 // Check if input descriptors can be supported AND 111 // Find out if a single buffer can be shared for all the given input descriptors 112 uint32_t i = 0; 113 ssize_t max_buf_index = -1; 114 shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index); 115 116 if (test_allocate) { 117 status = shared ? GRALLOC1_ERROR_NOT_SHARED : status; 118 return status; 119 } 120 121 if (shared && (max_buf_index >= 0)) { 122 // Allocate one and duplicate/copy the handles for each descriptor 123 if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) { 124 return GRALLOC1_ERROR_NO_RESOURCES; 125 } 126 127 for (i = 0; i < num_descriptors; i++) { 128 // Create new handle for a given descriptor. 129 // Current assumption is even MetaData memory would be same 130 // Need to revisit if there is a need for own metadata memory 131 if (i != UINT(max_buf_index)) { 132 CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]); 133 } 134 } 135 } else { 136 // Buffer sharing is not feasible. 137 // Allocate separate buffer for each descriptor 138 for (i = 0; i < num_descriptors; i++) { 139 if (AllocateBuffer(*descriptors[i], &out_buffers[i])) { 140 return GRALLOC1_ERROR_NO_RESOURCES; 141 } 142 } 143 } 144 145 // Allocation is successful. If backstore is not shared inform the client. 146 if (!shared) { 147 return GRALLOC1_ERROR_NOT_SHARED; 148 } 149 150 return status; 151} 152 153void BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor, 154 buffer_handle_t *outbuffer) { 155 private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer); 156 157 // Get Buffer attributes or dimension 158 unsigned int alignedw = 0, alignedh = 0; 159 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh); 160 161 // create new handle from input reference handle and given descriptor 162 int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(), 163 descriptor.GetConsumerUsage()); 164 int buffer_type = GetBufferType(descriptor.GetFormat()); 165 166 // Duplicate the fds 167 // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions? 168 private_handle_t *out_hnd = new private_handle_t(dup(input->fd), 169 dup(input->fd_metadata), 170 flags, 171 INT(alignedw), 172 INT(alignedh), 173 descriptor.GetWidth(), 174 descriptor.GetHeight(), 175 descriptor.GetFormat(), 176 buffer_type, 177 input->size, 178 descriptor.GetProducerUsage(), 179 descriptor.GetConsumerUsage()); 180 out_hnd->id = ++next_id_; 181 // TODO(user): Base address of shared handle and ion handles 182 auto buffer = std::make_shared<Buffer>(out_hnd); 183 handles_map_.emplace(std::make_pair(out_hnd, buffer)); 184 *outbuffer = out_hnd; 185} 186 187gralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) { 188 auto hnd = buf->handle; 189 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset, 190 hnd->fd, buf->ion_handle_main) != 0) { 191 return GRALLOC1_ERROR_BAD_HANDLE; 192 } 193 194 unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE); 195 if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size, 196 hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) { 197 return GRALLOC1_ERROR_BAD_HANDLE; 198 } 199 200 // TODO(user): delete handle once framework bug around this is confirmed 201 // to be resolved. This is tracked in bug 36355756 202 private_handle_t * handle = const_cast<private_handle_t *>(hnd); 203 handle->fd = -1; 204 handle->fd_metadata = -1; 205 return GRALLOC1_ERROR_NONE; 206} 207 208gralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) { 209 private_handle_t *hnd = const_cast<private_handle_t *>(handle); 210 211 hnd->base = 0; 212 hnd->base_metadata = 0; 213 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset, 214 hnd->fd) != 0) { 215 return GRALLOC1_ERROR_BAD_HANDLE; 216 } 217 218 unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE); 219 if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size, 220 hnd->offset_metadata, hnd->fd_metadata) != 0) { 221 return GRALLOC1_ERROR_BAD_HANDLE; 222 } 223 224 return GRALLOC1_ERROR_NONE; 225} 226 227gralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) { 228 std::lock_guard<std::mutex> lock(locker_); 229 230 // find if this handle is already in map 231 auto it = handles_map_.find(hnd); 232 if (it != handles_map_.end()) { 233 // It's already in map, Just increment refcnt 234 // No need to mmap the memory. 235 auto buf = it->second; 236 buf->ref_count++; 237 } else { 238 // not present in the map. mmap and then add entry to map 239 if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) { 240 auto buffer = std::make_shared<Buffer>(hnd); 241 handles_map_.emplace(std::make_pair(hnd, buffer)); 242 } 243 } 244 245 return GRALLOC1_ERROR_NONE; 246} 247 248gralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) { 249 std::lock_guard<std::mutex> lock(locker_); 250 // find if this handle is already in map 251 auto it = handles_map_.find(hnd); 252 if (it == handles_map_.end()) { 253 // Corrupt handle or map. 254 ALOGE("Could not find handle"); 255 return GRALLOC1_ERROR_BAD_HANDLE; 256 } else { 257 auto buf = it->second; 258 buf->ref_count--; 259 if (buf->ref_count == 0) { 260 handles_map_.erase(it); 261 FreeBuffer(buf); 262 } 263 } 264 return GRALLOC1_ERROR_NONE; 265} 266 267gralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd, 268 gralloc1_producer_usage_t prod_usage, 269 gralloc1_consumer_usage_t cons_usage) { 270 gralloc1_error_t err = GRALLOC1_ERROR_NONE; 271 272 // If buffer is not meant for CPU return err 273 if (!CpuCanAccess(prod_usage, cons_usage)) { 274 return GRALLOC1_ERROR_BAD_VALUE; 275 } 276 277 if (hnd->base == 0) { 278 // we need to map for real 279 locker_.lock(); 280 err = MapBuffer(hnd); 281 locker_.unlock(); 282 } 283 284 // Invalidate if CPU reads in software and there are non-CPU 285 // writers. No need to do this for the metadata buffer as it is 286 // only read/written in software. 287 if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) && 288 (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) { 289 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset, 290 hnd->fd, CACHE_INVALIDATE)) { 291 return GRALLOC1_ERROR_BAD_HANDLE; 292 } 293 } 294 295 // Mark the buffer to be flushed after CPU write. 296 if (!err && CpuCanWrite(prod_usage)) { 297 private_handle_t *handle = const_cast<private_handle_t *>(hnd); 298 handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 299 } 300 301 return err; 302} 303 304gralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) { 305 gralloc1_error_t status = GRALLOC1_ERROR_NONE; 306 307 locker_.lock(); 308 private_handle_t *hnd = const_cast<private_handle_t *>(handle); 309 310 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) { 311 if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset, 312 hnd->fd, CACHE_CLEAN) != 0) { 313 status = GRALLOC1_ERROR_BAD_HANDLE; 314 } 315 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH; 316 } 317 318 locker_.unlock(); 319 return status; 320} 321 322uint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage, 323 gralloc1_consumer_usage_t cons_usage) { 324 uint32_t align = UINT(getpagesize()); 325 if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) { 326 align = 8192; 327 } 328 329 if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) { 330 if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) || 331 (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) { 332 // The alignment here reflects qsee mmu V7L/V8L requirement 333 align = SZ_2M; 334 } else { 335 align = SECURE_ALIGN; 336 } 337 } 338 339 return align; 340} 341 342int BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage, 343 gralloc1_consumer_usage_t cons_usage) { 344 int flags = 0; 345 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) { 346 flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY; 347 } 348 349 if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) { 350 flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY; 351 } 352 353 if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) { 354 flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER; 355 } 356 357 if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) { 358 flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE; 359 } 360 361 if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) { 362 flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ; 363 } 364 365 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) { 366 flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER; 367 } 368 369 if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) { 370 flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE; 371 } 372 373 if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) { 374 flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY; 375 } 376 377 if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) { 378 flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 379 } 380 381 if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) { 382 flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED; 383 } 384 385 // TODO(user): is this correct??? 386 if ((cons_usage & 387 (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) || 388 (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) { 389 flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER; 390 } 391 392 if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) { 393 flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER; 394 } 395 396 if (!allocator_->UseUncached(prod_usage)) { 397 flags |= private_handle_t::PRIV_FLAGS_CACHED; 398 } 399 400 return flags; 401} 402 403int BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int unaligned_w, 404 int unaligned_h, int format, int bufferType, 405 gralloc1_producer_usage_t prod_usage, 406 gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) { 407 auto page_size = UINT(getpagesize()); 408 int err = 0; 409 int flags = 0; 410 AllocData data; 411 data.align = GetDataAlignment(format, prod_usage, cons_usage); 412 data.size = ALIGN(size, data.align); 413 data.handle = (uintptr_t)handle; 414 data.uncached = allocator_->UseUncached(prod_usage); 415 416 // Allocate buffer memory 417 err = allocator_->AllocateMem(&data, prod_usage, cons_usage); 418 if (err) { 419 ALOGE("gralloc failed to allocate err=%s", strerror(-err)); 420 return err; 421 } 422 423 // Allocate memory for MetaData 424 AllocData e_data; 425 e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size); 426 e_data.handle = data.handle; 427 e_data.align = page_size; 428 429 err = 430 allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE); 431 if (err) { 432 ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err)); 433 return err; 434 } 435 436 flags = GetHandleFlags(format, prod_usage, cons_usage); 437 flags |= data.alloc_type; 438 439 // Create handle 440 private_handle_t *hnd = new private_handle_t(data.fd, 441 e_data.fd, 442 flags, 443 aligned_w, 444 aligned_h, 445 unaligned_w, 446 unaligned_h, 447 format, 448 bufferType, 449 size, 450 prod_usage, 451 cons_usage); 452 453 hnd->id = ++next_id_; 454 hnd->base = reinterpret_cast<uint64_t >(data.base); 455 hnd->base_metadata = reinterpret_cast<uint64_t >(e_data.base); 456 457 ColorSpace_t colorSpace = ITU_R_601; 458 setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace)); 459 *handle = hnd; 460 auto buffer = std::make_shared<Buffer>(hnd, data.ion_handle, e_data.ion_handle); 461 handles_map_.emplace(std::make_pair(hnd, buffer)); 462 return err; 463} 464 465int BufferManager::GetBufferType(int inputFormat) { 466 int buffer_type = BUFFER_TYPE_VIDEO; 467 if (IsUncompressedRGBFormat(inputFormat)) { 468 // RGB formats 469 buffer_type = BUFFER_TYPE_UI; 470 } 471 472 return buffer_type; 473} 474 475int BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle, 476 unsigned int bufferSize) { 477 if (!handle) 478 return -EINVAL; 479 480 int format = descriptor.GetFormat(); 481 gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage(); 482 gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage(); 483 484 // Get implementation defined format 485 int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format); 486 487 bool use_fb_mem = false; 488 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && map_fb_mem_) { 489 use_fb_mem = true; 490 } 491 492 if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && ubwc_for_fb_) { 493 prod_usage = 494 (gralloc1_producer_usage_t)(prod_usage | GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC); 495 } 496 497 unsigned int size; 498 unsigned int alignedw, alignedh; 499 int buffer_type = GetBufferType(gralloc_format); 500 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh); 501 502 size = (bufferSize >= size) ? bufferSize : size; 503 504 int err = 0; 505 if (use_fb_mem) { 506 // TODO(user): TBD Framebuffer specific implementation in a seperate file/class 507 } else { 508 err = AllocateBuffer(size, INT(alignedw), INT(alignedh), descriptor.GetWidth(), 509 descriptor.GetHeight(), format, buffer_type, descriptor.GetProducerUsage(), 510 descriptor.GetConsumerUsage(), handle); 511 } 512 513 if (err < 0) { 514 return err; 515 } 516 517 return 0; 518} 519 520gralloc1_error_t BufferManager::Perform(int operation, va_list args) { 521 switch (operation) { 522 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: { 523 int fd = va_arg(args, int); 524 unsigned int size = va_arg(args, unsigned int); 525 unsigned int offset = va_arg(args, unsigned int); 526 void *base = va_arg(args, void *); 527 int width = va_arg(args, int); 528 int height = va_arg(args, int); 529 int format = va_arg(args, int); 530 531 native_handle_t **handle = va_arg(args, native_handle_t **); 532 private_handle_t *hnd = reinterpret_cast<private_handle_t *>( 533 native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts())); 534 if (hnd) { 535 unsigned int alignedw = 0, alignedh = 0; 536 hnd->magic = private_handle_t::kMagic; 537 hnd->fd = fd; 538 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION; 539 hnd->size = size; 540 hnd->offset = offset; 541 hnd->base = uint64_t(base) + offset; 542 hnd->gpuaddr = 0; 543 BufferDescriptor descriptor(width, height, format); 544 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh); 545 hnd->unaligned_width = width; 546 hnd->unaligned_height = height; 547 hnd->width = INT(alignedw); 548 hnd->height = INT(alignedh); 549 hnd->format = format; 550 *handle = reinterpret_cast<native_handle_t *>(hnd); 551 } 552 } break; 553 554 case GRALLOC_MODULE_PERFORM_GET_STRIDE: { 555 int width = va_arg(args, int); 556 int format = va_arg(args, int); 557 int *stride = va_arg(args, int *); 558 unsigned int alignedw = 0, alignedh = 0; 559 BufferDescriptor descriptor(width, width, format); 560 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh); 561 *stride = INT(alignedw); 562 } break; 563 564 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: { 565 private_handle_t *hnd = va_arg(args, private_handle_t *); 566 int *stride = va_arg(args, int *); 567 if (private_handle_t::validate(hnd) != 0) { 568 return GRALLOC1_ERROR_BAD_HANDLE; 569 } 570 571 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata); 572 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { 573 *stride = metadata->bufferDim.sliceWidth; 574 } else { 575 *stride = hnd->width; 576 } 577 } break; 578 579 // TODO(user) : this alone should be sufficient, ask gfx to get rid of above 580 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: { 581 private_handle_t *hnd = va_arg(args, private_handle_t *); 582 int *stride = va_arg(args, int *); 583 int *height = va_arg(args, int *); 584 if (private_handle_t::validate(hnd) != 0) { 585 return GRALLOC1_ERROR_BAD_HANDLE; 586 } 587 588 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata); 589 if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) { 590 *stride = metadata->bufferDim.sliceWidth; 591 *height = metadata->bufferDim.sliceHeight; 592 } else { 593 *stride = hnd->width; 594 *height = hnd->height; 595 } 596 } break; 597 598 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: { 599 // TODO(user): Usage is split now. take care of it from Gfx client. 600 // see if we can directly expect descriptor from gfx client. 601 int width = va_arg(args, int); 602 int height = va_arg(args, int); 603 int format = va_arg(args, int); 604 uint64_t producer_usage = va_arg(args, uint64_t); 605 uint64_t consumer_usage = va_arg(args, uint64_t); 606 gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage); 607 gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage); 608 609 int *aligned_width = va_arg(args, int *); 610 int *aligned_height = va_arg(args, int *); 611 int *tile_enabled = va_arg(args, int *); 612 unsigned int alignedw, alignedh; 613 BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage); 614 *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage); 615 616 allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh); 617 *aligned_width = INT(alignedw); 618 *aligned_height = INT(alignedh); 619 } break; 620 621 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: { 622 private_handle_t *hnd = va_arg(args, private_handle_t *); 623 int *color_space = va_arg(args, int *); 624 if (private_handle_t::validate(hnd) != 0) { 625 return GRALLOC1_ERROR_BAD_HANDLE; 626 } 627 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata); 628 if (!metadata) { 629 return GRALLOC1_ERROR_BAD_HANDLE; 630#ifdef USE_COLOR_METADATA 631 } else if (metadata->operation & COLOR_METADATA) { 632 ColorMetaData *colorMetadata = &metadata->color; 633 switch (colorMetadata->colorPrimaries) { 634 case ColorPrimaries_BT709_5: 635 *color_space = HAL_CSC_ITU_R_709; 636 break; 637 case ColorPrimaries_BT601_6_525: 638 *color_space = ((colorMetadata->range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601); 639 break; 640 case ColorPrimaries_BT2020: 641 *color_space = (colorMetadata->range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020; 642 break; 643 default: 644 ALOGE("Unknown Color Space = %d", colorMetadata->colorPrimaries); 645 break; 646 } 647#endif 648 } else if (metadata->operation & UPDATE_COLOR_SPACE) { 649 *color_space = metadata->colorSpace; 650 } 651 } break; 652 case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: { 653 private_handle_t *hnd = va_arg(args, private_handle_t *); 654 android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *); 655 if (private_handle_t::validate(hnd) != 0) { 656 return GRALLOC1_ERROR_BAD_HANDLE; 657 } 658 if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) { 659 return GRALLOC1_ERROR_UNDEFINED; 660 } 661 } break; 662 663 case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: { 664 private_handle_t *hnd = va_arg(args, private_handle_t *); 665 int *map_secure_buffer = va_arg(args, int *); 666 if (private_handle_t::validate(hnd) != 0) { 667 return GRALLOC1_ERROR_BAD_HANDLE; 668 } 669 MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata); 670 if (metadata && metadata->operation & MAP_SECURE_BUFFER) { 671 *map_secure_buffer = metadata->mapSecureBuffer; 672 } else { 673 *map_secure_buffer = 0; 674 } 675 } break; 676 677 case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: { 678 private_handle_t *hnd = va_arg(args, private_handle_t *); 679 int *flag = va_arg(args, int *); 680 if (private_handle_t::validate(hnd) != 0) { 681 return GRALLOC1_ERROR_BAD_HANDLE; 682 } 683 *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED; 684 } break; 685 686 case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: { 687 private_handle_t *hnd = va_arg(args, private_handle_t *); 688 void **rgb_data = va_arg(args, void **); 689 if (private_handle_t::validate(hnd) != 0) { 690 return GRALLOC1_ERROR_BAD_HANDLE; 691 } 692 if (allocator_->GetRgbDataAddress(hnd, rgb_data)) { 693 return GRALLOC1_ERROR_UNDEFINED; 694 } 695 } break; 696 697 case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: { 698 int width = va_arg(args, int); 699 int height = va_arg(args, int); 700 int format = va_arg(args, int); 701 uint64_t p_usage = va_arg(args, uint64_t); 702 uint64_t c_usage = va_arg(args, uint64_t); 703 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage); 704 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage); 705 uint32_t *aligned_width = va_arg(args, uint32_t *); 706 uint32_t *aligned_height = va_arg(args, uint32_t *); 707 uint32_t *size = va_arg(args, uint32_t *); 708 auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage); 709 allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height); 710 // Align size 711 auto align = GetDataAlignment(format, producer_usage, consumer_usage); 712 *size = ALIGN(*size, align); 713 } break; 714 715 // TODO(user): Break out similar functionality, preferably moving to a common lib. 716 717 case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: { 718 int width = va_arg(args, int); 719 int height = va_arg(args, int); 720 int format = va_arg(args, int); 721 uint64_t p_usage = va_arg(args, uint64_t); 722 uint64_t c_usage = va_arg(args, uint64_t); 723 buffer_handle_t *hnd = va_arg(args, buffer_handle_t*); 724 gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage); 725 gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage); 726 BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage); 727 unsigned int size; 728 unsigned int alignedw, alignedh; 729 allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh); 730 AllocateBuffer(descriptor, hnd, size); 731 } break; 732 733 default: 734 break; 735 } 736 return GRALLOC1_ERROR_NONE; 737} 738 739static bool IsYuvFormat(const private_handle_t *hnd) { 740 switch (hnd->format) { 741 case HAL_PIXEL_FORMAT_YCbCr_420_SP: 742 case HAL_PIXEL_FORMAT_YCbCr_422_SP: 743 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS: 744 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: // Same as YCbCr_420_SP_VENUS 745 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC: 746 case HAL_PIXEL_FORMAT_YCrCb_420_SP: 747 case HAL_PIXEL_FORMAT_YCrCb_422_SP: 748 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: 749 case HAL_PIXEL_FORMAT_NV21_ZSL: 750 case HAL_PIXEL_FORMAT_RAW16: 751 case HAL_PIXEL_FORMAT_RAW10: 752 case HAL_PIXEL_FORMAT_YV12: 753 return true; 754 default: 755 return false; 756 } 757} 758 759gralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd, 760 uint32_t *out_num_planes) { 761 if (!IsYuvFormat(hnd)) { 762 return GRALLOC1_ERROR_UNSUPPORTED; 763 } else { 764 *out_num_planes = 3; 765 } 766 return GRALLOC1_ERROR_NONE; 767} 768 769gralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd, 770 struct android_flex_layout *layout) { 771 if (!IsYuvFormat(hnd)) { 772 return GRALLOC1_ERROR_UNSUPPORTED; 773 } 774 775 android_ycbcr ycbcr; 776 int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr); 777 778 if (err != 0) { 779 return GRALLOC1_ERROR_BAD_HANDLE; 780 } 781 782 layout->format = FLEX_FORMAT_YCbCr; 783 layout->num_planes = 3; 784 785 for (uint32_t i = 0; i < layout->num_planes; i++) { 786 layout->planes[i].bits_per_component = 8; 787 layout->planes[i].bits_used = 8; 788 layout->planes[i].h_increment = 1; 789 layout->planes[i].v_increment = 1; 790 layout->planes[i].h_subsampling = 2; 791 layout->planes[i].v_subsampling = 2; 792 } 793 794 layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y); 795 layout->planes[0].component = FLEX_COMPONENT_Y; 796 layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride); 797 798 layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb); 799 layout->planes[1].component = FLEX_COMPONENT_Cb; 800 layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step); 801 layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride); 802 803 layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr); 804 layout->planes[2].component = FLEX_COMPONENT_Cr; 805 layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step); 806 layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride); 807 return GRALLOC1_ERROR_NONE; 808} 809} // namespace gralloc1 810