12ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/*
26e71b7f95e9fdc03147c5f235060dd4ed4f23b86Thierry Strudel * Copyright (c) 2011-2017 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>
216cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel#include <vector>
222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "qd_utils.h"
242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_priv_handle.h"
252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_buf_descriptor.h"
262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_utils.h"
272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_buf_mgr.h"
282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "qdMetaData.h"
292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelnamespace gralloc1 {
316cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelstd::atomic<gralloc1_buffer_descriptor_t> BufferDescriptor::next_id_(1);
322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
336cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry StrudelBufferManager::BufferManager() : next_id_(0) {
342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  char property[PROPERTY_VALUE_MAX];
352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Map framebuffer memory
372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    map_fb_mem_ = true;
412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Enable UBWC for framebuffer
442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((property_get("debug.gralloc.enable_fb_ubwc", property, NULL) > 0) &&
452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (!strncmp(property, "1", PROPERTY_VALUE_MAX) ||
462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel       (!strncasecmp(property, "true", PROPERTY_VALUE_MAX)))) {
472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    ubwc_for_fb_ = true;
482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  handles_map_.clear();
516cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  allocator_ = new Allocator();
526cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  allocator_->Init();
536cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel}
546cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
556cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
566cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelgralloc1_error_t BufferManager::CreateBufferDescriptor(
576cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    gralloc1_buffer_descriptor_t *descriptor_id) {
586cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  std::lock_guard<std::mutex> lock(locker_);
596cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  auto descriptor = std::make_shared<BufferDescriptor>();
606cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  descriptors_map_.emplace(descriptor->GetId(), descriptor);
616cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  *descriptor_id = descriptor->GetId();
626cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  return GRALLOC1_ERROR_NONE;
636cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel}
646cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
656cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelgralloc1_error_t BufferManager::DestroyBufferDescriptor(
666cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    gralloc1_buffer_descriptor_t descriptor_id) {
676cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  std::lock_guard<std::mutex> lock(locker_);
686cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  const auto descriptor = descriptors_map_.find(descriptor_id);
696cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  if (descriptor == descriptors_map_.end()) {
706cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    return GRALLOC1_ERROR_BAD_DESCRIPTOR;
716cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  }
726cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  descriptors_map_.erase(descriptor);
736cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  return GRALLOC1_ERROR_NONE;
742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelBufferManager::~BufferManager() {
772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_) {
782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    delete allocator_;
792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::AllocateBuffers(uint32_t num_descriptors,
836cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                const gralloc1_buffer_descriptor_t *descriptor_ids,
842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                                buffer_handle_t *out_buffers) {
852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool shared = true;
862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_error_t status = GRALLOC1_ERROR_NONE;
872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // since GRALLOC1_CAPABILITY_TEST_ALLOCATE capability is supported
892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // client can ask to test the allocation by passing NULL out_buffers
902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool test_allocate = !out_buffers;
912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
926cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  // Validate descriptors
936cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  std::vector<std::shared_ptr<BufferDescriptor>> descriptors;
946cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  for (uint32_t i = 0; i < num_descriptors; i++) {
956cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    const auto map_descriptor = descriptors_map_.find(descriptor_ids[i]);
966cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    if (map_descriptor == descriptors_map_.end()) {
976cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      return GRALLOC1_ERROR_BAD_DESCRIPTOR;
986cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    } else {
996cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      descriptors.push_back(map_descriptor->second);
1006cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    }
1016cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  }
1026cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
1036cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  //  Resolve implementation defined formats
1046cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  for (auto &descriptor : descriptors) {
1056cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    descriptor->SetColorFormat(allocator_->GetImplDefinedFormat(descriptor->GetProducerUsage(),
1066cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                                descriptor->GetConsumerUsage(),
1076cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                                descriptor->GetFormat()));
1086cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  }
1096cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
1102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Check if input descriptors can be supported AND
1112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Find out if a single buffer can be shared for all the given input descriptors
1122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t i = 0;
1136cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  ssize_t max_buf_index = -1;
1142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  shared = allocator_->CheckForBufferSharing(num_descriptors, descriptors, &max_buf_index);
1152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (test_allocate) {
1172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    status = shared ? GRALLOC1_ERROR_NOT_SHARED : status;
1182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return status;
1192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (shared && (max_buf_index >= 0)) {
1222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Allocate one and duplicate/copy the handles for each descriptor
1236cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    if (AllocateBuffer(*descriptors[UINT(max_buf_index)], &out_buffers[max_buf_index])) {
1242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return GRALLOC1_ERROR_NO_RESOURCES;
1252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    for (i = 0; i < num_descriptors; i++) {
1282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Create new handle for a given descriptor.
1292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Current assumption is even MetaData memory would be same
1302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Need to revisit if there is a need for own metadata memory
1312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (i != UINT(max_buf_index)) {
1326cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel        CreateSharedHandle(out_buffers[max_buf_index], *descriptors[i], &out_buffers[i]);
1332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
1342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
1362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Buffer sharing is not feasible.
1376cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    // Allocate separate buffer for each descriptor
1382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    for (i = 0; i < num_descriptors; i++) {
1396cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      if (AllocateBuffer(*descriptors[i], &out_buffers[i])) {
1402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_NO_RESOURCES;
1412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
1422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Allocation is successful. If backstore is not shared inform the client.
1462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!shared) {
1472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_NOT_SHARED;
1482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return status;
1512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid BufferManager::CreateSharedHandle(buffer_handle_t inbuffer, const BufferDescriptor &descriptor,
1542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                       buffer_handle_t *outbuffer) {
1552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t const *input = reinterpret_cast<private_handle_t const *>(inbuffer);
1562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Get Buffer attributes or dimension
1582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int alignedw = 0, alignedh = 0;
1592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
1602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // create new handle from input reference handle and given descriptor
1622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int flags = GetHandleFlags(descriptor.GetFormat(), descriptor.GetProducerUsage(),
1632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                             descriptor.GetConsumerUsage());
1642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int buffer_type = GetBufferType(descriptor.GetFormat());
1652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Duplicate the fds
1676cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  // TODO(user): Not sure what to do for fb_id. Use duped fd and new dimensions?
1686cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  private_handle_t *out_hnd = new private_handle_t(dup(input->fd),
1696cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   dup(input->fd_metadata),
1706cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   flags,
1716cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   INT(alignedw),
1726cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   INT(alignedh),
1736cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   descriptor.GetWidth(),
1746cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   descriptor.GetHeight(),
1756cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   descriptor.GetFormat(),
1766cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   buffer_type,
1776cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   input->size,
1786cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   descriptor.GetProducerUsage(),
1796cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                   descriptor.GetConsumerUsage());
1806cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  out_hnd->id = ++next_id_;
1816cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  // TODO(user): Base address of shared handle and ion handles
1826cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  auto buffer = std::make_shared<Buffer>(out_hnd);
183e40f5bbed2e071e87100ac29586844588875cffeNaseer Ahmed  handles_map_.emplace(std::make_pair(out_hnd, buffer));
1842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *outbuffer = out_hnd;
1852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1876cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelgralloc1_error_t BufferManager::FreeBuffer(std::shared_ptr<Buffer> buf) {
1886cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  auto hnd = buf->handle;
1892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
1906cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                             hnd->fd, buf->ion_handle_main) != 0) {
1912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
1922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int meta_size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
1952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->FreeBuffer(reinterpret_cast<void *>(hnd->base_metadata), meta_size,
1966cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                             hnd->offset_metadata, hnd->fd_metadata, buf->ion_handle_meta) != 0) {
1972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
1982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2006cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  // TODO(user): delete handle once framework bug around this is confirmed
201daaf9024dc41f2ff2740589a065f18fcf9b0a473Naseer Ahmed  // to be resolved. This is tracked in bug 36355756
202daaf9024dc41f2ff2740589a065f18fcf9b0a473Naseer Ahmed  private_handle_t * handle = const_cast<private_handle_t *>(hnd);
203daaf9024dc41f2ff2740589a065f18fcf9b0a473Naseer Ahmed  handle->fd = -1;
204daaf9024dc41f2ff2740589a065f18fcf9b0a473Naseer Ahmed  handle->fd_metadata = -1;
2052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
2062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::MapBuffer(private_handle_t const *handle) {
2092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
2102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  hnd->base = 0;
2122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  hnd->base_metadata = 0;
2132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base), hnd->size, hnd->offset,
2142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                            hnd->fd) != 0) {
2152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
2162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int size = ALIGN((unsigned int)sizeof(MetaData_t), PAGE_SIZE);
2192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->MapBuffer(reinterpret_cast<void **>(&hnd->base_metadata), size,
2202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                            hnd->offset_metadata, hnd->fd_metadata) != 0) {
2212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
2222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
2252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::RetainBuffer(private_handle_t const *hnd) {
2286cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  std::lock_guard<std::mutex> lock(locker_);
2292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // find if this handle is already in map
231e40f5bbed2e071e87100ac29586844588875cffeNaseer Ahmed  auto it = handles_map_.find(hnd);
2322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (it != handles_map_.end()) {
2332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // It's already in map, Just increment refcnt
2342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // No need to mmap the memory.
2356cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    auto buf = it->second;
2366cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    buf->ref_count++;
2372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
2382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // not present in the map. mmap and then add entry to map
2392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (MapBuffer(hnd) == GRALLOC1_ERROR_NONE) {
2406cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      auto buffer = std::make_shared<Buffer>(hnd);
241e40f5bbed2e071e87100ac29586844588875cffeNaseer Ahmed      handles_map_.emplace(std::make_pair(hnd, buffer));
2422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
2432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
2462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::ReleaseBuffer(private_handle_t const *hnd) {
2496cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  std::lock_guard<std::mutex> lock(locker_);
2502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // find if this handle is already in map
251e40f5bbed2e071e87100ac29586844588875cffeNaseer Ahmed  auto it = handles_map_.find(hnd);
2522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (it == handles_map_.end()) {
2532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Corrupt handle or map.
2546cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    ALOGE("Could not find handle");
2552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
2562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
2576cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    auto buf = it->second;
2586cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    buf->ref_count--;
2596cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    if (buf->ref_count == 0) {
2606cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      handles_map_.erase(it);
2616cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      FreeBuffer(buf);
2626cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    }
2632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
2652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::LockBuffer(const private_handle_t *hnd,
2682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                           gralloc1_producer_usage_t prod_usage,
2692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                           gralloc1_consumer_usage_t cons_usage) {
2702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_error_t err = GRALLOC1_ERROR_NONE;
2712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // If buffer is not meant for CPU return err
2732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!CpuCanAccess(prod_usage, cons_usage)) {
2742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GRALLOC1_ERROR_BAD_VALUE;
2752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (hnd->base == 0) {
2782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // we need to map for real
2792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    locker_.lock();
2802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    err = MapBuffer(hnd);
2812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    locker_.unlock();
2822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Invalidate if CPU reads in software and there are non-CPU
2852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // writers. No need to do this for the metadata buffer as it is
2862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // only read/written in software.
2872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!err && (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) &&
2882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (hnd->flags & private_handle_t::PRIV_FLAGS_CACHED)) {
2892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
2902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                hnd->fd, CACHE_INVALIDATE)) {
2912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return GRALLOC1_ERROR_BAD_HANDLE;
2922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
2932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Mark the buffer to be flushed after CPU write.
2962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!err && CpuCanWrite(prod_usage)) {
2972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    private_handle_t *handle = const_cast<private_handle_t *>(hnd);
2982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    handle->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
2992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return err;
3022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
3032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::UnlockBuffer(const private_handle_t *handle) {
3052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_error_t status = GRALLOC1_ERROR_NONE;
3062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.lock();
3082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  private_handle_t *hnd = const_cast<private_handle_t *>(handle);
3092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
3112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (allocator_->CleanBuffer(reinterpret_cast<void *>(hnd->base), hnd->size, hnd->offset,
3122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                hnd->fd, CACHE_CLEAN) != 0) {
3132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      status = GRALLOC1_ERROR_BAD_HANDLE;
3142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
3152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
3162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  locker_.unlock();
3192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return status;
3202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
3212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3226cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudeluint32_t BufferManager::GetDataAlignment(int format, gralloc1_producer_usage_t prod_usage,
3232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                    gralloc1_consumer_usage_t cons_usage) {
3246cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  uint32_t align = UINT(getpagesize());
3252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
3262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    align = 8192;
3272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
33072adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel    if ((prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) ||
33172adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel        (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY)) {
3322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // The alignment here reflects qsee mmu V7L/V8L requirement
3332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      align = SZ_2M;
3342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } else {
3352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      align = SECURE_ALIGN;
3362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
3372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return align;
3402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
3412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BufferManager::GetHandleFlags(int format, gralloc1_producer_usage_t prod_usage,
3432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  gralloc1_consumer_usage_t cons_usage) {
3442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int flags = 0;
3452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_EXTERNAL_ONLY) {
3462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
3472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_INTERNAL_ONLY) {
3502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_INTERNAL_ONLY;
3512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
3542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_VIDEO_ENCODER;
3552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
3582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_CAMERA_WRITE;
3592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
3622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_CAMERA_READ;
3632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
3662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_HW_COMPOSER;
3672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) {
3702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_HW_TEXTURE;
3712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
3742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_SECURE_DISPLAY;
3752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (allocator_->IsUBwcEnabled(format, prod_usage, cons_usage)) {
3782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
3792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & (GRALLOC1_PRODUCER_USAGE_CPU_READ | GRALLOC1_PRODUCER_USAGE_CPU_WRITE)) {
3822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_CPU_RENDERED;
3832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // TODO(user): is this correct???
3862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((cons_usage &
3872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel       (GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER | GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET)) ||
3882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (prod_usage & (GRALLOC1_PRODUCER_USAGE_CAMERA | GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))) {
3892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_NON_CPU_WRITER;
3902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
3932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_DISP_CONSUMER;
3942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!allocator_->UseUncached(prod_usage)) {
3972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    flags |= private_handle_t::PRIV_FLAGS_CACHED;
3982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return flags;
4012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4033d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudelint BufferManager::AllocateBuffer(unsigned int size, int aligned_w, int aligned_h, int unaligned_w,
4043d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel                                  int unaligned_h, int format, int bufferType,
4052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  gralloc1_producer_usage_t prod_usage,
4062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  gralloc1_consumer_usage_t cons_usage, buffer_handle_t *handle) {
4076cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  auto page_size = UINT(getpagesize());
4082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int err = 0;
4092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int flags = 0;
4102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  AllocData data;
4116cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  data.align = GetDataAlignment(format, prod_usage, cons_usage);
4126cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  data.size = ALIGN(size, data.align);
4132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  data.handle = (uintptr_t)handle;
4142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  data.uncached = allocator_->UseUncached(prod_usage);
4156cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
4166cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  // Allocate buffer memory
4172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  err = allocator_->AllocateMem(&data, prod_usage, cons_usage);
4182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (err) {
4192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    ALOGE("gralloc failed to allocate err=%s", strerror(-err));
4202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return err;
4212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4236cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  // Allocate memory for MetaData
4242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  AllocData e_data;
4256cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  e_data.size = ALIGN(UINT(sizeof(MetaData_t)), page_size);
4262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  e_data.handle = data.handle;
4276cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  e_data.align = page_size;
4282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  err =
4302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      allocator_->AllocateMem(&e_data, GRALLOC1_PRODUCER_USAGE_NONE, GRALLOC1_CONSUMER_USAGE_NONE);
4316cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  if (err) {
4326cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    ALOGE("gralloc failed to allocate metadata error=%s", strerror(-err));
4336cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    return err;
4346cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  }
4352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  flags = GetHandleFlags(format, prod_usage, cons_usage);
4372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  flags |= data.alloc_type;
4382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Create handle
4406cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  private_handle_t *hnd = new private_handle_t(data.fd,
4416cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               e_data.fd,
4426cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               flags,
4436cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               aligned_w,
4446cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               aligned_h,
4456cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               unaligned_w,
4466cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               unaligned_h,
4476cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               format,
4486cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               bufferType,
4496cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               size,
4506cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               prod_usage,
4516cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                               cons_usage);
4526cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
4536cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  hnd->id = ++next_id_;
4546cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  hnd->base = reinterpret_cast<uint64_t >(data.base);
4556cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  hnd->base_metadata = reinterpret_cast<uint64_t >(e_data.base);
4562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4576cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  ColorSpace_t colorSpace = ITU_R_601;
4582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  setMetaData(hnd, UPDATE_COLOR_SPACE, reinterpret_cast<void *>(&colorSpace));
4592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *handle = hnd;
4606cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  auto buffer = std::make_shared<Buffer>(hnd, data.ion_handle, e_data.ion_handle);
461e40f5bbed2e071e87100ac29586844588875cffeNaseer Ahmed  handles_map_.emplace(std::make_pair(hnd, buffer));
4622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return err;
4632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BufferManager::GetBufferType(int inputFormat) {
4662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int buffer_type = BUFFER_TYPE_VIDEO;
4672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (IsUncompressedRGBFormat(inputFormat)) {
4682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // RGB formats
4692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    buffer_type = BUFFER_TYPE_UI;
4702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return buffer_type;
4732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint BufferManager::AllocateBuffer(const BufferDescriptor &descriptor, buffer_handle_t *handle,
4762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  unsigned int bufferSize) {
4772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!handle)
4782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return -EINVAL;
4792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int format = descriptor.GetFormat();
4812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
4822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
4832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Get implementation defined format
4852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int gralloc_format = allocator_->GetImplDefinedFormat(prod_usage, cons_usage, format);
4862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool use_fb_mem = false;
4882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && map_fb_mem_) {
4892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    use_fb_mem = true;
4902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((cons_usage & GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET) && ubwc_for_fb_) {
4932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    prod_usage =
4942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        (gralloc1_producer_usage_t)(prod_usage | GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC);
4952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int size;
4982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int alignedw, alignedh;
4992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int buffer_type = GetBufferType(gralloc_format);
5002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
5012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  size = (bufferSize >= size) ? bufferSize : size;
5032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int err = 0;
5052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (use_fb_mem) {
5062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // TODO(user): TBD Framebuffer specific implementation in a seperate file/class
5072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
5082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    err = AllocateBuffer(size, INT(alignedw), INT(alignedh), descriptor.GetWidth(),
5092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                         descriptor.GetHeight(), format, buffer_type, descriptor.GetProducerUsage(),
5102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                         descriptor.GetConsumerUsage(), handle);
5112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (err < 0) {
5142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return err;
5152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return 0;
5182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
5192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelgralloc1_error_t BufferManager::Perform(int operation, va_list args) {
5212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (operation) {
5222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {
5232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int fd = va_arg(args, int);
5242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      unsigned int size = va_arg(args, unsigned int);
5252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      unsigned int offset = va_arg(args, unsigned int);
5262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      void *base = va_arg(args, void *);
5272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int width = va_arg(args, int);
5282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int height = va_arg(args, int);
5292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int format = va_arg(args, int);
5302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      native_handle_t **handle = va_arg(args, native_handle_t **);
5322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = reinterpret_cast<private_handle_t *>(
5332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel          native_handle_create(private_handle_t::kNumFds, private_handle_t::NumInts()));
5342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (hnd) {
5353d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        unsigned int alignedw = 0, alignedh = 0;
5362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->magic = private_handle_t::kMagic;
5372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->fd = fd;
5382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
5392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->size = size;
5402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->offset = offset;
5412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->base = uint64_t(base) + offset;
5422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->gpuaddr = 0;
5433d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        BufferDescriptor descriptor(width, height, format);
5443d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
5453d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        hnd->unaligned_width = width;
5463d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel        hnd->unaligned_height = height;
5476cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel        hnd->width = INT(alignedw);
5486cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel        hnd->height = INT(alignedh);
5492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        hnd->format = format;
5502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *handle = reinterpret_cast<native_handle_t *>(hnd);
5512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
5532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_STRIDE: {
5552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int width = va_arg(args, int);
5562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int format = va_arg(args, int);
5572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *stride = va_arg(args, int *);
5582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      unsigned int alignedw = 0, alignedh = 0;
5592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      BufferDescriptor descriptor(width, width, format);
5602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
5612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *stride = INT(alignedw);
5622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
5632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE: {
5652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
5662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *stride = va_arg(args, int *);
5672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
5682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
5692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
5722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
5732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *stride = metadata->bufferDim.sliceWidth;
5742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      } else {
5752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *stride = hnd->width;
5762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
5782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // TODO(user) : this alone should be sufficient, ask gfx to get rid of above
5802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE: {
5812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
5822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *stride = va_arg(args, int *);
5832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *height = va_arg(args, int *);
5842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
5852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
5862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
5892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
5902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *stride = metadata->bufferDim.sliceWidth;
5912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *height = metadata->bufferDim.sliceHeight;
5922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      } else {
5932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *stride = hnd->width;
5942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *height = hnd->height;
5952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
5962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
5972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES: {
5992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // TODO(user): Usage is split now. take care of it from Gfx client.
6002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // see if we can directly expect descriptor from gfx client.
6012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int width = va_arg(args, int);
6022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int height = va_arg(args, int);
6032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int format = va_arg(args, int);
6042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      uint64_t producer_usage = va_arg(args, uint64_t);
6052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      uint64_t consumer_usage = va_arg(args, uint64_t);
6062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gralloc1_producer_usage_t prod_usage = static_cast<gralloc1_producer_usage_t>(producer_usage);
6072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gralloc1_consumer_usage_t cons_usage = static_cast<gralloc1_consumer_usage_t>(consumer_usage);
6082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *aligned_width = va_arg(args, int *);
6102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *aligned_height = va_arg(args, int *);
6112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *tile_enabled = va_arg(args, int *);
6122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      unsigned int alignedw, alignedh;
6132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      BufferDescriptor descriptor(width, height, format, prod_usage, cons_usage);
6146e71b7f95e9fdc03147c5f235060dd4ed4f23b86Thierry Strudel      *tile_enabled = allocator_->IsUBwcEnabled(format, prod_usage, cons_usage);
6152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      allocator_->GetAlignedWidthAndHeight(descriptor, &alignedw, &alignedh);
6172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *aligned_width = INT(alignedw);
6182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *aligned_height = INT(alignedh);
6192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE: {
6222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
6232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *color_space = va_arg(args, int *);
6242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
6252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
6262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
628d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel      if (!metadata) {
629d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
630d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel#ifdef USE_COLOR_METADATA
631d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel      } else if (metadata->operation & COLOR_METADATA) {
632d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        ColorMetaData *colorMetadata = &metadata->color;
633d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        switch (colorMetadata->colorPrimaries) {
634d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        case ColorPrimaries_BT709_5:
635d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          *color_space = HAL_CSC_ITU_R_709;
636d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          break;
637d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        case ColorPrimaries_BT601_6_525:
638d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          *color_space = ((colorMetadata->range) ? HAL_CSC_ITU_R_601_FR : HAL_CSC_ITU_R_601);
639d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel           break;
640d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        case ColorPrimaries_BT2020:
641d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          *color_space = (colorMetadata->range) ? HAL_CSC_ITU_R_2020_FR : HAL_CSC_ITU_R_2020;
642d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          break;
643d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        default:
644d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          ALOGE("Unknown Color Space = %d", colorMetadata->colorPrimaries);
645d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel          break;
646d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel        }
647d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel#endif
648d62c8a289ff6b4838e543e82b655dc436f387574Thierry Strudel      } else if (metadata->operation & UPDATE_COLOR_SPACE) {
6492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *color_space = metadata->colorSpace;
6502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO: {
6532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
6542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      android_ycbcr *ycbcr = va_arg(args, struct android_ycbcr *);
6552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
6562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
6572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (allocator_->GetYUVPlaneInfo(hnd, ycbcr)) {
6592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_UNDEFINED;
6602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO: {
6642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
6652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *map_secure_buffer = va_arg(args, int *);
6662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
6672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
6682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
6702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (metadata && metadata->operation & MAP_SECURE_BUFFER) {
6712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *map_secure_buffer = metadata->mapSecureBuffer;
6722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      } else {
6732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        *map_secure_buffer = 0;
6742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG: {
6782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
6792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      int *flag = va_arg(args, int *);
6802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
6812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
6822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *flag = hnd->flags &private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
6842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS: {
6872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      private_handle_t *hnd = va_arg(args, private_handle_t *);
6882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      void **rgb_data = va_arg(args, void **);
6892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (private_handle_t::validate(hnd) != 0) {
6902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_BAD_HANDLE;
6912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (allocator_->GetRgbDataAddress(hnd, rgb_data)) {
6932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return GRALLOC1_ERROR_UNDEFINED;
6942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
6952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } break;
6962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6976cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case GRALLOC1_MODULE_PERFORM_GET_BUFFER_SIZE_AND_DIMENSIONS: {
6986cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      int width = va_arg(args, int);
6996cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      int height = va_arg(args, int);
7006cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      int format = va_arg(args, int);
7016cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      uint64_t p_usage = va_arg(args, uint64_t);
7026cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      uint64_t c_usage = va_arg(args, uint64_t);
7036cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
7046cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
7056cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      uint32_t *aligned_width = va_arg(args, uint32_t *);
7066cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      uint32_t *aligned_height = va_arg(args, uint32_t *);
7076cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      uint32_t *size = va_arg(args, uint32_t *);
7086cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      auto descriptor = BufferDescriptor(width, height, format, producer_usage, consumer_usage);
7096cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      allocator_->GetBufferSizeAndDimensions(descriptor, size, aligned_width, aligned_height);
7106cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      // Align size
7116cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      auto align = GetDataAlignment(format, producer_usage, consumer_usage);
7126cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      *size = ALIGN(*size, align);
7136cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    } break;
7146cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7156cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      // TODO(user): Break out similar functionality, preferably moving to a common lib.
7166cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7176cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case GRALLOC1_MODULE_PERFORM_ALLOCATE_BUFFER: {
7186cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      int width = va_arg(args, int);
7196cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      int height = va_arg(args, int);
7206cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      int format = va_arg(args, int);
7216cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      uint64_t p_usage = va_arg(args, uint64_t);
7226cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      uint64_t c_usage = va_arg(args, uint64_t);
7236cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      buffer_handle_t *hnd = va_arg(args, buffer_handle_t*);
7246cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      gralloc1_producer_usage_t producer_usage = static_cast<gralloc1_producer_usage_t>(p_usage);
7256cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      gralloc1_consumer_usage_t consumer_usage = static_cast<gralloc1_consumer_usage_t>(c_usage);
7266cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      BufferDescriptor descriptor(width, height, format, producer_usage, consumer_usage);
7276cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      unsigned int size;
7286cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      unsigned int alignedw, alignedh;
7296cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      allocator_->GetBufferSizeAndDimensions(descriptor, &size, &alignedw, &alignedh);
7306cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      AllocateBuffer(descriptor, hnd, size);
7316cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    } break;
7326cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
7342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
7366cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  return GRALLOC1_ERROR_NONE;
7376cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel}
7386cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7396cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelstatic bool IsYuvFormat(const private_handle_t *hnd) {
7406cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  switch (hnd->format) {
7416cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
7426cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
7436cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
7446cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:   // Same as YCbCr_420_SP_VENUS
7456cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
7466cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
7476cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
7486cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
7496cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_NV21_ZSL:
7506cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_RAW16:
7516cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_RAW10:
7526cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    case HAL_PIXEL_FORMAT_YV12:
7536cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      return true;
7546cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    default:
7556cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel      return false;
7566cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  }
7576cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel}
7582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7596cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelgralloc1_error_t BufferManager::GetNumFlexPlanes(const private_handle_t *hnd,
7606cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                                 uint32_t *out_num_planes) {
7616cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  if (!IsYuvFormat(hnd)) {
7626cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    return GRALLOC1_ERROR_UNSUPPORTED;
7636cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  } else {
7646cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    *out_num_planes = 3;
7656cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  }
7662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return GRALLOC1_ERROR_NONE;
7672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
7682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7696cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelgralloc1_error_t BufferManager::GetFlexLayout(const private_handle_t *hnd,
7706cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                              struct android_flex_layout *layout) {
7716cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  if (!IsYuvFormat(hnd)) {
7726cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    return GRALLOC1_ERROR_UNSUPPORTED;
7736cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  }
7746cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7756cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  android_ycbcr ycbcr;
7766cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  int err = allocator_->GetYUVPlaneInfo(hnd, &ycbcr);
7776cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7786cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  if (err != 0) {
7796cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    return GRALLOC1_ERROR_BAD_HANDLE;
7806cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  }
7816cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7826cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->format = FLEX_FORMAT_YCbCr;
7836cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->num_planes = 3;
7846cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7856cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  for (uint32_t i = 0; i < layout->num_planes; i++) {
7866cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    layout->planes[i].bits_per_component = 8;
7876cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    layout->planes[i].bits_used = 8;
7886cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    layout->planes[i].h_increment = 1;
7896cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    layout->planes[i].v_increment = 1;
7906cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    layout->planes[i].h_subsampling = 2;
7916cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    layout->planes[i].v_subsampling = 2;
7926cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  }
7936cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7946cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[0].top_left = static_cast<uint8_t *>(ycbcr.y);
7956cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[0].component = FLEX_COMPONENT_Y;
7966cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[0].v_increment = static_cast<int32_t>(ycbcr.ystride);
7976cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
7986cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[1].top_left = static_cast<uint8_t *>(ycbcr.cb);
7996cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[1].component = FLEX_COMPONENT_Cb;
8006cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[1].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
8016cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[1].v_increment = static_cast<int32_t>(ycbcr.cstride);
8026cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
8036cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[2].top_left = static_cast<uint8_t *>(ycbcr.cr);
8046cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[2].component = FLEX_COMPONENT_Cr;
8056cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[2].h_increment = static_cast<int32_t>(ycbcr.chroma_step);
8066cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  layout->planes[2].v_increment = static_cast<int32_t>(ycbcr.cstride);
8076cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  return GRALLOC1_ERROR_NONE;
8086cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel}
8092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}  //  namespace gralloc1
810