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