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