12ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/*
26e71b7f95e9fdc03147c5f235060dd4ed4f23b86Thierry Strudel * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
32ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
42ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Redistribution and use in source and binary forms, with or without
52ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * modification, are permitted provided that the following conditions are
62ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * met:
72ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *   * Redistributions of source code must retain the above copyright
82ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *     notice, this list of conditions and the following disclaimer.
92ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *   * Redistributions in binary form must reproduce the above
102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *     copyright notice, this list of conditions and the following
112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *     disclaimer in the documentation and/or other materials provided
122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *     with the distribution.
132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *   * Neither the name of The Linux Foundation nor the names of its
142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *     contributors may be used to endorse or promote products derived
152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *     from this software without specific prior written permission.
162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *
172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */
292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <cutils/log.h>
312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <algorithm>
326cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel#include <vector>
332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_utils.h"
352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_allocator.h"
362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gr_adreno_info.h"
372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "gralloc_priv.h"
382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "qd_utils.h"
402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "qdMetaData.h"
412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define ASTC_BLOCK_SIZE 16
432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#ifndef ION_FLAG_CP_PIXEL
452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define ION_FLAG_CP_PIXEL 0
462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#endif
472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#ifndef ION_FLAG_ALLOW_NON_CONTIG
492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define ION_FLAG_ALLOW_NON_CONTIG 0
502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#endif
512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5272adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel#ifndef ION_FLAG_CP_CAMERA_PREVIEW
5372adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel#define ION_FLAG_CP_CAMERA_PREVIEW 0
5472adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel#endif
5572adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel
562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#ifdef MASTER_SIDE_CP
572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define CP_HEAP_ID ION_SECURE_HEAP_ID
582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
6172adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel#define ION_SC_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA)
6272adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel#define ION_SC_PREVIEW_FLAGS (ION_SECURE | ION_FLAG_CP_CAMERA_PREVIEW)
632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#else  // SLAVE_SIDE_CP
642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define CP_HEAP_ID ION_CP_MM_HEAP_ID
652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define SD_HEAP_ID CP_HEAP_ID
662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define ION_SD_FLAGS ION_SECURE
6872adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel#define ION_SC_FLAGS ION_SECURE
6972adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel#define ION_SC_PREVIEW_FLAGS ION_SECURE
702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#endif
712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
726cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelusing std::vector;
736cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelusing std::shared_ptr;
746cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel
752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelnamespace gralloc1 {
762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelAllocator::Allocator() : ion_allocator_(NULL), adreno_helper_(NULL) {
782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelbool Allocator::Init() {
812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ion_allocator_ = new IonAlloc();
822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!ion_allocator_->Init()) {
832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return false;
842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  adreno_helper_ = new AdrenoMemInfo();
872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!adreno_helper_->Init()) {
882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return false;
892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return true;
922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelAllocator::~Allocator() {
952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (ion_allocator_) {
962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    delete ion_allocator_;
972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (adreno_helper_) {
1002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    delete adreno_helper_;
1012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage,
1052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                           gralloc1_consumer_usage_t cons_usage) {
1062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int ret;
1072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  alloc_data->uncached = UseUncached(prod_usage);
1082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // After this point we should have the right heap set, there is no fallback
1102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  GetIonHeapInfo(prod_usage, cons_usage, &alloc_data->heap_id, &alloc_data->alloc_type,
1112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                 &alloc_data->flags);
1122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ret = ion_allocator_->AllocBuffer(alloc_data);
1142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (ret >= 0) {
1152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION;
1162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else {
1172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__,
1182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel          alloc_data->heap_id, alloc_data->flags);
1192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return ret;
1222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
1252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (ion_allocator_) {
1262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return ion_allocator_->MapBuffer(base, size, offset, fd);
1272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return -EINVAL;
1302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1326cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelint Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd,
1336cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                          int handle) {
1342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (ion_allocator_) {
1356cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    return ion_allocator_->FreeBuffer(base, size, offset, fd, handle);
1362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return -EINVAL;
1392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) {
1422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (ion_allocator_) {
1432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return ion_allocator_->CleanBuffer(base, size, offset, fd, op);
1442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return -EINVAL;
1472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1496cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudelbool Allocator::CheckForBufferSharing(uint32_t num_descriptors,
1506cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                      const vector<shared_ptr<BufferDescriptor>>& descriptors,
1516cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel                                      ssize_t *max_index) {
1522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int cur_heap_id = 0, prev_heap_id = 0;
1532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int cur_alloc_type = 0, prev_alloc_type = 0;
1542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int cur_ion_flags = 0, prev_ion_flags = 0;
1552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool cur_uncached = false, prev_uncached = false;
1562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int alignedw, alignedh;
1572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int max_size = 0;
1582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *max_index = -1;
1602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  for (uint32_t i = 0; i < num_descriptors; i++) {
1612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Check Cached vs non-cached and all the ION flags
1626cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    cur_uncached = UseUncached(descriptors[i]->GetProducerUsage());
1636cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    GetIonHeapInfo(descriptors[i]->GetProducerUsage(), descriptors[i]->GetConsumerUsage(),
1642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                   &cur_heap_id, &cur_alloc_type, &cur_ion_flags);
1652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type ||
1672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                  cur_ion_flags != prev_ion_flags)) {
1682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return false;
1692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // For same format type, find the descriptor with bigger size
1726cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    GetAlignedWidthAndHeight(*descriptors[i], &alignedw, &alignedh);
1736cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel    unsigned int size = GetSize(*descriptors[i], alignedw, alignedh);
1742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (max_size < size) {
1752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *max_index = INT(i);
1762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      max_size = size;
1772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
1782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    prev_heap_id = cur_heap_id;
1802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    prev_uncached = cur_uncached;
1812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    prev_ion_flags = cur_ion_flags;
1822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    prev_alloc_type = cur_alloc_type;
1832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
1842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return true;
1862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
1872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel// helper function
1892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelunsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int alignedw,
1902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                unsigned int alignedh) {
1912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int size = 0;
1922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int format = descriptor.GetFormat();
1932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int width = descriptor.GetWidth();
1942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int height = descriptor.GetHeight();
1952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
1962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
1972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
1982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
1992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return GetUBwcSize(width, height, format, alignedw, alignedh);
2002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (IsUncompressedRGBFormat(format)) {
2032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    uint32_t bpp = GetBppForUncompressedRGB(format);
2042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    size = alignedw * alignedh * bpp;
2052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return size;
2062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (IsCompressedRGBFormat(format)) {
2092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    size = alignedw * alignedh * ASTC_BLOCK_SIZE;
2102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return size;
2112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Below switch should be for only YUV/custom formats
2142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (format) {
2152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RAW16:
2162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = alignedw * alignedh * 2;
2172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RAW10:
2192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = ALIGN(alignedw * alignedh, SIZE_4K);
2202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // adreno formats
2232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
2242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = ALIGN(alignedw * alignedh, SIZE_4K);
2252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
2262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:  // NV12
2282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // The chroma plane is subsampled,
2292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // but the pitch in bytes is unchanged
2302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // The GPU needs 4K alignment, but the video decoder needs 8K
2312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = ALIGN(alignedw * alignedh, SIZE_8K);
2322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
2332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YV12:
2352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
2362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        ALOGE("w or h is odd for the YV12 format");
2372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return 0;
2382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
2392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
2402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = ALIGN(size, (unsigned int)SIZE_4K);
2412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
2432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
2442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
2452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
246b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
247b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
248b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel      break;
2492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
2502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
2512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_422_I:
2522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_422_I:
2532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (width & 1) {
2542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        ALOGE("width is odd for the YUV422_SP format");
2552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return 0;
2562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
2572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
2582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
2602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
2612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
2622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
2642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
2652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_BLOB:
2672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
2682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (height != 1) {
2692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
2702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        return 0;
2712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
2722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = (unsigned int)width;
2732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_NV21_ZSL:
2752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
2762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
2772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
2782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
2792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return 0;
2802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
2812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return size;
2832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid Allocator::GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size,
2862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                           unsigned int *alignedw, unsigned int *alignedh) {
2872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  BufferDescriptor descriptor = BufferDescriptor(width, height, format);
2882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
2892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *size = GetSize(descriptor, *alignedw, *alignedh);
2912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid Allocator::GetBufferSizeAndDimensions(const BufferDescriptor &descriptor, unsigned int *size,
2942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                           unsigned int *alignedw, unsigned int *alignedh) {
2952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
2962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
2972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *size = GetSize(descriptor, *alignedw, *alignedh);
2982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
2992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid Allocator::GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
3012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                      int color_format, struct android_ycbcr *ycbcr) {
3022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // UBWC buffer has these 4 planes in the following sequence:
3032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
3042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int y_meta_stride, y_meta_height, y_meta_size;
3052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int y_stride, y_height, y_size;
3062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int c_meta_stride, c_meta_height, c_meta_size;
3072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int alignment = 4096;
3082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
3102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
3112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
3122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  y_stride = VENUS_Y_STRIDE(color_format, INT(width));
3142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  y_height = VENUS_Y_SCANLINES(color_format, INT(height));
3152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  y_size = ALIGN((y_stride * y_height), alignment);
3162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
3182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
3192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
3202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
3222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
3232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
3242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->ystride = y_stride;
3252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
3262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
3272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid Allocator::GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
3292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                  struct android_ycbcr *ycbcr) {
3302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int ystride, cstride;
3312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ystride = cstride = UINT(width) * bpp;
3332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->y = reinterpret_cast<void *>(base);
3342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
3352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
3362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->ystride = ystride;
3372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->cstride = cstride;
3382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  ycbcr->chroma_step = 2 * bpp;
3392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
3402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint Allocator::GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
3422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int err = 0;
3432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t width = UINT(hnd->width);
3442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t height = UINT(hnd->height);
3452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int format = hnd->format;
3462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
3472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
3482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int ystride, cstride;
3492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
3512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
3522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Check if UBWC buffer has been rendered in linear format.
3542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (metadata && (metadata->operation & LINEAR_FORMAT)) {
3552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    format = INT(metadata->linearFormat);
3562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Check metadata if the geometry has been updated.
3592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
3602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    int usage = 0;
3612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
3632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
3642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
3652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    BufferDescriptor descriptor =
3672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        BufferDescriptor(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
3682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                         prod_usage, cons_usage);
3692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    GetAlignedWidthAndHeight(descriptor, &width, &height);
3702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
3712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Get the chroma offsets from the handle width/height. We take advantage
3732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // of the fact the width _is_ the stride
3742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (format) {
3752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Semiplanar
3762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
3772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
3782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
3792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
3802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // Same as YCbCr_420_SP_VENUS
3812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
3822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
3832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
3852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
3862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
3872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
3892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
3902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ycbcr->chroma_step = 2;
3912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
3922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
3942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
3952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ycbcr->chroma_step = 3;
3962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
3972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
3982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
3992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
4002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
4012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
4022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_NV21_ZSL:
4032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RAW16:
4042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RAW10:
4052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
4062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      std::swap(ycbcr->cb, ycbcr->cr);
4072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
4082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Planar
4102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YV12:
4112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ystride = width;
4122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      cstride = ALIGN(width / 2, 16);
4132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ycbcr->y = reinterpret_cast<void *>(hnd->base);
4142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
4152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
4162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ycbcr->ystride = ystride;
4172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ycbcr->cstride = cstride;
4182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ycbcr->chroma_step = 1;
4192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
4202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Unsupported formats
4222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_422_I:
4232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_422_I:
4242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
4252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
4262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
4272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      err = -EINVAL;
4282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return err;
4312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
4342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                    gralloc1_consumer_usage_t cons_usage, int format) {
4352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int gr_format = format;
4362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
4382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // the usage bits, gralloc assigns a format.
4392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
4402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
4412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) {
4422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
4432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
4442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;  // NV12
4452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL) {
4462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21 ZSL
4472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
4482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;  // NV21
4492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
4502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
4512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
4522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      } else {
4532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;  // NV12 preview
4542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      }
4552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
4562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // XXX: If we still haven't set a format, default to RGBA8888
4572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
4582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
4592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // If no other usage flags are detected, default the
4602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      // flexible YUV format to NV21_ZSL
4612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
4622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
4632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return gr_format;
4662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel// Explicitly defined UBWC formats
4692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelbool Allocator::IsUBwcFormat(int format) {
4702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (format) {
4712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
4722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return true;
4732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
4742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return false;
4752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelbool Allocator::IsUBwcSupported(int format) {
4792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Existing HAL formats with UBWC support
4802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (format) {
4812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_BGR_565:
4822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RGBA_8888:
4832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RGBX_8888:
4842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
4852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
4862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return true;
4872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
4882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
4892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
4902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return false;
4922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
4932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
4942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* The default policy is to return cached buffers unless the client explicity
4952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
4962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * read or written in software. */
4972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel// TODO(user) : As of now relying only on producer usage
4982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelbool Allocator::UseUncached(gralloc1_producer_usage_t usage) {
4992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED) ||
5002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      (usage & GRALLOC1_PRODUCER_USAGE_PROTECTED)) {
5012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return true;
5022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // CPU read rarely
5052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) &&
5062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      !(usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)) {
5072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return true;
5082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // CPU  write rarely
5112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) &&
5122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      !(usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) {
5132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return true;
5142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return false;
5172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
5182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage,
5202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                               gralloc1_consumer_usage_t cons_usage, unsigned int *ion_heap_id,
5212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                               unsigned int *alloc_type, unsigned int *ion_flags) {
5222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int heap_id = 0;
5232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int type = 0;
5246cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  unsigned int flags = 0;
5252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
5262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
5272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      heap_id = ION_HEAP(SD_HEAP_ID);
5282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      /*
5292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel       * There is currently no flag in ION for Secure Display
5302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel       * VM. Please add it to the define once available.
5312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel       */
5322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      flags |= ION_SD_FLAGS;
53372adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel    } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
53472adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel      heap_id = ION_HEAP(SD_HEAP_ID);
53572adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel      if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
53672adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel        flags |= ION_SC_PREVIEW_FLAGS;
53772adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel      } else {
53872adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel        flags |= ION_SC_FLAGS;
53972adb432f6bdb99433ebb261d8e55395d10783deThierry Strudel      }
5402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    } else {
5412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      heap_id = ION_HEAP(CP_HEAP_ID);
5422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      flags |= ION_CP_FLAGS;
5432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
5442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP) {
5452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // MM Heap is exclusively a secure heap.
5462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // If it is used for non secure cases, fallback to IOMMU heap
5472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    ALOGW("MM_HEAP cannot be used as an insecure heap. Using system heap instead!!");
5482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    heap_id |= ION_HEAP(ION_SYSTEM_HEAP_ID);
5492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP) {
5522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    heap_id |= ION_HEAP(ION_CAMERA_HEAP_ID);
5532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP) {
5562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    heap_id |= ION_HEAP(ION_ADSP_HEAP_ID);
5572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (flags & ION_SECURE) {
5602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
5612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // if no ion heap flags are set, default to system heap
5642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!heap_id) {
5652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
5662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *alloc_type = type;
5696cfbcfa35e4da3a5975d9904a8caae9968acc768Thierry Strudel  *ion_flags = flags;
5702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *ion_heap_id = heap_id;
5712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return;
5732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
5742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelbool Allocator::IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
5762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                              gralloc1_consumer_usage_t cons_usage) {
5772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
5782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (IsUBwcFormat(format)) {
5792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return true;
5802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
5832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
5842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // usage flag and MDP supports the format.
5852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
5862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    bool enable = true;
5872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Query GPU for UBWC only if buffer is intended to be used by GPU.
5882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
5892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel        (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
5902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      enable = adreno_helper_->IsUBWCSupportedByGPU(format);
5912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
5922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    // Allow UBWC, only if CPU usage flags are not set
5942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
5952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      return true;
5962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    }
5972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
5982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
5992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return false;
6002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
6012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid Allocator::GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
6032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                         unsigned int *aligned_h) {
6042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (format) {
6052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
6062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
6072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
6082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
6092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
6102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6113d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
6123d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel      // The macro returns the stride which is 4/3 times the width, hence * 3/4
6133d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel      *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
6143d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel      *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
6153d2d9c4a5c7de4febeaf0055d9d19b26f17898c8Thierry Strudel      break;
6162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
6172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
6182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *aligned_w = 0;
6192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *aligned_h = 0;
6202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
6222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
6232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid Allocator::GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
6252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *block_width = 0;
6262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *block_height = 0;
6272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (bpp) {
6292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case 2:
6302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case 4:
6312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *block_width = 16;
6322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *block_height = 4;
6332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case 8:
6352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *block_width = 8;
6362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *block_height = 4;
6372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case 16:
6392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *block_width = 4;
6402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      *block_height = 4;
6412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
6432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
6442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
6462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
6472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelunsigned int Allocator::GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
6492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int size = 0;
6502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int meta_width, meta_height;
6512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int block_width, block_height;
6522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
6542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!block_width || !block_height) {
6552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
6562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return size;
6572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
6582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Align meta buffer height to 16 blocks
6602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
6612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Align meta buffer width to 64 blocks
6632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
6642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Align meta buffer size to 4K
6662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
6672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return size;
6692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
6702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelunsigned int Allocator::GetUBwcSize(int width, int height, int format, unsigned int alignedw,
6722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                    unsigned int alignedh) {
6732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int size = 0;
6742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t bpp = 0;
6752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (format) {
6762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_BGR_565:
6772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RGBA_8888:
6782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RGBX_8888:
6792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RGBA_1010102:
6802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RGBX_1010102:
6812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      bpp = GetBppForUncompressedRGB(format);
6822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = alignedw * alignedh * bpp;
6832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size += GetRgbUBwcMetaBufferSize(width, height, bpp);
6842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
6862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
6872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
6882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
6892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
6912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
6922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
6942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
6952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
6962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
6972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
6982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return size;
6992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
7002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint Allocator::GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
7022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int err = 0;
7032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // This api is for RGB* formats
7052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
7062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return -EINVAL;
7072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
7082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // linear buffer, nothing to do further
7102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
7112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    *rgb_data = reinterpret_cast<void *>(hnd->base);
7122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return err;
7132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
7142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int meta_size = 0;
7162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
7172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (hnd->format) {
7182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_BGR_565:
7192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RGBA_8888:
7202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RGBX_8888:
7212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
7222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
7242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
7252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      err = -EINVAL;
7262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
7282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
7292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  return err;
7312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
7322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelvoid Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, unsigned int *alignedw,
7342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel                                         unsigned int *alignedh) {
7352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int width = descriptor.GetWidth();
7362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int height = descriptor.GetHeight();
7372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int format = descriptor.GetFormat();
7382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
7392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
7402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Currently surface padding is only computed for RGB* surfaces.
7422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
7436e71b7f95e9fdc03147c5f235060dd4ed4f23b86Thierry Strudel  int tile = ubwc_enabled;
7442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (IsUncompressedRGBFormat(format)) {
7462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    adreno_helper_->AlignUnCompressedRGB(width, height, format, tile, alignedw, alignedh);
7472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return;
7482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
7492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (ubwc_enabled) {
7512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
7522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return;
7532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
7542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  if (IsCompressedRGBFormat(format)) {
7562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    adreno_helper_->AlignCompressedRGB(width, height, format, alignedw, alignedh);
7572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    return;
7582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
7592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int aligned_w = width;
7612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  int aligned_h = height;
7622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  unsigned int alignment = 32;
7632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
7642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  // Below should be only YUV family
7652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  switch (format) {
7662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
7672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
7682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      alignment = adreno_helper_->GetGpuPixelAlignment();
7692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_w = ALIGN(width, alignment);
7702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
7722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_w = ALIGN(width, alignment);
7732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RAW16:
7752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_w = ALIGN(width, 16);
7762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RAW10:
778477175715cba3f3f870ea312cfebeb3fd18401cfNaseer Ahmed      aligned_w = ALIGN(width * 10 / 8, 8);
7792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
7812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_w = ALIGN(width, 128);
7822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YV12:
7842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
7852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
7862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_422_I:
7872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_422_I:
788b06147dd70f03970c8f3b30837a82394b814cb43Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_P010:
7892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_w = ALIGN(width, 16);
7902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
7922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
7932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
7942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
7952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
7962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
7972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
7982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
7992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
8002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_BLOB:
8012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_RAW_OPAQUE:
8022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
8032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    case HAL_PIXEL_FORMAT_NV21_ZSL:
8042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_w = ALIGN(width, 64);
8052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      aligned_h = ALIGN(height, 64);
8062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
8072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel    default:
8082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel      break;
8092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  }
8102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
8112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *alignedw = (unsigned int)aligned_w;
8122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel  *alignedh = (unsigned int)aligned_h;
8132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}
8142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel
8152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}  // namespace gralloc1
816