Home | History | Annotate | Download | only in gralloc
      1 /*
      2  * Copyright (c) 2011-2017, 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 <media/msm_media_info.h>
     31 #include <algorithm>
     32 
     33 #include "gr_utils.h"
     34 #include "gr_adreno_info.h"
     35 #include "qdMetaData.h"
     36 
     37 #define ASTC_BLOCK_SIZE 16
     38 
     39 #ifndef COLOR_FMT_P010_UBWC
     40 #define COLOR_FMT_P010_UBWC 9
     41 #endif
     42 
     43 namespace gralloc1 {
     44 
     45 bool IsUncompressedRGBFormat(int format) {
     46   switch (format) {
     47     case HAL_PIXEL_FORMAT_RGBA_8888:
     48     case HAL_PIXEL_FORMAT_RGBX_8888:
     49     case HAL_PIXEL_FORMAT_RGB_888:
     50     case HAL_PIXEL_FORMAT_RGB_565:
     51     case HAL_PIXEL_FORMAT_BGR_565:
     52     case HAL_PIXEL_FORMAT_BGRA_8888:
     53     case HAL_PIXEL_FORMAT_RGBA_5551:
     54     case HAL_PIXEL_FORMAT_RGBA_4444:
     55     case HAL_PIXEL_FORMAT_R_8:
     56     case HAL_PIXEL_FORMAT_RG_88:
     57     case HAL_PIXEL_FORMAT_BGRX_8888:
     58     case HAL_PIXEL_FORMAT_RGBA_1010102:
     59     case HAL_PIXEL_FORMAT_ARGB_2101010:
     60     case HAL_PIXEL_FORMAT_RGBX_1010102:
     61     case HAL_PIXEL_FORMAT_XRGB_2101010:
     62     case HAL_PIXEL_FORMAT_BGRA_1010102:
     63     case HAL_PIXEL_FORMAT_ABGR_2101010:
     64     case HAL_PIXEL_FORMAT_BGRX_1010102:
     65     case HAL_PIXEL_FORMAT_XBGR_2101010:
     66     case HAL_PIXEL_FORMAT_RGBA_FP16:
     67     case HAL_PIXEL_FORMAT_BGR_888:
     68       return true;
     69     default:
     70       break;
     71   }
     72 
     73   return false;
     74 }
     75 
     76 bool IsCompressedRGBFormat(int format) {
     77   switch (format) {
     78     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
     79     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
     80     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
     81     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
     82     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
     83     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
     84     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
     85     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
     86     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
     87     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
     88     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
     89     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
     90     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
     91     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
     92     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
     93     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
     94     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
     95     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
     96     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
     97     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
     98     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
     99     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
    100     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
    101     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
    102     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
    103     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
    104     case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
    105     case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
    106       return true;
    107     default:
    108       break;
    109   }
    110 
    111   return false;
    112 }
    113 
    114 uint32_t GetBppForUncompressedRGB(int format) {
    115   uint32_t bpp = 0;
    116   switch (format) {
    117     case HAL_PIXEL_FORMAT_RGBA_FP16:
    118       bpp = 8;
    119       break;
    120     case HAL_PIXEL_FORMAT_RGBA_8888:
    121     case HAL_PIXEL_FORMAT_RGBX_8888:
    122     case HAL_PIXEL_FORMAT_BGRA_8888:
    123     case HAL_PIXEL_FORMAT_BGRX_8888:
    124     case HAL_PIXEL_FORMAT_RGBA_1010102:
    125     case HAL_PIXEL_FORMAT_ARGB_2101010:
    126     case HAL_PIXEL_FORMAT_RGBX_1010102:
    127     case HAL_PIXEL_FORMAT_XRGB_2101010:
    128     case HAL_PIXEL_FORMAT_BGRA_1010102:
    129     case HAL_PIXEL_FORMAT_ABGR_2101010:
    130     case HAL_PIXEL_FORMAT_BGRX_1010102:
    131     case HAL_PIXEL_FORMAT_XBGR_2101010:
    132       bpp = 4;
    133       break;
    134     case HAL_PIXEL_FORMAT_RGB_888:
    135     case HAL_PIXEL_FORMAT_BGR_888:
    136       bpp = 3;
    137       break;
    138     case HAL_PIXEL_FORMAT_RGB_565:
    139     case HAL_PIXEL_FORMAT_BGR_565:
    140     case HAL_PIXEL_FORMAT_RGBA_5551:
    141     case HAL_PIXEL_FORMAT_RGBA_4444:
    142       bpp = 2;
    143       break;
    144     default:
    145       ALOGE("Error : %s New format request = 0x%x", __FUNCTION__, format);
    146       break;
    147   }
    148 
    149   return bpp;
    150 }
    151 
    152 bool CpuCanAccess(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) {
    153   return CpuCanRead(prod_usage, cons_usage) || CpuCanWrite(prod_usage);
    154 }
    155 
    156 bool CpuCanRead(gralloc1_producer_usage_t prod_usage, gralloc1_consumer_usage_t cons_usage) {
    157   if (prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_READ) {
    158     return true;
    159   }
    160 
    161   if (cons_usage & GRALLOC1_CONSUMER_USAGE_CPU_READ) {
    162     return true;
    163   }
    164 
    165   return false;
    166 }
    167 
    168 bool CpuCanWrite(gralloc1_producer_usage_t prod_usage) {
    169   if (prod_usage & GRALLOC1_PRODUCER_USAGE_CPU_WRITE) {
    170     // Application intends to use CPU for rendering
    171     return true;
    172   }
    173 
    174   return false;
    175 }
    176 
    177 unsigned int GetSize(const BufferInfo &info, unsigned int alignedw,
    178                      unsigned int alignedh) {
    179   unsigned int size = 0;
    180   int format = info.format;
    181   int width = info.width;
    182   int height = info.height;
    183   gralloc1_producer_usage_t prod_usage = info.prod_usage;
    184   gralloc1_consumer_usage_t cons_usage = info.cons_usage;
    185 
    186   if (IsUBwcEnabled(format, prod_usage, cons_usage)) {
    187     return GetUBwcSize(width, height, format, alignedw, alignedh);
    188   }
    189 
    190   if (IsUncompressedRGBFormat(format)) {
    191     uint32_t bpp = GetBppForUncompressedRGB(format);
    192     size = alignedw * alignedh * bpp;
    193     return size;
    194   }
    195 
    196   if (IsCompressedRGBFormat(format)) {
    197     size = alignedw * alignedh * ASTC_BLOCK_SIZE;
    198     return size;
    199   }
    200 
    201   // Below switch should be for only YUV/custom formats
    202   switch (format) {
    203     case HAL_PIXEL_FORMAT_RAW16:
    204     case HAL_PIXEL_FORMAT_Y16:
    205       size = alignedw * alignedh * 2;
    206       break;
    207     case HAL_PIXEL_FORMAT_RAW10:
    208     case HAL_PIXEL_FORMAT_RAW12:
    209       size = ALIGN(alignedw * alignedh, SIZE_4K);
    210       break;
    211     case HAL_PIXEL_FORMAT_RAW8:
    212     case HAL_PIXEL_FORMAT_Y8:
    213       size = alignedw * alignedh * 1;
    214       break;
    215 
    216       // adreno formats
    217     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
    218       size = ALIGN(alignedw * alignedh, SIZE_4K);
    219       size += (unsigned int)ALIGN(2 * ALIGN(width / 2, 32) * ALIGN(height / 2, 32), SIZE_4K);
    220       break;
    221     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:  // NV12
    222       // The chroma plane is subsampled,
    223       // but the pitch in bytes is unchanged
    224       // The GPU needs 4K alignment, but the video decoder needs 8K
    225       size = ALIGN(alignedw * alignedh, SIZE_8K);
    226       size += ALIGN(alignedw * (unsigned int)ALIGN(height / 2, 32), SIZE_8K);
    227       break;
    228     case HAL_PIXEL_FORMAT_YV12:
    229       if ((format == HAL_PIXEL_FORMAT_YV12) && ((width & 1) || (height & 1))) {
    230         ALOGE("w or h is odd for the YV12 format");
    231         return 0;
    232       }
    233       size = alignedw * alignedh + (ALIGN(alignedw / 2, 16) * (alignedh / 2)) * 2;
    234       size = ALIGN(size, (unsigned int)SIZE_4K);
    235       break;
    236     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    237     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    238       size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2 + 1, SIZE_4K);
    239       break;
    240     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
    241       size = ALIGN((alignedw * alignedh * 2) + (alignedw * alignedh) + 1, SIZE_4K);
    242       break;
    243     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    244     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    245     case HAL_PIXEL_FORMAT_YCbCr_422_I:
    246     case HAL_PIXEL_FORMAT_YCrCb_422_I:
    247     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
    248       if (width & 1) {
    249         ALOGE("width is odd for the YUV422_SP format");
    250         return 0;
    251       }
    252       size = ALIGN(alignedw * alignedh * 2, SIZE_4K);
    253       break;
    254     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    255     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    256       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
    257       break;
    258     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    259       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
    260       break;
    261     case HAL_PIXEL_FORMAT_BLOB:
    262     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
    263       if (height != 1) {
    264         ALOGE("%s: Buffers with HAL_PIXEL_FORMAT_BLOB must have height 1 ", __FUNCTION__);
    265         return 0;
    266       }
    267       size = (unsigned int)width;
    268       break;
    269     case HAL_PIXEL_FORMAT_NV21_ZSL:
    270       size = ALIGN((alignedw * alignedh) + (alignedw * alignedh) / 2, SIZE_4K);
    271       break;
    272     default:
    273       ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
    274       return 0;
    275   }
    276 
    277   return size;
    278 }
    279 
    280 void GetBufferSizeAndDimensions(const BufferInfo &info, unsigned int *size,
    281                                 unsigned int *alignedw, unsigned int *alignedh) {
    282   GetAlignedWidthAndHeight(info, alignedw, alignedh);
    283   *size = GetSize(info, *alignedw, *alignedh);
    284 }
    285 
    286 void GetYuvUbwcSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
    287                            int color_format, struct android_ycbcr *ycbcr) {
    288   // UBWC buffer has these 4 planes in the following sequence:
    289   // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
    290   unsigned int y_meta_stride, y_meta_height, y_meta_size;
    291   unsigned int y_stride, y_height, y_size;
    292   unsigned int c_meta_stride, c_meta_height, c_meta_size;
    293   unsigned int alignment = 4096;
    294 
    295   y_meta_stride = VENUS_Y_META_STRIDE(color_format, INT(width));
    296   y_meta_height = VENUS_Y_META_SCANLINES(color_format, INT(height));
    297   y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
    298 
    299   y_stride = VENUS_Y_STRIDE(color_format, INT(width));
    300   y_height = VENUS_Y_SCANLINES(color_format, INT(height));
    301   y_size = ALIGN((y_stride * y_height), alignment);
    302 
    303   c_meta_stride = VENUS_UV_META_STRIDE(color_format, INT(width));
    304   c_meta_height = VENUS_UV_META_SCANLINES(color_format, INT(height));
    305   c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
    306 
    307   ycbcr->y = reinterpret_cast<void *>(base + y_meta_size);
    308   ycbcr->cb = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size);
    309   ycbcr->cr = reinterpret_cast<void *>(base + y_meta_size + y_size + c_meta_size + 1);
    310   ycbcr->ystride = y_stride;
    311   ycbcr->cstride = VENUS_UV_STRIDE(color_format, INT(width));
    312 }
    313 
    314 void GetYuvUbwcInterlacedSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height,
    315                                      int color_format, struct android_ycbcr *ycbcr) {
    316   unsigned int uv_stride, uv_height, uv_size;
    317   unsigned int alignment = 4096;
    318   uint64_t field_base;
    319 
    320   // UBWC interlaced has top-bottom field layout with each field as
    321   // 4-plane NV12_UBWC with width = image_width & height = image_height / 2.
    322   // Client passed ycbcr argument is ptr to struct android_ycbcr[2].
    323   // Plane info to be filled for each field separately.
    324   height = (height + 1) >> 1;
    325   uv_stride = VENUS_UV_STRIDE(color_format, INT(width));
    326   uv_height = VENUS_UV_SCANLINES(color_format, INT(height));
    327   uv_size = ALIGN((uv_stride * uv_height), alignment);
    328 
    329   field_base = base;
    330   GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[0]);
    331 
    332   field_base = reinterpret_cast<uint64_t>(ycbcr[0].cb) + uv_size;
    333   GetYuvUbwcSPPlaneInfo(field_base, width, height, COLOR_FMT_NV12_UBWC, &ycbcr[1]);
    334 }
    335 
    336 void GetYuvSPPlaneInfo(uint64_t base, uint32_t width, uint32_t height, uint32_t bpp,
    337                        struct android_ycbcr *ycbcr) {
    338   unsigned int ystride, cstride;
    339 
    340   ystride = cstride = UINT(width) * bpp;
    341   ycbcr->y = reinterpret_cast<void *>(base);
    342   ycbcr->cb = reinterpret_cast<void *>(base + ystride * UINT(height));
    343   ycbcr->cr = reinterpret_cast<void *>(base + ystride * UINT(height) + 1);
    344   ycbcr->ystride = ystride;
    345   ycbcr->cstride = cstride;
    346   ycbcr->chroma_step = 2 * bpp;
    347 }
    348 
    349 int GetYUVPlaneInfo(const private_handle_t *hnd, struct android_ycbcr *ycbcr) {
    350   int err = 0;
    351   uint32_t width = UINT(hnd->width);
    352   uint32_t height = UINT(hnd->height);
    353   int format = hnd->format;
    354   gralloc1_producer_usage_t prod_usage = hnd->GetProducerUsage();
    355   gralloc1_consumer_usage_t cons_usage = hnd->GetConsumerUsage();
    356   unsigned int ystride, cstride;
    357   bool interlaced = false;
    358 
    359   memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
    360 
    361   // Check if UBWC buffer has been rendered in linear format.
    362   int linear_format = 0;
    363   if (getMetaData(const_cast<private_handle_t *>(hnd),
    364                   GET_LINEAR_FORMAT, &linear_format) == 0) {
    365       format = INT(linear_format);
    366   }
    367 
    368   // Check metadata if the geometry has been updated.
    369   BufferDim_t buffer_dim;
    370   if (getMetaData(const_cast<private_handle_t *>(hnd),
    371                   GET_BUFFER_GEOMETRY, &buffer_dim) == 0) {
    372     int usage = 0;
    373     if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
    374       usage = GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC;
    375     }
    376 
    377     BufferInfo info(buffer_dim.sliceWidth, buffer_dim.sliceHeight, format,
    378                     prod_usage, cons_usage);
    379     GetAlignedWidthAndHeight(info, &width, &height);
    380   }
    381 
    382   // Check metadata for interlaced content.
    383   int interlace_flag = 0;
    384   if (getMetaData(const_cast<private_handle_t *>(hnd),
    385                   GET_PP_PARAM_INTERLACED, &interlace_flag) != 0) {
    386     interlaced = interlace_flag;
    387   }
    388 
    389   // Get the chroma offsets from the handle width/height. We take advantage
    390   // of the fact the width _is_ the stride
    391   switch (format) {
    392     // Semiplanar
    393     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    394     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    395     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    396     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    397       // Same as YCbCr_420_SP_VENUS
    398       GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
    399       break;
    400 
    401     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
    402       GetYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
    403       break;
    404 
    405     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    406       if (!interlaced) {
    407         GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
    408       } else {
    409         GetYuvUbwcInterlacedSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_UBWC, ycbcr);
    410       }
    411       ycbcr->chroma_step = 2;
    412       break;
    413 
    414     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    415       GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
    416       ycbcr->chroma_step = 3;
    417       break;
    418 
    419     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
    420       GetYuvUbwcSPPlaneInfo(hnd->base, width, height, COLOR_FMT_P010_UBWC, ycbcr);
    421       ycbcr->chroma_step = 4;
    422       break;
    423 
    424     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    425     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    426     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    427     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    428     case HAL_PIXEL_FORMAT_NV21_ZSL:
    429     case HAL_PIXEL_FORMAT_RAW16:
    430     case HAL_PIXEL_FORMAT_Y16:
    431     case HAL_PIXEL_FORMAT_RAW10:
    432     case HAL_PIXEL_FORMAT_RAW8:
    433     case HAL_PIXEL_FORMAT_Y8:
    434       GetYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
    435       std::swap(ycbcr->cb, ycbcr->cr);
    436       break;
    437 
    438       // Planar
    439     case HAL_PIXEL_FORMAT_YV12:
    440       ystride = width;
    441       cstride = ALIGN(width / 2, 16);
    442       ycbcr->y = reinterpret_cast<void *>(hnd->base);
    443       ycbcr->cr = reinterpret_cast<void *>(hnd->base + ystride * height);
    444       ycbcr->cb = reinterpret_cast<void *>(hnd->base + ystride * height + cstride * height / 2);
    445       ycbcr->ystride = ystride;
    446       ycbcr->cstride = cstride;
    447       ycbcr->chroma_step = 1;
    448       break;
    449     case HAL_PIXEL_FORMAT_CbYCrY_422_I:
    450       ystride = width * 2;
    451       cstride = 0;
    452       ycbcr->y  = reinterpret_cast<void *>(hnd->base);
    453       ycbcr->cr = NULL;
    454       ycbcr->cb = NULL;
    455       ycbcr->ystride = ystride;
    456       ycbcr->cstride = 0;
    457       ycbcr->chroma_step = 0;
    458       break;
    459       // Unsupported formats
    460     case HAL_PIXEL_FORMAT_YCbCr_422_I:
    461     case HAL_PIXEL_FORMAT_YCrCb_422_I:
    462     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    463     default:
    464       ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
    465       err = -EINVAL;
    466   }
    467 
    468   return err;
    469 }
    470 
    471 // Explicitly defined UBWC formats
    472 bool IsUBwcFormat(int format) {
    473   switch (format) {
    474     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    475     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    476     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
    477       return true;
    478     default:
    479       return false;
    480   }
    481 }
    482 
    483 bool IsUBwcSupported(int format) {
    484   // Existing HAL formats with UBWC support
    485   switch (format) {
    486     case HAL_PIXEL_FORMAT_BGR_565:
    487     case HAL_PIXEL_FORMAT_RGBA_8888:
    488     case HAL_PIXEL_FORMAT_RGBX_8888:
    489     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    490     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    491     case HAL_PIXEL_FORMAT_RGBA_1010102:
    492     case HAL_PIXEL_FORMAT_RGBX_1010102:
    493       return true;
    494     default:
    495       break;
    496   }
    497 
    498   return false;
    499 }
    500 
    501 bool IsUBwcEnabled(int format, gralloc1_producer_usage_t prod_usage,
    502                    gralloc1_consumer_usage_t cons_usage) {
    503   // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
    504   if (IsUBwcFormat(format)) {
    505     return true;
    506   }
    507 
    508   // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
    509   // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
    510   // usage flag and MDP supports the format.
    511   if ((prod_usage & GRALLOC1_PRODUCER_USAGE_PRIVATE_ALLOC_UBWC) && IsUBwcSupported(format)) {
    512     bool enable = true;
    513     // Query GPU for UBWC only if buffer is intended to be used by GPU.
    514     if ((cons_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) ||
    515         (prod_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET)) {
    516       if (AdrenoMemInfo::GetInstance()) {
    517         enable = AdrenoMemInfo::GetInstance()->IsUBWCSupportedByGPU(format);
    518       }
    519     }
    520 
    521     // Allow UBWC, only if CPU usage flags are not set
    522     if (enable && !(CpuCanAccess(prod_usage, cons_usage))) {
    523       return true;
    524     }
    525   }
    526 
    527   return false;
    528 }
    529 
    530 void GetYuvUBwcWidthAndHeight(int width, int height, int format, unsigned int *aligned_w,
    531                               unsigned int *aligned_h) {
    532   switch (format) {
    533     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    534     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    535     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    536       *aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
    537       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
    538       break;
    539     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    540       // The macro returns the stride which is 4/3 times the width, hence * 3/4
    541       *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width) * 3) / 4;
    542       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
    543       break;
    544     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
    545       // The macro returns the stride which is 2 times the width, hence / 2
    546       *aligned_w = (VENUS_Y_STRIDE(COLOR_FMT_P010_UBWC, width) / 2);
    547       *aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_P010_UBWC, height);
    548       break;
    549     default:
    550       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
    551       *aligned_w = 0;
    552       *aligned_h = 0;
    553       break;
    554   }
    555 }
    556 
    557 void GetRgbUBwcBlockSize(uint32_t bpp, int *block_width, int *block_height) {
    558   *block_width = 0;
    559   *block_height = 0;
    560 
    561   switch (bpp) {
    562     case 2:
    563     case 4:
    564       *block_width = 16;
    565       *block_height = 4;
    566       break;
    567     case 8:
    568       *block_width = 8;
    569       *block_height = 4;
    570       break;
    571     case 16:
    572       *block_width = 4;
    573       *block_height = 4;
    574       break;
    575     default:
    576       ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
    577       break;
    578   }
    579 }
    580 
    581 unsigned int GetRgbUBwcMetaBufferSize(int width, int height, uint32_t bpp) {
    582   unsigned int size = 0;
    583   int meta_width, meta_height;
    584   int block_width, block_height;
    585 
    586   GetRgbUBwcBlockSize(bpp, &block_width, &block_height);
    587   if (!block_width || !block_height) {
    588     ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
    589     return size;
    590   }
    591 
    592   // Align meta buffer height to 16 blocks
    593   meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
    594 
    595   // Align meta buffer width to 64 blocks
    596   meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
    597 
    598   // Align meta buffer size to 4K
    599   size = (unsigned int)ALIGN((meta_width * meta_height), 4096);
    600 
    601   return size;
    602 }
    603 
    604 unsigned int GetUBwcSize(int width, int height, int format, unsigned int alignedw,
    605                          unsigned int alignedh) {
    606   unsigned int size = 0;
    607   uint32_t bpp = 0;
    608   switch (format) {
    609     case HAL_PIXEL_FORMAT_BGR_565:
    610     case HAL_PIXEL_FORMAT_RGBA_8888:
    611     case HAL_PIXEL_FORMAT_RGBX_8888:
    612     case HAL_PIXEL_FORMAT_RGBA_1010102:
    613     case HAL_PIXEL_FORMAT_RGBX_1010102:
    614       bpp = GetBppForUncompressedRGB(format);
    615       size = alignedw * alignedh * bpp;
    616       size += GetRgbUBwcMetaBufferSize(width, height, bpp);
    617       break;
    618     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    619     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    620     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    621       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
    622       break;
    623     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    624       size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
    625       break;
    626     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
    627       size = VENUS_BUFFER_SIZE(COLOR_FMT_P010_UBWC, width, height);
    628       break;
    629     default:
    630       ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
    631       break;
    632   }
    633 
    634   return size;
    635 }
    636 
    637 int GetRgbDataAddress(private_handle_t *hnd, void **rgb_data) {
    638   int err = 0;
    639 
    640   // This api is for RGB* formats
    641   if (!gralloc1::IsUncompressedRGBFormat(hnd->format)) {
    642     return -EINVAL;
    643   }
    644 
    645   // linear buffer, nothing to do further
    646   if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
    647     *rgb_data = reinterpret_cast<void *>(hnd->base);
    648     return err;
    649   }
    650 
    651   unsigned int meta_size = 0;
    652   uint32_t bpp = GetBppForUncompressedRGB(hnd->format);
    653   switch (hnd->format) {
    654     case HAL_PIXEL_FORMAT_BGR_565:
    655     case HAL_PIXEL_FORMAT_RGBA_8888:
    656     case HAL_PIXEL_FORMAT_RGBX_8888:
    657     case HAL_PIXEL_FORMAT_RGBA_1010102:
    658     case HAL_PIXEL_FORMAT_RGBX_1010102:
    659       meta_size = GetRgbUBwcMetaBufferSize(hnd->width, hnd->height, bpp);
    660       break;
    661     default:
    662       ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
    663       err = -EINVAL;
    664       break;
    665   }
    666   *rgb_data = reinterpret_cast<void *>(hnd->base + meta_size);
    667 
    668   return err;
    669 }
    670 
    671 void GetAlignedWidthAndHeight(const BufferInfo &info, unsigned int *alignedw,
    672                               unsigned int *alignedh) {
    673   int width = info.width;
    674   int height = info.height;
    675   int format = info.format;
    676   gralloc1_producer_usage_t prod_usage = info.prod_usage;
    677   gralloc1_consumer_usage_t cons_usage = info.cons_usage;
    678 
    679   // Currently surface padding is only computed for RGB* surfaces.
    680   bool ubwc_enabled = IsUBwcEnabled(format, prod_usage, cons_usage);
    681   int tile = ubwc_enabled;
    682 
    683   if (IsUncompressedRGBFormat(format)) {
    684     if (AdrenoMemInfo::GetInstance()) {
    685       AdrenoMemInfo::GetInstance()->AlignUnCompressedRGB(width, height, format, tile, alignedw,
    686                                                          alignedh);
    687     }
    688     return;
    689   }
    690 
    691   if (ubwc_enabled) {
    692     GetYuvUBwcWidthAndHeight(width, height, format, alignedw, alignedh);
    693     return;
    694   }
    695 
    696   if (IsCompressedRGBFormat(format)) {
    697     if (AdrenoMemInfo::GetInstance()) {
    698       AdrenoMemInfo::GetInstance()->AlignCompressedRGB(width, height, format, alignedw, alignedh);
    699     }
    700     return;
    701   }
    702 
    703   int aligned_w = width;
    704   int aligned_h = height;
    705   unsigned int alignment = 32;
    706 
    707   // Below should be only YUV family
    708   switch (format) {
    709     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    710     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    711       if (AdrenoMemInfo::GetInstance() == nullptr) {
    712         return;
    713       }
    714       alignment = AdrenoMemInfo::GetInstance()->GetGpuPixelAlignment();
    715       aligned_w = ALIGN(width, alignment);
    716       break;
    717     case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    718       aligned_w = ALIGN(width, alignment);
    719       break;
    720     case HAL_PIXEL_FORMAT_RAW16:
    721     case HAL_PIXEL_FORMAT_Y16:
    722     case HAL_PIXEL_FORMAT_Y8:
    723       aligned_w = ALIGN(width, 16);
    724       break;
    725     case HAL_PIXEL_FORMAT_RAW12:
    726       aligned_w = ALIGN(width * 12 / 8, 8);
    727       break;
    728     case HAL_PIXEL_FORMAT_RAW10:
    729       aligned_w = ALIGN(width * 10 / 8, 8);
    730       break;
    731     case HAL_PIXEL_FORMAT_RAW8:
    732       aligned_w = ALIGN(width, 8);
    733       break;
    734     case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    735       aligned_w = ALIGN(width, 128);
    736       break;
    737     case HAL_PIXEL_FORMAT_YV12:
    738     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    739     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    740     case HAL_PIXEL_FORMAT_YCbCr_422_I:
    741     case HAL_PIXEL_FORMAT_YCrCb_422_I:
    742     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
    743       aligned_w = ALIGN(width, 16);
    744       break;
    745     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    746     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    747       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV12, width));
    748       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV12, height));
    749       break;
    750     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    751       aligned_w = INT(VENUS_Y_STRIDE(COLOR_FMT_NV21, width));
    752       aligned_h = INT(VENUS_Y_SCANLINES(COLOR_FMT_NV21, height));
    753       break;
    754     case HAL_PIXEL_FORMAT_BLOB:
    755     case HAL_PIXEL_FORMAT_RAW_OPAQUE:
    756       break;
    757     case HAL_PIXEL_FORMAT_NV21_ZSL:
    758       aligned_w = ALIGN(width, 64);
    759       aligned_h = ALIGN(height, 64);
    760       break;
    761     default:
    762       break;
    763   }
    764 
    765   *alignedw = (unsigned int)aligned_w;
    766   *alignedh = (unsigned int)aligned_h;
    767 }
    768 
    769 int GetBufferLayout(private_handle_t *hnd, uint32_t stride[4],
    770                     uint32_t offset[4], uint32_t *num_planes) {
    771   if (!hnd || !stride || !offset || !num_planes) {
    772     return -EINVAL;
    773   }
    774 
    775   struct android_ycbcr yuvInfo = {};
    776   *num_planes = 1;
    777   stride[0] = 0;
    778 
    779   switch (hnd->format) {
    780     case HAL_PIXEL_FORMAT_RGB_565:
    781     case HAL_PIXEL_FORMAT_BGR_565:
    782     case HAL_PIXEL_FORMAT_RGBA_5551:
    783     case HAL_PIXEL_FORMAT_RGBA_4444:
    784       stride[0] = static_cast<uint32_t>(hnd->width * 2);
    785       break;
    786     case HAL_PIXEL_FORMAT_RGB_888:
    787       stride[0] = static_cast<uint32_t>(hnd->width * 3);
    788       break;
    789     case HAL_PIXEL_FORMAT_RGBA_8888:
    790     case HAL_PIXEL_FORMAT_BGRA_8888:
    791     case HAL_PIXEL_FORMAT_RGBX_8888:
    792     case HAL_PIXEL_FORMAT_BGRX_8888:
    793     case HAL_PIXEL_FORMAT_RGBA_1010102:
    794     case HAL_PIXEL_FORMAT_ARGB_2101010:
    795     case HAL_PIXEL_FORMAT_RGBX_1010102:
    796     case HAL_PIXEL_FORMAT_XRGB_2101010:
    797     case HAL_PIXEL_FORMAT_BGRA_1010102:
    798     case HAL_PIXEL_FORMAT_ABGR_2101010:
    799     case HAL_PIXEL_FORMAT_BGRX_1010102:
    800     case HAL_PIXEL_FORMAT_XBGR_2101010:
    801       stride[0] = static_cast<uint32_t>(hnd->width * 4);
    802       break;
    803   }
    804 
    805   // Format is RGB
    806   if (stride[0]) {
    807     return 0;
    808   }
    809 
    810   (*num_planes)++;
    811   int ret = GetYUVPlaneInfo(hnd, &yuvInfo);
    812   if (ret < 0) {
    813     ALOGE("%s failed", __FUNCTION__);
    814     return ret;
    815   }
    816 
    817   stride[0] = static_cast<uint32_t>(yuvInfo.ystride);
    818   offset[0] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.y) - hnd->base);
    819   stride[1] = static_cast<uint32_t>(yuvInfo.cstride);
    820   switch (hnd->format) {
    821     case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    822     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    823     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    824     case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    825     case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    826     case HAL_PIXEL_FORMAT_YCbCr_420_P010:
    827     case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    828     case HAL_PIXEL_FORMAT_YCbCr_420_P010_UBWC:
    829       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
    830       break;
    831     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    832     case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    833     case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    834       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
    835       break;
    836     case HAL_PIXEL_FORMAT_YV12:
    837       offset[1] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cr) - hnd->base);
    838       stride[2] = static_cast<uint32_t>(yuvInfo.cstride);
    839       offset[2] = static_cast<uint32_t>(reinterpret_cast<uint64_t>(yuvInfo.cb) - hnd->base);
    840       (*num_planes)++;
    841       break;
    842     default:
    843       ALOGW("%s: Unsupported format", __FUNCTION__);
    844       ret = -EINVAL;
    845   }
    846 
    847   if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
    848     std::fill(offset, offset + 4, 0);
    849   }
    850 
    851   return 0;
    852 }
    853 
    854 }  // namespace gralloc1
    855