Home | History | Annotate | Download | only in libgralloc1
      1 /*
      2  * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
      3 
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *   * Redistributions of source code must retain the above copyright
      8  *     notice, this list of conditions and the following disclaimer.
      9  *   * Redistributions in binary form must reproduce the above
     10  *     copyright notice, this list of conditions and the following
     11  *     disclaimer in the documentation and/or other materials provided
     12  *     with the distribution.
     13  *   * Neither the name of The Linux Foundation nor the names of its
     14  *     contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include <cutils/log.h>
     31 #include <algorithm>
     32 
     33 #include "gr_utils.h"
     34 #include "gr_allocator.h"
     35 #include "gr_adreno_info.h"
     36 #include "gralloc_priv.h"
     37 
     38 #include "qd_utils.h"
     39 #include "qdMetaData.h"
     40 
     41 #define ASTC_BLOCK_SIZE 16
     42 
     43 #ifndef ION_FLAG_CP_PIXEL
     44 #define ION_FLAG_CP_PIXEL 0
     45 #endif
     46 
     47 #ifndef ION_FLAG_ALLOW_NON_CONTIG
     48 #define ION_FLAG_ALLOW_NON_CONTIG 0
     49 #endif
     50 
     51 #ifdef MASTER_SIDE_CP
     52 #define CP_HEAP_ID ION_SECURE_HEAP_ID
     53 #define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
     54 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
     55 #define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
     56 #else  // SLAVE_SIDE_CP
     57 #define CP_HEAP_ID ION_CP_MM_HEAP_ID
     58 #define SD_HEAP_ID CP_HEAP_ID
     59 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
     60 #define ION_SD_FLAGS ION_SECURE
     61 #endif
     62 
     63 namespace gralloc1 {
     64 
     65 Allocator::Allocator() : ion_allocator_(NULL), adreno_helper_(NULL) {
     66 }
     67 
     68 bool Allocator::Init() {
     69   ion_allocator_ = new IonAlloc();
     70   if (!ion_allocator_->Init()) {
     71     return false;
     72   }
     73 
     74   adreno_helper_ = new AdrenoMemInfo();
     75   if (!adreno_helper_->Init()) {
     76     return false;
     77   }
     78 
     79   gpu_support_macrotile = adreno_helper_->IsMacroTilingSupportedByGPU();
     80   int supports_macrotile = 0;
     81   qdutils::querySDEInfo(qdutils::HAS_MACRO_TILE, &supports_macrotile);
     82   display_support_macrotile = !!supports_macrotile;
     83 
     84   return true;
     85 }
     86 
     87 Allocator::~Allocator() {
     88   if (ion_allocator_) {
     89     delete ion_allocator_;
     90   }
     91 
     92   if (adreno_helper_) {
     93     delete adreno_helper_;
     94   }
     95 }
     96 
     97 int Allocator::AllocateMem(AllocData *alloc_data, gralloc1_producer_usage_t prod_usage,
     98                            gralloc1_consumer_usage_t cons_usage) {
     99   int ret;
    100   alloc_data->uncached = UseUncached(prod_usage);
    101 
    102   // After this point we should have the right heap set, there is no fallback
    103   GetIonHeapInfo(prod_usage, cons_usage, &alloc_data->heap_id, &alloc_data->alloc_type,
    104                  &alloc_data->flags);
    105 
    106   ret = ion_allocator_->AllocBuffer(alloc_data);
    107   if (ret >= 0) {
    108     alloc_data->alloc_type |= private_handle_t::PRIV_FLAGS_USES_ION;
    109   } else {
    110     ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x", __FUNCTION__,
    111           alloc_data->heap_id, alloc_data->flags);
    112   }
    113 
    114   return ret;
    115 }
    116 
    117 // Allocates buffer from width, height and format into a
    118 // private_handle_t. It is the responsibility of the caller
    119 // to free the buffer using the FreeBuffer function
    120 int Allocator::AllocateBuffer(const BufferDescriptor &descriptor, private_handle_t **pHnd) {
    121   AllocData data;
    122   unsigned int aligned_w, aligned_h;
    123   data.base = 0;
    124   data.fd = -1;
    125   data.offset = 0;
    126   data.align = (unsigned int)getpagesize();
    127   int format = descriptor.GetFormat();
    128   gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
    129   gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
    130   GetBufferSizeAndDimensions(descriptor, &data.size, &aligned_w, &aligned_h);
    131 
    132   int err = AllocateMem(&data, prod_usage, cons_usage);
    133   if (0 != err) {
    134     ALOGE("%s: allocate failed", __FUNCTION__);
    135     return -ENOMEM;
    136   }
    137 
    138   if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
    139     data.alloc_type |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
    140   }
    141 
    142   // Metadata is not allocated. would be empty
    143   private_handle_t *hnd = new private_handle_t(
    144       data.fd, data.size, INT(data.alloc_type), 0, INT(format), INT(aligned_w), INT(aligned_h), -1,
    145       0, 0, descriptor.GetWidth(), descriptor.GetHeight(), prod_usage, cons_usage);
    146   hnd->base = (uint64_t)data.base;
    147   hnd->offset = data.offset;
    148   hnd->gpuaddr = 0;
    149   *pHnd = hnd;
    150 
    151   return 0;
    152 }
    153 
    154 int Allocator::MapBuffer(void **base, unsigned int size, unsigned int offset, int fd) {
    155   if (ion_allocator_) {
    156     return ion_allocator_->MapBuffer(base, size, offset, fd);
    157   }
    158 
    159   return -EINVAL;
    160 }
    161 
    162 int Allocator::FreeBuffer(void *base, unsigned int size, unsigned int offset, int fd) {
    163   if (ion_allocator_) {
    164     return ion_allocator_->FreeBuffer(base, size, offset, fd);
    165   }
    166 
    167   return -EINVAL;
    168 }
    169 
    170 int Allocator::CleanBuffer(void *base, unsigned int size, unsigned int offset, int fd, int op) {
    171   if (ion_allocator_) {
    172     return ion_allocator_->CleanBuffer(base, size, offset, fd, op);
    173   }
    174 
    175   return -EINVAL;
    176 }
    177 
    178 bool Allocator::CheckForBufferSharing(uint32_t num_descriptors, const BufferDescriptor *descriptors,
    179                                       int *max_index) {
    180   unsigned int cur_heap_id = 0, prev_heap_id = 0;
    181   unsigned int cur_alloc_type = 0, prev_alloc_type = 0;
    182   unsigned int cur_ion_flags = 0, prev_ion_flags = 0;
    183   bool cur_uncached = false, prev_uncached = false;
    184   unsigned int alignedw, alignedh;
    185   unsigned int max_size = 0;
    186 
    187   *max_index = -1;
    188   for (uint32_t i = 0; i < num_descriptors; i++) {
    189     // Check Cached vs non-cached and all the ION flags
    190     cur_uncached = UseUncached(descriptors[i].GetProducerUsage());
    191     GetIonHeapInfo(descriptors[i].GetProducerUsage(), descriptors[i].GetConsumerUsage(),
    192                    &cur_heap_id, &cur_alloc_type, &cur_ion_flags);
    193 
    194     if (i > 0 && (cur_heap_id != prev_heap_id || cur_alloc_type != prev_alloc_type ||
    195                   cur_ion_flags != prev_ion_flags)) {
    196       return false;
    197     }
    198 
    199     // For same format type, find the descriptor with bigger size
    200     GetAlignedWidthAndHeight(descriptors[i], &alignedw, &alignedh);
    201     unsigned int size = GetSize(descriptors[i], alignedw, alignedh);
    202     if (max_size < size) {
    203       *max_index = INT(i);
    204       max_size = size;
    205     }
    206 
    207     prev_heap_id = cur_heap_id;
    208     prev_uncached = cur_uncached;
    209     prev_ion_flags = cur_ion_flags;
    210     prev_alloc_type = cur_alloc_type;
    211   }
    212 
    213   return true;
    214 }
    215 
    216 bool Allocator::IsMacroTileEnabled(int format, gralloc1_producer_usage_t prod_usage,
    217                                    gralloc1_consumer_usage_t cons_usage) {
    218   bool tile_enabled = false;
    219 
    220   // Check whether GPU & MDSS supports MacroTiling feature
    221   if (!adreno_helper_->IsMacroTilingSupportedByGPU() || !display_support_macrotile) {
    222     return tile_enabled;
    223   }
    224 
    225   // check the format
    226   switch (format) {
    227     case HAL_PIXEL_FORMAT_RGBA_8888:
    228     case HAL_PIXEL_FORMAT_RGBX_8888:
    229     case HAL_PIXEL_FORMAT_BGRA_8888:
    230     case HAL_PIXEL_FORMAT_RGB_565:
    231     case HAL_PIXEL_FORMAT_BGR_565:
    232       if (!CpuCanAccess(prod_usage, cons_usage)) {
    233         // not touched by CPU
    234         tile_enabled = true;
    235       }
    236       break;
    237     default:
    238       break;
    239   }
    240 
    241   return tile_enabled;
    242 }
    243 
    244 // helper function
    245 unsigned int Allocator::GetSize(const BufferDescriptor &descriptor, unsigned int alignedw,
    246                                 unsigned int alignedh) {
    247   unsigned int size = 0;
    248   int format = descriptor.GetFormat();
    249   int width = descriptor.GetWidth();
    250   int height = descriptor.GetHeight();
    251   gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
    252   gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
    253 
    254   if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
    255     return GetUBwcSize(width, height, format, alignedw, alignedh);
    256   }
    257 
    258   if (IsUncompressedRGBFormat(format)) {
    259     uint32_t bpp = GetBppForUncompressedRGB(format);
    260     size = alignedw * alignedh * bpp;
    261     return size;
    262   }
    263 
    264   if (IsCompressedRGBFormat(format)) {
    265     size = alignedw * alignedh * ASTC_BLOCK_SIZE;
    266     return size;
    267   }
    268 
    269   // Below switch should be for only YUV/custom formats
    270   switch (format) {
    271     case HAL_PIXEL_FORMAT_RAW16:
    272       size = alignedw * alignedh * 2;
    273       break;
    274     case HAL_PIXEL_FORMAT_RAW10:
    275       size = ALIGN(alignedw * alignedh, SIZE_4K);
    276       break;
    277 
    278     // adreno formats
    279     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
    280       size = ALIGN(alignedw * alignedh, SIZE_4K);
    281       size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
    282       break;
    283     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:  // NV12
    284       // The chroma plane is subsampled,
    285       // but the pitch in bytes is unchanged
    286       // The GPU needs 4K alignment, but the video decoder needs 8K
    287       size = ALIGN(alignedw * alignedh, SIZE_8K);
    288       size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
    289       break;
    290     case HAL_PIXEL_FORMAT_YV12:
    291       if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
    292         ALOGE("w or h is odd for the YV12 format");
    293         return 0;
    294       }
    295       size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
    296       size = ALIGN(size, (unsigned int)SIZE_4K);
    297       break;
    298     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    299     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    300       size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
    301       break;
    302     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    303     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    304     case HAL_PIXEL_FORMAT_YCbCr_422_I:
    305     case HAL_PIXEL_FORMAT_YCrCb_422_I:
    306       if (width & 1) {
    307         ALOGE("width is odd for the YUV422_SP format");
    308         return 0;
    309       }
    310       size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
    311       break;
    312     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    313     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    314       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
    315       break;
    316     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    317       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
    318       break;
    319     case HAL_PIXEL_FORMAT_BLOB:
    320     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
    321       if (height != 1) {
    322         ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
    323         return 0;
    324       }
    325       size = (unsigned int)width;
    326       break;
    327     case HAL_PIXEL_FORMAT_NV21_ZSL:
    328       size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
    329       break;
    330     default:
    331       ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
    332       return 0;
    333   }
    334 
    335   return size;
    336 }
    337 
    338 void Allocator::GetBufferSizeAndDimensions(int width, int height, int format, unsigned int *size,
    339                                            unsigned int *alignedw, unsigned int *alignedh) {
    340   BufferDescriptor descriptor = BufferDescriptor(width, height, format);
    341   GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
    342 
    343   *size = GetSize(descriptor, *alignedw, *alignedh);
    344 }
    345 
    346 void Allocator::GetBufferSizeAndDimensions(const BufferDescriptor &descriptor, unsigned int *size,
    347                                            unsigned int *alignedw, unsigned int *alignedh) {
    348   GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
    349 
    350   *size = GetSize(descriptor, *alignedw, *alignedh);
    351 }
    352 
    353 void Allocator::GetBufferAttributes(const BufferDescriptor &descriptor, unsigned int *alignedw,
    354                                     unsigned int *alignedh, int *tiled, unsigned int *size) {
    355   int format = descriptor.GetFormat();
    356   gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
    357   gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
    358 
    359   *tiled = false;
    360   if (IsUBwcEnabled(format, prod_usage, cons_usage) ||
    361       IsMacroTileEnabled(format, prod_usage, cons_usage)) {
    362     *tiled = true;
    363   }
    364 
    365   GetAlignedWidthAndHeight(descriptor, alignedw, alignedh);
    366   *size = GetSize(descriptor, *alignedw, *alignedh);
    367 }
    368 
    369 void Allocator::GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
    370                                       int color_format, struct android_ycbcr *ycbcr) {
    371   // UBWC buffer has these 4 planes in the following sequence:
    372   // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
    373   unsigned int y_meta_stride, y_meta_height, y_meta_size;
    374   unsigned int y_stride, y_height, y_size;
    375   unsigned int c_meta_stride, c_meta_height, c_meta_size;
    376   unsigned int alignment = 4096;
    377 
    378   y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
    379   y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
    380   y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
    381 
    382   y_stride = VENUS_Y_STRIDE(color_format, INT(width));
    383   y_height = VENUS_Y_SCANLINES(color_format, INT(height));
    384   y_size = ALIGN((y_stride * y_height), alignment);
    385 
    386   c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
    387   c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
    388   c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
    389 
    390   ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
    391   ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
    392   ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
    393   ycbcr->ystride = y_stride;
    394   ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
    395 }
    396 
    397 void Allocator::GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
    398                                   struct android_ycbcr *ycbcr) {
    399   unsigned int ystride, cstride;
    400 
    401   ystride = cstride = UINT(width) * bpp;
    402   ycbcr->y = reinterpret_cast<void *>(base);
    403   ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
    404   ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
    405   ycbcr->ystride = ystride;
    406   ycbcr->cstride = cstride;
    407   ycbcr->chroma_step = 2 * bpp;
    408 }
    409 
    410 int Allocator::GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
    411   int err = 0;
    412   uint32_t width = UINT(hnd->width);
    413   uint32_t height = UINT(hnd->height);
    414   int format = hnd->format;
    415   gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
    416   gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
    417   unsigned int ystride, cstride;
    418 
    419   memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
    420   MetaData_t *metadata = reinterpret_cast<MetaData_t *>(hnd->base_metadata);
    421 
    422   // Check if UBWC buffer has been rendered in linear format.
    423   if (metadata && (metadata->operation & LINEAR_FORMAT)) {
    424     format = INT(metadata->linearFormat);
    425   }
    426 
    427   // Check metadata if the geometry has been updated.
    428   if (metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
    429     int usage = 0;
    430 
    431     if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
    432       usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
    433     }
    434 
    435     BufferDescriptor descriptor =
    436         BufferDescriptor(metadata->bufferDim.sliceWidth, metadata->bufferDim.sliceHeight, format,
    437                          prod_usage, cons_usage);
    438     GetAlignedWidthAndHeight(descriptor, &width, &height);
    439   }
    440 
    441   // Get the chroma offsets from the handle width/height. We take advantage
    442   // of the fact the width _is_ the stride
    443   switch (format) {
    444     // Semiplanar
    445     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    446     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    447     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    448     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    449       // Same as YCbCr_420_SP_VENUS
    450       GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
    451       break;
    452 
    453     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
    454       GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
    455       break;
    456 
    457     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    458       GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
    459       ycbcr->chroma_step = 2;
    460       break;
    461 
    462     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    463       GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
    464       ycbcr->chroma_step = 3;
    465       break;
    466 
    467     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    468     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    469     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    470     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    471     case HAL_PIXEL_FORMAT_NV21_ZSL:
    472     case HAL_PIXEL_FORMAT_RAW16:
    473     case HAL_PIXEL_FORMAT_RAW10:
    474       GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
    475       std::swap(ycbcr->cb, ycbcr->cr);
    476       break;
    477 
    478     // Planar
    479     case HAL_PIXEL_FORMAT_YV12:
    480       ystride = width;
    481       cstride = ALIGN(width / 2, 16);
    482       ycbcr->y = reinterpret_cast<void *>(hnd->base);
    483       ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
    484       ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
    485       ycbcr->ystride = ystride;
    486       ycbcr->cstride = cstride;
    487       ycbcr->chroma_step = 1;
    488       break;
    489 
    490     // Unsupported formats
    491     case HAL_PIXEL_FORMAT_YCbCr_422_I:
    492     case HAL_PIXEL_FORMAT_YCrCb_422_I:
    493     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    494     default:
    495       ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
    496       err = -EINVAL;
    497   }
    498 
    499   return err;
    500 }
    501 
    502 int Allocator::GetImplDefinedFormat(gralloc1_producer_usage_t prod_usage,
    503                                     gralloc1_consumer_usage_t cons_usage, int format) {
    504   int gr_format = format;
    505 
    506   // If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
    507   // the usage bits, gralloc assigns a format.
    508   if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
    509       format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
    510     if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) {
    511       gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC;
    512     } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER) {
    513       gr_format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;  // NV12
    514     } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_ZSL) {
    515       gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21 ZSL
    516     } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) {
    517       gr_format = HAL_PIXEL_FORMAT_YCrCb_420_SP;  // NV21
    518     } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_CAMERA) {
    519       if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
    520         gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;  // NV21
    521       } else {
    522         gr_format = HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS;  // NV12 preview
    523       }
    524     } else if (cons_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) {
    525       // XXX: If we still haven't set a format, default to RGBA8888
    526       gr_format = HAL_PIXEL_FORMAT_RGBA_8888;
    527     } else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
    528       // If no other usage flags are detected, default the
    529       // flexible YUV format to NV21_ZSL
    530       gr_format = HAL_PIXEL_FORMAT_NV21_ZSL;
    531     }
    532   }
    533 
    534   return gr_format;
    535 }
    536 
    537 // Explicitly defined UBWC formats
    538 bool Allocator::IsUBwcFormat(int format) {
    539   switch (format) {
    540     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    541       return true;
    542     default:
    543       return false;
    544   }
    545 }
    546 
    547 bool Allocator::IsUBwcSupported(int format) {
    548   // Existing HAL formats with UBWC support
    549   switch (format) {
    550     case HAL_PIXEL_FORMAT_BGR_565:
    551     case HAL_PIXEL_FORMAT_RGBA_8888:
    552     case HAL_PIXEL_FORMAT_RGBX_8888:
    553     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    554     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    555       return true;
    556     default:
    557       break;
    558   }
    559 
    560   return false;
    561 }
    562 
    563 /* The default policy is to return cached buffers unless the client explicity
    564  * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
    565  * read or written in software. */
    566 // TODO(user) : As of now relying only on producer usage
    567 bool Allocator::UseUncached(gralloc1_producer_usage_t usage) {
    568   if ((usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_UNCACHED) ||
    569       (usage & GRALLOC1_PRODUCER_USAGE_PROTECTED)) {
    570     return true;
    571   }
    572 
    573   // CPU read rarely
    574   if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) &&
    575       !(usage & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN)) {
    576     return true;
    577   }
    578 
    579   // CPU  write rarely
    580   if ((usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) &&
    581       !(usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN)) {
    582     return true;
    583   }
    584 
    585   return false;
    586 }
    587 
    588 void Allocator::GetIonHeapInfo(gralloc1_producer_usage_t prod_usage,
    589                                gralloc1_consumer_usage_t cons_usage, unsigned int *ion_heap_id,
    590                                unsigned int *alloc_type, unsigned int *ion_flags) {
    591   unsigned int heap_id = 0;
    592   unsigned int type = 0;
    593   int flags = 0;
    594   if (prod_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED) {
    595     if (cons_usage & GRALLOC1_CONSUMER_USAGE_PRIVATE_SECURE_DISPLAY) {
    596       heap_id = ION_HEAP(SD_HEAP_ID);
    597       /*
    598        * There is currently no flag in ION for Secure Display
    599        * VM. Please add it to the define once available.
    600        */
    601       flags |= ION_SD_FLAGS;
    602     } else {
    603       heap_id = ION_HEAP(CP_HEAP_ID);
    604       flags |= ION_CP_FLAGS;
    605     }
    606   } else if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_MM_HEAP) {
    607     // MM Heap is exclusively a secure heap.
    608     // If it is used for non secure cases, fallback to IOMMU heap
    609     ALOGW("MM_HEAP cannot be used as an insecure heap. Using system heap instead!!");
    610     heap_id |= ION_HEAP(ION_SYSTEM_HEAP_ID);
    611   }
    612 
    613   if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_CAMERA_HEAP) {
    614     heap_id |= ION_HEAP(ION_CAMERA_HEAP_ID);
    615   }
    616 
    617   if (prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ADSP_HEAP) {
    618     heap_id |= ION_HEAP(ION_ADSP_HEAP_ID);
    619   }
    620 
    621   if (flags & ION_SECURE) {
    622     type |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
    623   }
    624 
    625   // if no ion heap flags are set, default to system heap
    626   if (!heap_id) {
    627     heap_id = ION_HEAP(ION_SYSTEM_HEAP_ID);
    628   }
    629 
    630   *alloc_type = type;
    631   *ion_flags = (unsigned int)flags;
    632   *ion_heap_id = heap_id;
    633 
    634   return;
    635 }
    636 
    637 bool Allocator::IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
    638                               gralloc1_consumer_usage_t cons_usage) {
    639   // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
    640   if (IsUBwcFormat(format)) {
    641     return true;
    642   }
    643 
    644   // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
    645   // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
    646   // usage flag and MDP supports the format.
    647   if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
    648     bool enable = true;
    649     // Query GPU for UBWC only if buffer is intended to be used by GPU.
    650     if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
    651         (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
    652       enable = adreno_helper_->IsUBWCSupportedByGPU(format);
    653     }
    654 
    655     // Allow UBWC, only if CPU usage flags are not set
    656     if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
    657       return true;
    658     }
    659   }
    660 
    661   return false;
    662 }
    663 
    664 void Allocator::GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
    665                                          unsigned int *aligned_h) {
    666   switch (format) {
    667     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    668     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    669     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    670       *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
    671       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
    672       break;
    673     default:
    674       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
    675       *aligned_w = 0;
    676       *aligned_h = 0;
    677       break;
    678   }
    679 }
    680 
    681 void Allocator::GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
    682   *block_width = 0;
    683   *block_height = 0;
    684 
    685   switch (bpp) {
    686     case 2:
    687     case 4:
    688       *block_width = 16;
    689       *block_height = 4;
    690       break;
    691     case 8:
    692       *block_width = 8;
    693       *block_height = 4;
    694       break;
    695     case 16:
    696       *block_width = 4;
    697       *block_height = 4;
    698       break;
    699     default:
    700       ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
    701       break;
    702   }
    703 }
    704 
    705 unsigned int Allocator::GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
    706   unsigned int size = 0;
    707   int meta_width, meta_height;
    708   int block_width, block_height;
    709 
    710   GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
    711   if (!block_width || !block_height) {
    712     ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
    713     return size;
    714   }
    715 
    716   // Align meta buffer height to 16 blocks
    717   meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
    718 
    719   // Align meta buffer width to 64 blocks
    720   meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
    721 
    722   // Align meta buffer size to 4K
    723   size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
    724 
    725   return size;
    726 }
    727 
    728 unsigned int Allocator::GetUBwcSize(int width, int height, int format, unsigned int alignedw,
    729                                     unsigned int alignedh) {
    730   unsigned int size = 0;
    731   uint32_t bpp = 0;
    732   switch (format) {
    733     case HAL_PIXEL_FORMAT_BGR_565:
    734     case HAL_PIXEL_FORMAT_RGBA_8888:
    735     case HAL_PIXEL_FORMAT_RGBX_8888:
    736     case HAL_PIXEL_FORMAT_RGBA_1010102:
    737     case HAL_PIXEL_FORMAT_RGBX_1010102:
    738       bpp = GetBppForUncompressedRGB(format);
    739       size = alignedw * alignedh * bpp;
    740       size += GetRgbUBwcMetaBufferSize(width, height, bpp);
    741       break;
    742     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    743     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    744     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    745       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
    746       break;
    747     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    748       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
    749       break;
    750     default:
    751       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
    752       break;
    753   }
    754 
    755   return size;
    756 }
    757 
    758 int Allocator::GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
    759   int err = 0;
    760 
    761   // This api is for RGB* formats
    762   if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
    763     return -EINVAL;
    764   }
    765 
    766   // linear buffer, nothing to do further
    767   if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
    768     *rgb_data = reinterpret_cast<void *>(hnd->base);
    769     return err;
    770   }
    771 
    772   unsigned int meta_size = 0;
    773   uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
    774   switch (hnd->format) {
    775     case HAL_PIXEL_FORMAT_BGR_565:
    776     case HAL_PIXEL_FORMAT_RGBA_8888:
    777     case HAL_PIXEL_FORMAT_RGBX_8888:
    778       meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
    779       break;
    780     default:
    781       ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
    782       err = -EINVAL;
    783       break;
    784   }
    785   *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
    786 
    787   return err;
    788 }
    789 
    790 void Allocator::GetAlignedWidthAndHeight(const BufferDescriptor &descriptor, unsigned int *alignedw,
    791                                          unsigned int *alignedh) {
    792   int width = descriptor.GetWidth();
    793   int height = descriptor.GetHeight();
    794   int format = descriptor.GetFormat();
    795   gralloc1_producer_usage_t prod_usage = descriptor.GetProducerUsage();
    796   gralloc1_consumer_usage_t cons_usage = descriptor.GetConsumerUsage();
    797 
    798   // Currently surface padding is only computed for RGB* surfaces.
    799   bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
    800   int tile = ubwc_enabled || IsMacroTileEnabled(format, prod_usage, cons_usage);
    801 
    802   if (IsUncompressedRGBFormat(format)) {
    803     adreno_helper_->AlignUnCompressedRGB(width, height, format, tile, alignedw, alignedh);
    804     return;
    805   }
    806 
    807   if (ubwc_enabled) {
    808     GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
    809     return;
    810   }
    811 
    812   if (IsCompressedRGBFormat(format)) {
    813     adreno_helper_->AlignCompressedRGB(width, height, format, alignedw, alignedh);
    814     return;
    815   }
    816 
    817   int aligned_w = width;
    818   int aligned_h = height;
    819   unsigned int alignment = 32;
    820 
    821   // Below should be only YUV family
    822   switch (format) {
    823     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    824     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    825       alignment = adreno_helper_->GetGpuPixelAlignment();
    826       aligned_w = ALIGN(width, alignment);
    827       break;
    828     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    829       aligned_w = ALIGN(width, alignment);
    830       break;
    831     case HAL_PIXEL_FORMAT_RAW16:
    832       aligned_w = ALIGN(width, 16);
    833       break;
    834     case HAL_PIXEL_FORMAT_RAW10:
    835       aligned_w = ALIGN(width * 10 / 8, 16);
    836       break;
    837     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    838       aligned_w = ALIGN(width, 128);
    839       break;
    840     case HAL_PIXEL_FORMAT_YV12:
    841     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    842     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    843     case HAL_PIXEL_FORMAT_YCbCr_422_I:
    844     case HAL_PIXEL_FORMAT_YCrCb_422_I:
    845       aligned_w = ALIGN(width, 16);
    846       break;
    847     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    848     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    849       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
    850       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
    851       break;
    852     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    853       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
    854       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
    855       break;
    856     case HAL_PIXEL_FORMAT_BLOB:
    857     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
    858       break;
    859     case HAL_PIXEL_FORMAT_NV21_ZSL:
    860       aligned_w = ALIGN(width, 64);
    861       aligned_h = ALIGN(height, 64);
    862       break;
    863     default:
    864       break;
    865   }
    866 
    867   *alignedw = (unsigned int)aligned_w;
    868   *alignedh = (unsigned int)aligned_h;
    869 }
    870 
    871 }  // namespace gralloc1
    872