12ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/*
22ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved.
32ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Not a Contribution
42ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *
52ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Copyright (C) 2010 The Android Open Source Project
62ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *
72ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Licensed under the Apache License, Version 2.0 (the "License");
82ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * you may not use this file except in compliance with the License.
92ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * You may obtain a copy of the License at
102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *
112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *      http://www.apache.org/licenses/LICENSE-2.0
122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *
132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Unless required by applicable law or agreed to in writing, software
142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * distributed under the License is distributed on an "AS IS" BASIS,
152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * See the License for the specific language governing permissions and
172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * limitations under the License.
182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */
192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <utility>
212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "qd_utils.h"
232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_priv_handle.h"
242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_buf_descriptor.h"
252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_utils.h"
262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_buf_mgr.h"
272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "qdMetaData.h"
282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelnamespace gralloc1 {
302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelBufferManager::BufferManager() {
322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  char property[PROPERTY_VALUE_MAX];
332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Map framebuffer memory
352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    map_fb_mem_ = true;
392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Enable UBWC for framebuffer
422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    ubwc_for_fb_ = true;
462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  handles_map_.clear();
492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelBufferManager::~BufferManager() {
522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_) {
532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    delete allocator_;
542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelbool BufferManager::Init() {
582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  allocator_ = new Allocator();
592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return allocator_->Init();
612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                                const BufferDescriptor *descriptors,
652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                                buffer_handle_t *out_buffers) {
662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool shared = true;
672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_error_t status = GRALLOC1_ERROR_NONE;
682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // client can ask to test the allocation by passing NULL out_buffers
712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool test_allocate = !out_buffers;
722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Check if input descriptors can be supported AND
742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Find out if a single buffer can be shared for all the given input descriptors
752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t i = 0;
762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int max_buf_index = -1;
772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (test_allocate) {
802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return status;
822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (shared && (max_buf_index >= 0)) {
852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Allocate one and duplicate/copy the handles for each descriptor
862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (AllocateBuffer(descriptors[max_buf_index], &out_buffers[max_buf_index])) {
872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return GRALLOC1_ERROR_NO_RESOURCES;
882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    for (i = 0; i < num_descriptors; i++) {
912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Create new handle for a given descriptor.
922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Current assumption is even MetaData memory would be same
932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Need to revisit if there is a need for own metadata memory
942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (i != UINT(max_buf_index)) {
952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        CreateSharedHandle(out_buffers[max_buf_index], descriptors[i], &out_buffers[i]);
962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        // since we just created handle out of existing handle add it to map
982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        locker_.lock();
992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        handles_map_.insert(std::pair<private_handle_t const *, int>(
1002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel            reinterpret_cast<private_handle_t const *>(out_buffers[i]), 1));
1012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        locker_.unlock();
1022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
1032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
1052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Buffer sharing is not feasible.
1062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Allocate seperate buffer for each descriptor
1072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    for (i = 0; i < num_descriptors; i++) {
1082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (AllocateBuffer(descriptors[i], &out_buffers[i])) {
1092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_NO_RESOURCES;
1102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
1112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Allocation is successful. If backstore is not shared inform the client.
1152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!shared) {
1162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_NOT_SHARED;
1172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return status;
1202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
1232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                       buffer_handle_t *outbuffer) {
1242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
1252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Get Buffer attributes or dimension
1272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int alignedw = 0, alignedh = 0;
1282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
1292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // create new handle from input reference handle and given descriptor
1312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
1322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                             descriptor.GetConsumerUsage());
1332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int buffer_type = GetBufferType(descriptor.GetFormat());
1342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Duplicate the fds
1362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *out_hnd = new private_handle_t(
1372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      dup(input->fd), input->size, flags, buffer_type, descriptor.GetFormat(), INT(alignedw),
1382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      INT(alignedh), dup(input->fd_metadata), input->offset_metadata, input->base_metadata,
1392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      descriptor.GetWidth(), descriptor.GetHeight(), descriptor.GetProducerUsage(),
1402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      descriptor.GetConsumerUsage());
1412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *outbuffer = out_hnd;
1432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::FreeBuffer(private_handle_t const *hnd) {
1462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
1472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                             hnd->fd) != 0) {
1482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
1492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
1522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
1532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                             hnd->offset_metadata, hnd->fd_metadata) != 0) {
1542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
1552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // delete handle also
1582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *handle = const_cast<private_handle_t *>(hnd);
1592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  delete handle;
1602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
1622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
1652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
1662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  hnd->base = 0;
1682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  hnd->base_metadata = 0;
1692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
1702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                            hnd->fd) != 0) {
1712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
1722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
1752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
1762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                            hnd->offset_metadata, hnd->fd_metadata) != 0) {
1772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
1782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
1812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
1842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.lock();
1852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // find if this handle is already in map
1872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  auto it = handles_map_.find(hnd);
1882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (it != handles_map_.end()) {
1892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // It's already in map, Just increment refcnt
1902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // No need to mmap the memory.
1912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    it->second = it->second + 1;
1922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
1932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // not present in the map. mmap and then add entry to map
1942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) {
1952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      handles_map_.insert(std::pair<private_handle_t const *, int>(hnd, 1));
1962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.unlock();
2002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
2012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
2042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.lock();
2052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // find if this handle is already in map
2072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  auto it = handles_map_.find(hnd);
2082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (it == handles_map_.end()) {
2092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Corrupt handle or map.
2102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    locker_.unlock();
2112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
2122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
2132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    it->second = it->second - 1;
2142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!it->second) {
2172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    handles_map_.erase(it);
2182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    FreeBuffer(hnd);
2192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.unlock();
2222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
2232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
2262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                           gralloc1_producer_usage_t prod_usage,
2272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                           gralloc1_consumer_usage_t cons_usage) {
2282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_error_t err = GRALLOC1_ERROR_NONE;
2292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // If buffer is not meant for CPU return err
2312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!CpuCanAccess(prod_usage, cons_usage)) {
2322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_VALUE;
2332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (hnd->base == 0) {
2362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // we need to map for real
2372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    locker_.lock();
2382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    err = MapBuffer(hnd);
2392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    locker_.unlock();
2402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Invalidate if CPU reads in software and there are non-CPU
2432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // writers. No need to do this for the metadata buffer as it is
2442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // only read/written in software.
2452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
2462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
2472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
2482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                hnd->fd, CACHE_INVALIDATE)) {
2492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return GRALLOC1_ERROR_BAD_HANDLE;
2502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
2512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Mark the buffer to be flushed after CPU write.
2542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!err && CpuCanWrite(prod_usage)) {
2552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    private_handle_t *handle = const_cast<private_handle_t *>(hnd);
2562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
2572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return err;
2602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
2632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_error_t status = GRALLOC1_ERROR_NONE;
2642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.lock();
2662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
2672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
2692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
2702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                hnd->fd, CACHE_CLEAN) != 0) {
2712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      status = GRALLOC1_ERROR_BAD_HANDLE;
2722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
2732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
2742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.unlock();
2772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return status;
2782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
2812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                    gralloc1_consumer_usage_t cons_usage) {
2822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int align = getpagesize();
2832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
2842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    align = 8192;
2852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
28872adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel    if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
28972adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel        (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
2902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // The alignment here reflects qsee mmu V7L/V8L requirement
2912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      align = SZ_2M;
2922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } else {
2932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      align = SECURE_ALIGN;
2942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
2952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return align;
2982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
3012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  gralloc1_consumer_usage_t cons_usage) {
3022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int flags = 0;
3032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
3042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
3052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
3082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
3092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
3122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
3132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
3162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
3172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
3202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
3212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
3242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
3252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
3282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
3292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
3322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
3332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage)) {
3362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_TILE_RENDERED;
3372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
3402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
3442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
3452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // TODO(user): is this correct???
3482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((cons_usage &
3492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel       (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
3502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
3512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
3522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
3552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
3562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!allocator_->UseUncached(prod_usage)) {
3592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_CACHED;
3602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return flags;
3632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
3642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3653d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudelint BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int unaligned_w,
3663d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel                                  int unaligned_h, int format, int bufferType,
3672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  gralloc1_producer_usage_t prod_usage,
3682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) {
3692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int err = 0;
3702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int flags = 0;
3712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  size = ALIGN(size, PAGE_SIZE);
3722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  AllocData data;
3732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  data.align = (unsigned int)GetDataAlignment(format, prod_usage, cons_usage);
3742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  size = ALIGN(size, data.align);
3752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  data.size = size;
3762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  data.handle = (uintptr_t)handle;
3772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Allocate memory
3792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  data.uncached = allocator_->UseUncached(prod_usage);
3802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
3812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (err) {
3822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    ALOGE("gralloc failed to allocate err=%s", strerror(-err));
3832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    *handle = 0;
3842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return err;
3852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // allocate memory for MetaData
3882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  AllocData e_data;
3892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  e_data.size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
3902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  e_data.handle = data.handle;
3912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  e_data.align = (unsigned int)getpagesize();
3922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ColorSpace_t colorSpace = ITU_R_601;
3942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
3952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    colorSpace = ITU_R_601_FR;
3962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  err =
3992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
4002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ALOGE_IF(err, "gralloc failed for e_daata error=%s", strerror(-err));
4012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  flags = GetHandleFlags(format, prod_usage, cons_usage);
4032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  flags |= data.alloc_type;
4042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Create handle
4062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint64_t eBaseAddr = (uint64_t)(e_data.base) + e_data.offset;
4072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *hnd = new private_handle_t(data.fd, size, flags, bufferType, format, aligned_w,
4082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                               aligned_h, e_data.fd, e_data.offset, eBaseAddr,
4093d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel                                               unaligned_w, unaligned_h, prod_usage, cons_usage);
4102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  hnd->offset = data.offset;
4122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  hnd->base = (uint64_t)(data.base) + data.offset;
4132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  hnd->gpuaddr = 0;
4142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
4162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *handle = hnd;
4182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // we have just allocated the buffer & mmapped. Add to map
4202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.lock();
4212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  handles_map_.insert(std::pair<private_handle_t const *, int>(hnd, 1));
4222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.unlock();
4232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return err;
4252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BufferManager::GetBufferType(int inputFormat) {
4282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int buffer_type = BUFFER_TYPE_VIDEO;
4292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (IsUncompressedRGBFormat(inputFormat)) {
4302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // RGB formats
4312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    buffer_type = BUFFER_TYPE_UI;
4322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return buffer_type;
4352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
4382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  unsigned int bufferSize) {
4392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!handle)
4402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return -EINVAL;
4412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int format = descriptor.GetFormat();
4432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
4442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
4452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Get implementation defined format
4472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
4482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool use_fb_mem = false;
4502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && map_fb_mem_) {
4512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    use_fb_mem = true;
4522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && ubwc_for_fb_) {
4552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    prod_usage =
4562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        (gralloc1_producer_usage_t)(prod_usage | GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC);
4572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int size;
4602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int alignedw, alignedh;
4612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int buffer_type = GetBufferType(gralloc_format);
4622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
4632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  size = (bufferSize >= size) ? bufferSize : size;
4652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int err = 0;
4672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (use_fb_mem) {
4682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // TODO(user): TBD Framebuffer specific implementation in a seperate file/class
4692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
4702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    err = AllocateBuffer(size, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
4712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                         descriptor.GetHeight(), format, buffer_type, descriptor.GetProducerUsage(),
4722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                         descriptor.GetConsumerUsage(), handle);
4732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (err < 0) {
4762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return err;
4772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return 0;
4802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::Perform(int operation, va_list args) {
4832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (operation) {
4842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
4852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int fd = va_arg(args, int);
4862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      unsigned int size = va_arg(args, unsigned int);
4872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      unsigned int offset = va_arg(args, unsigned int);
4882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      void *base = va_arg(args, void *);
4892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int width = va_arg(args, int);
4902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int height = va_arg(args, int);
4912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int format = va_arg(args, int);
4922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      native_handle_t **handle = va_arg(args, native_handle_t **);
4942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
4952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel          native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
4962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (hnd) {
4973d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        unsigned int alignedw = 0, alignedh = 0;
4982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->magic = private_handle_t::kMagic;
4992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->fd = fd;
5002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
5012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->size = size;
5022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->offset = offset;
5032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->base = uint64_t(base) + offset;
5042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->gpuaddr = 0;
5053d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        BufferDescriptor descriptor(width, height, format);
5063d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
5073d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        hnd->unaligned_width = width;
5083d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        hnd->unaligned_height = height;
5093d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        hnd->width = alignedw;
5103d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        hnd->height = alignedh;
5112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->format = format;
5122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *handle = reinterpret_cast<native_handle_t *>(hnd);
5132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
5152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
5172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int width = va_arg(args, int);
5182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int format = va_arg(args, int);
5192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *stride = va_arg(args, int *);
5202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      unsigned int alignedw = 0, alignedh = 0;
5212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      BufferDescriptor descriptor(width, width, format);
5222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
5232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *stride = INT(alignedw);
5242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
5252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
5272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
5282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *stride = va_arg(args, int *);
5292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
5302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
5312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
5342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
5352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *stride = metadata->bufferDim.sliceWidth;
5362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      } else {
5372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *stride = hnd->width;
5382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
5402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
5422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
5432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
5442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *stride = va_arg(args, int *);
5452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *height = va_arg(args, int *);
5462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
5472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
5482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
5512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
5522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *stride = metadata->bufferDim.sliceWidth;
5532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *height = metadata->bufferDim.sliceHeight;
5542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      } else {
5552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *stride = hnd->width;
5562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *height = hnd->height;
5572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
5592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
5612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // TODO(user): Usage is split now. take care of it from Gfx client.
5622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // see if we can directly expect descriptor from gfx client.
5632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int width = va_arg(args, int);
5642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int height = va_arg(args, int);
5652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int format = va_arg(args, int);
5662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      uint64_t producer_usage = va_arg(args, uint64_t);
5672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      uint64_t consumer_usage = va_arg(args, uint64_t);
5682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
5692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
5702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *aligned_width = va_arg(args, int *);
5722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *aligned_height = va_arg(args, int *);
5732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *tile_enabled = va_arg(args, int *);
5742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      unsigned int alignedw, alignedh;
5752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
5762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage) ||
5772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                      allocator_->IsMacroTileEnabled(format, prod_usage, cons_usage);
5782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
5802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *aligned_width = INT(alignedw);
5812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *aligned_height = INT(alignedh);
5822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
5832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
5852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
5862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *color_space = va_arg(args, int *);
5872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
5882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
5892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
591d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel      if (!metadata) {
592d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
593d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel#ifdef USE_COLOR_METADATA
594d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel      } else if (metadata->operation & COLOR_METADATA) {
595d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        ColorMetaData *colorMetadata = &metadata->color;
596d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        switch (colorMetadata->colorPrimaries) {
597d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        case ColorPrimaries_BT709_5:
598d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          *color_space = HAL_CSC_ITU_R_709;
599d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          break;
600d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        case ColorPrimaries_BT601_6_525:
601d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          *color_space = ((colorMetadata->range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
602d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel           break;
603d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        case ColorPrimaries_BT2020:
604d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          *color_space = (colorMetadata->range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
605d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          break;
606d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        default:
607d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          ALOGE("Unknown Color Space = %d", colorMetadata->colorPrimaries);
608d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          break;
609d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        }
610d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel#endif
611d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel      } else if (metadata->operation & UPDATE_COLOR_SPACE) {
6122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *color_space = metadata->colorSpace;
6132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
6162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
6172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
6182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
6192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
6202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
6222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_UNDEFINED;
6232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
6272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
6282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *map_secure_buffer = va_arg(args, int *);
6292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
6302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
6312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
6332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (metadata && metadata->operation & MAP_SECURE_BUFFER) {
6342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *map_secure_buffer = metadata->mapSecureBuffer;
6352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      } else {
6362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *map_secure_buffer = 0;
6372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
6412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
6422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *flag = va_arg(args, int *);
6432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
6442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
6452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
6472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
6502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
6512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      void **rgb_data = va_arg(args, void **);
6522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
6532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
6542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
6562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_UNDEFINED;
6572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
6612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
6632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
6652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
6662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}  //  namespace gralloc1
668