Home | History | Annotate | Download | only in libgralloc
      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 <fcntl.h>
     32 #include <dlfcn.h>
     33 #include "gralloc_priv.h"
     34 #include "alloc_controller.h"
     35 #include "memalloc.h"
     36 #include "ionalloc.h"
     37 #include "gr.h"
     38 #include "qd_utils.h"
     39 #include <qdMetaData.h>
     40 #include <utils/Singleton.h>
     41 #include <utils/Mutex.h>
     42 
     43 
     44 #ifdef VENUS_COLOR_FORMAT
     45 #include <media/msm_media_info.h>
     46 #else
     47 #define VENUS_Y_STRIDE(args...) 0
     48 #define VENUS_Y_SCANLINES(args...) 0
     49 #define VENUS_BUFFER_SIZE(args...) 0
     50 #endif
     51 
     52 #define ASTC_BLOCK_SIZE 16
     53 
     54 #ifndef ION_FLAG_CP_PIXEL
     55 #define ION_FLAG_CP_PIXEL 0
     56 #endif
     57 
     58 #ifndef ION_FLAG_ALLOW_NON_CONTIG
     59 #define ION_FLAG_ALLOW_NON_CONTIG 0
     60 #endif
     61 
     62 #ifdef MASTER_SIDE_CP
     63 #define CP_HEAP_ID ION_SECURE_HEAP_ID
     64 #define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
     65 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
     66 #define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
     67 #else // SLAVE_SIDE_CP
     68 #define CP_HEAP_ID ION_CP_MM_HEAP_ID
     69 #define SD_HEAP_ID CP_HEAP_ID
     70 #define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
     71 #define ION_SD_FLAGS ION_SECURE
     72 #endif
     73 
     74 using namespace gralloc;
     75 using namespace qdutils;
     76 using namespace android;
     77 
     78 ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
     79 ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo);
     80 
     81 static void getYuvUBwcWidthHeight(int, int, int, int&, int&);
     82 static unsigned int getUBwcSize(int, int, int, const int, const int);
     83 
     84 //Common functions
     85 
     86 /* The default policy is to return cached buffers unless the client explicity
     87  * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
     88  * read or written in software. Any combination with a _RARELY_ flag will be
     89  * treated as uncached. */
     90 static bool useUncached(const int& usage) {
     91     if ((usage & GRALLOC_USAGE_PROTECTED) or
     92         (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
     93         ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
     94         ((usage & GRALLOC_USAGE_SW_READ_MASK) ==  GRALLOC_USAGE_SW_READ_RARELY))
     95         return true;
     96 
     97     return false;
     98 }
     99 
    100 //------------- MDPCapabilityInfo-----------------------//
    101 MDPCapabilityInfo :: MDPCapabilityInfo() {
    102   qdutils::querySDEInfo(HAS_MACRO_TILE, &isMacroTileSupported);
    103   qdutils::querySDEInfo(HAS_UBWC, &isUBwcSupported);
    104 }
    105 
    106 //------------- AdrenoMemInfo-----------------------//
    107 AdrenoMemInfo::AdrenoMemInfo()
    108 {
    109     LINK_adreno_compute_aligned_width_and_height = NULL;
    110     LINK_adreno_compute_padding = NULL;
    111     LINK_adreno_isMacroTilingSupportedByGpu = NULL;
    112     LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
    113     LINK_adreno_isUBWCSupportedByGpu = NULL;
    114     LINK_adreno_get_gpu_pixel_alignment = NULL;
    115 
    116     libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
    117     if (libadreno_utils) {
    118         *(void **)&LINK_adreno_compute_aligned_width_and_height =
    119                 ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
    120         *(void **)&LINK_adreno_compute_padding =
    121                 ::dlsym(libadreno_utils, "compute_surface_padding");
    122         *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
    123                 ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
    124         *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
    125                 ::dlsym(libadreno_utils,
    126                         "compute_compressedfmt_aligned_width_and_height");
    127         *(void **)&LINK_adreno_isUBWCSupportedByGpu =
    128                 ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
    129         *(void **)&LINK_adreno_get_gpu_pixel_alignment =
    130                 ::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
    131     }
    132 
    133     // Check if the overriding property debug.gralloc.gfx_ubwc_disable
    134     // that disables UBWC allocations for the graphics stack is set
    135     gfx_ubwc_disable = 0;
    136     char property[PROPERTY_VALUE_MAX];
    137     property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
    138     if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
    139        !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
    140         gfx_ubwc_disable = 1;
    141     }
    142 }
    143 
    144 AdrenoMemInfo::~AdrenoMemInfo()
    145 {
    146     if (libadreno_utils) {
    147         ::dlclose(libadreno_utils);
    148     }
    149 }
    150 
    151 int AdrenoMemInfo::isMacroTilingSupportedByGPU()
    152 {
    153     if ((libadreno_utils)) {
    154         if(LINK_adreno_isMacroTilingSupportedByGpu) {
    155             return LINK_adreno_isMacroTilingSupportedByGpu();
    156         }
    157     }
    158     return 0;
    159 }
    160 
    161 void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
    162                           int& aligned_h) {
    163     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
    164     if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
    165         int w = metadata->bufferDim.sliceWidth;
    166         int h = metadata->bufferDim.sliceHeight;
    167         int f = hnd->format;
    168         int usage = 0;
    169 
    170         if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
    171             usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
    172         }
    173 
    174         getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h);
    175     } else {
    176         aligned_w = hnd->width;
    177         aligned_h = hnd->height;
    178     }
    179 
    180 }
    181 
    182 bool isUncompressedRgbFormat(int format)
    183 {
    184     bool is_rgb_format = false;
    185 
    186     switch (format)
    187     {
    188         case HAL_PIXEL_FORMAT_RGBA_8888:
    189         case HAL_PIXEL_FORMAT_RGBX_8888:
    190         case HAL_PIXEL_FORMAT_RGB_888:
    191         case HAL_PIXEL_FORMAT_RGB_565:
    192         case HAL_PIXEL_FORMAT_BGR_565:
    193         case HAL_PIXEL_FORMAT_BGRA_8888:
    194         case HAL_PIXEL_FORMAT_RGBA_FP16:
    195         case HAL_PIXEL_FORMAT_RGBA_5551:
    196         case HAL_PIXEL_FORMAT_RGBA_4444:
    197         case HAL_PIXEL_FORMAT_R_8:
    198         case HAL_PIXEL_FORMAT_RG_88:
    199         case HAL_PIXEL_FORMAT_BGRX_8888:
    200         case HAL_PIXEL_FORMAT_RGBA_1010102:
    201         case HAL_PIXEL_FORMAT_ARGB_2101010:
    202         case HAL_PIXEL_FORMAT_RGBX_1010102:
    203         case HAL_PIXEL_FORMAT_XRGB_2101010:
    204         case HAL_PIXEL_FORMAT_BGRA_1010102:
    205         case HAL_PIXEL_FORMAT_ABGR_2101010:
    206         case HAL_PIXEL_FORMAT_BGRX_1010102:
    207         case HAL_PIXEL_FORMAT_XBGR_2101010:    // Intentional fallthrough
    208             is_rgb_format = true;
    209             break;
    210         default:
    211             break;
    212     }
    213 
    214     return is_rgb_format;
    215 }
    216 
    217 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
    218                             int usage, int& aligned_w, int& aligned_h)
    219 {
    220     bool ubwc_enabled = isUBwcEnabled(format, usage);
    221 
    222     // Currently surface padding is only computed for RGB* surfaces.
    223     if (isUncompressedRgbFormat(format) == true) {
    224         int tileEnabled = ubwc_enabled || isMacroTileEnabled(format, usage);
    225         getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h);
    226     } else if (ubwc_enabled) {
    227         getYuvUBwcWidthHeight(width, height, format, aligned_w, aligned_h);
    228     } else {
    229         aligned_w = width;
    230         aligned_h = height;
    231         int alignment = 32;
    232         switch (format)
    233         {
    234             case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    235             case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    236                 if (LINK_adreno_get_gpu_pixel_alignment) {
    237                   alignment = LINK_adreno_get_gpu_pixel_alignment();
    238                 }
    239                 aligned_w = ALIGN(width, alignment);
    240                 break;
    241             case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    242                 aligned_w = ALIGN(width, alignment);
    243                 break;
    244             case HAL_PIXEL_FORMAT_RAW16:
    245                 aligned_w = ALIGN(width, 16);
    246                 break;
    247             case HAL_PIXEL_FORMAT_RAW10:
    248                 aligned_w = ALIGN(width * 10 / 8, 8);
    249                 break;
    250             case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    251                 aligned_w = ALIGN(width, 128);
    252                 break;
    253             case HAL_PIXEL_FORMAT_YV12:
    254             case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    255             case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    256             case HAL_PIXEL_FORMAT_YCbCr_422_I:
    257             case HAL_PIXEL_FORMAT_YCrCb_422_I:
    258                 aligned_w = ALIGN(width, 16);
    259                 break;
    260             case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    261             case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    262                 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
    263                 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
    264                 break;
    265             case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    266                 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width);
    267                 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height);
    268                 break;
    269             case HAL_PIXEL_FORMAT_BLOB:
    270             case HAL_PIXEL_FORMAT_RAW_OPAQUE:
    271                 break;
    272             case HAL_PIXEL_FORMAT_NV21_ZSL:
    273                 aligned_w = ALIGN(width, 64);
    274                 aligned_h = ALIGN(height, 64);
    275                 break;
    276             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
    277             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
    278             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
    279             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
    280             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
    281             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
    282             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
    283             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
    284             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
    285             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
    286             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
    287             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
    288             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
    289             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
    290             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
    291             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
    292             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
    293             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
    294             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
    295             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
    296             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
    297             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
    298             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
    299             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
    300             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
    301             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
    302             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
    303             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
    304                 if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
    305                     int bytesPerPixel = 0;
    306                     int raster_mode         = 0;   //Adreno unknown raster mode.
    307                     int padding_threshold   = 512; //Threshold for padding
    308                     //surfaces.
    309 
    310                     LINK_adreno_compute_compressedfmt_aligned_width_and_height(
    311                         width, height, format, 0,raster_mode, padding_threshold,
    312                         &aligned_w, &aligned_h, &bytesPerPixel);
    313                 } else {
    314                     ALOGW("%s: Warning!! Symbols" \
    315                           " compute_compressedfmt_aligned_width_and_height" \
    316                           " not found", __FUNCTION__);
    317                 }
    318                 break;
    319             default: break;
    320         }
    321     }
    322 }
    323 
    324 void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
    325                             int tile_enabled, int& aligned_w, int& aligned_h)
    326 {
    327     aligned_w = ALIGN(width, 32);
    328     aligned_h = ALIGN(height, 32);
    329 
    330     // Don't add any additional padding if debug.gralloc.map_fb_memory
    331     // is enabled
    332     char property[PROPERTY_VALUE_MAX];
    333     if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
    334        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
    335        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
    336         return;
    337     }
    338 
    339     int bpp = 4;
    340     switch(format)
    341     {
    342         case HAL_PIXEL_FORMAT_RGBA_FP16:
    343             bpp = 8;
    344             break;
    345         case HAL_PIXEL_FORMAT_RGB_888:
    346             bpp = 3;
    347             break;
    348         case HAL_PIXEL_FORMAT_RGB_565:
    349         case HAL_PIXEL_FORMAT_BGR_565:
    350         case HAL_PIXEL_FORMAT_RGBA_5551:
    351         case HAL_PIXEL_FORMAT_RGBA_4444:
    352             bpp = 2;
    353             break;
    354         default: break;
    355     }
    356 
    357     if (libadreno_utils) {
    358         int raster_mode         = 0;   // Adreno unknown raster mode.
    359         int padding_threshold   = 512; // Threshold for padding surfaces.
    360         // the function below computes aligned width and aligned height
    361         // based on linear or macro tile mode selected.
    362         if(LINK_adreno_compute_aligned_width_and_height) {
    363             LINK_adreno_compute_aligned_width_and_height(width,
    364                                  height, bpp, tile_enabled,
    365                                  raster_mode, padding_threshold,
    366                                  &aligned_w, &aligned_h);
    367 
    368         } else if(LINK_adreno_compute_padding) {
    369             int surface_tile_height = 1;   // Linear surface
    370             aligned_w = LINK_adreno_compute_padding(width, bpp,
    371                                  surface_tile_height, raster_mode,
    372                                  padding_threshold);
    373             ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
    374                                                             __FUNCTION__);
    375         } else {
    376             ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
    377                  "compute_aligned_width_and_height not found", __FUNCTION__);
    378         }
    379    }
    380 }
    381 
    382 int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
    383 {
    384     if (!gfx_ubwc_disable && libadreno_utils) {
    385         if (LINK_adreno_isUBWCSupportedByGpu) {
    386             ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
    387             return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
    388         }
    389     }
    390     return 0;
    391 }
    392 
    393 ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
    394 {
    395     switch (hal_format) {
    396         case HAL_PIXEL_FORMAT_RGBA_8888:
    397             return ADRENO_PIXELFORMAT_R8G8B8A8;
    398         case HAL_PIXEL_FORMAT_RGBX_8888:
    399             return ADRENO_PIXELFORMAT_R8G8B8X8;
    400         case HAL_PIXEL_FORMAT_RGB_565:
    401             return ADRENO_PIXELFORMAT_B5G6R5;
    402         case HAL_PIXEL_FORMAT_BGR_565:
    403             return ADRENO_PIXELFORMAT_R5G6B5;
    404         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    405             return ADRENO_PIXELFORMAT_NV12;
    406         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    407         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    408             return ADRENO_PIXELFORMAT_NV12_EXT;
    409         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    410             return ADRENO_PIXELFORMAT_TP10;
    411         case HAL_PIXEL_FORMAT_RGBA_1010102:
    412             return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
    413         case HAL_PIXEL_FORMAT_RGBX_1010102:
    414             return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
    415         case HAL_PIXEL_FORMAT_ABGR_2101010:
    416             return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
    417         default:
    418             ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
    419             break;
    420     }
    421     return ADRENO_PIXELFORMAT_UNKNOWN;
    422 }
    423 
    424 //-------------- IAllocController-----------------------//
    425 IAllocController* IAllocController::sController = NULL;
    426 IAllocController* IAllocController::getInstance(void)
    427 {
    428     if(sController == NULL) {
    429         sController = new IonController();
    430     }
    431     return sController;
    432 }
    433 
    434 
    435 //-------------- IonController-----------------------//
    436 IonController::IonController()
    437 {
    438     allocateIonMem();
    439 
    440     char property[PROPERTY_VALUE_MAX];
    441     property_get("video.disable.ubwc", property, "0");
    442     mDisableUBWCForEncode = atoi(property);
    443 }
    444 
    445 void IonController::allocateIonMem()
    446 {
    447    mIonAlloc = new IonAlloc();
    448 }
    449 
    450 int IonController::allocate(alloc_data& data, int usage)
    451 {
    452     int ionFlags = 0;
    453     int ionHeapId = 0;
    454     int ret;
    455 
    456     data.uncached = useUncached(usage);
    457     data.allocType = 0;
    458 
    459     if(usage & GRALLOC_USAGE_PROTECTED) {
    460         if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
    461             ionHeapId = ION_HEAP(SD_HEAP_ID);
    462             /*
    463              * There is currently no flag in ION for Secure Display
    464              * VM. Please add it to the define once available.
    465              */
    466             ionFlags |= ION_SD_FLAGS;
    467         } else {
    468             ionHeapId = ION_HEAP(CP_HEAP_ID);
    469             ionFlags |= ION_CP_FLAGS;
    470         }
    471     } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
    472         //MM Heap is exclusively a secure heap.
    473         //If it is used for non secure cases, fallback to IOMMU heap
    474         ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
    475                                 cannot be used as an insecure heap!\
    476                                 trying to use system heap instead !!");
    477         ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
    478     }
    479 
    480     if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
    481         ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID);
    482 
    483     if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
    484         ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID);
    485 
    486     if(ionFlags & ION_SECURE)
    487          data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
    488 
    489     // if no ion heap flags are set, default to system heap
    490     if(!ionHeapId)
    491         ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID);
    492 
    493     //At this point we should have the right heap set, there is no fallback
    494     data.flags = ionFlags;
    495     data.heapId = ionHeapId;
    496     ret = mIonAlloc->alloc_buffer(data);
    497 
    498     if(ret >= 0 ) {
    499         data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
    500     } else {
    501         ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x",
    502                 __FUNCTION__, ionHeapId, ionFlags);
    503     }
    504 
    505     return ret;
    506 }
    507 
    508 IMemAlloc* IonController::getAllocator(int flags)
    509 {
    510     IMemAlloc* memalloc = NULL;
    511     if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
    512         memalloc = mIonAlloc;
    513     } else {
    514         ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
    515     }
    516 
    517     return memalloc;
    518 }
    519 
    520 bool isMacroTileEnabled(int format, int usage)
    521 {
    522     bool tileEnabled = false;
    523     // Check whether GPU & MDSS supports MacroTiling feature
    524     if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
    525        MDPCapabilityInfo::getInstance().isMacroTilingSupportedByMDP())
    526     {
    527         // check the format
    528         switch(format)
    529         {
    530             case  HAL_PIXEL_FORMAT_RGBA_8888:
    531             case  HAL_PIXEL_FORMAT_RGBX_8888:
    532             case  HAL_PIXEL_FORMAT_BGRA_8888:
    533             case  HAL_PIXEL_FORMAT_RGB_565:
    534             case  HAL_PIXEL_FORMAT_BGR_565:
    535                 {
    536                     tileEnabled = true;
    537                     // check the usage flags
    538                     if (usage & (GRALLOC_USAGE_SW_READ_MASK |
    539                                 GRALLOC_USAGE_SW_WRITE_MASK)) {
    540                         // Application intends to use CPU for rendering
    541                         tileEnabled = false;
    542                     }
    543                     break;
    544                 }
    545             default:
    546                 break;
    547         }
    548     }
    549     return tileEnabled;
    550 }
    551 
    552 // helper function
    553 unsigned int getSize(int format, int width, int height, int usage,
    554         const int alignedw, const int alignedh) {
    555 
    556     if (isUBwcEnabled(format, usage)) {
    557         return getUBwcSize(width, height, format, alignedw, alignedh);
    558     }
    559 
    560     unsigned int size = 0;
    561     switch (format) {
    562         case HAL_PIXEL_FORMAT_RGBA_FP16:
    563             size = alignedw * alignedh * 8;
    564             break;
    565         case HAL_PIXEL_FORMAT_RGBA_8888:
    566         case HAL_PIXEL_FORMAT_RGBX_8888:
    567         case HAL_PIXEL_FORMAT_BGRA_8888:
    568         case HAL_PIXEL_FORMAT_RGBA_1010102:
    569         case HAL_PIXEL_FORMAT_ARGB_2101010:
    570         case HAL_PIXEL_FORMAT_RGBX_1010102:
    571         case HAL_PIXEL_FORMAT_XRGB_2101010:
    572         case HAL_PIXEL_FORMAT_BGRA_1010102:
    573         case HAL_PIXEL_FORMAT_ABGR_2101010:
    574         case HAL_PIXEL_FORMAT_BGRX_1010102:
    575         case HAL_PIXEL_FORMAT_XBGR_2101010:
    576             size = alignedw * alignedh * 4;
    577             break;
    578         case HAL_PIXEL_FORMAT_RGB_888:
    579             size = alignedw * alignedh * 3;
    580             break;
    581         case HAL_PIXEL_FORMAT_RGB_565:
    582         case HAL_PIXEL_FORMAT_BGR_565:
    583         case HAL_PIXEL_FORMAT_RGBA_5551:
    584         case HAL_PIXEL_FORMAT_RGBA_4444:
    585         case HAL_PIXEL_FORMAT_RAW16:
    586             size = alignedw * alignedh * 2;
    587             break;
    588         case HAL_PIXEL_FORMAT_RAW10:
    589             size = ALIGN(alignedw * alignedh, 4096);
    590             break;
    591 
    592             // adreno formats
    593         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
    594             size  = ALIGN(alignedw*alignedh, 4096);
    595             size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
    596             break;
    597         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
    598             // The chroma plane is subsampled,
    599             // but the pitch in bytes is unchanged
    600             // The GPU needs 4K alignment, but the video decoder needs 8K
    601             size  = ALIGN( alignedw * alignedh, 8192);
    602             size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
    603             break;
    604         case HAL_PIXEL_FORMAT_YV12:
    605             if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
    606                 ALOGE("w or h is odd for the YV12 format");
    607                 return 0;
    608             }
    609             size = alignedw*alignedh +
    610                     (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
    611             size = ALIGN(size, (unsigned int)4096);
    612             break;
    613         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    614         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    615             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
    616             break;
    617         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    618         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    619         case HAL_PIXEL_FORMAT_YCbCr_422_I:
    620         case HAL_PIXEL_FORMAT_YCrCb_422_I:
    621             if(width & 1) {
    622                 ALOGE("width is odd for the YUV422_SP format");
    623                 return 0;
    624             }
    625             size = ALIGN(alignedw * alignedh * 2, 4096);
    626             break;
    627         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    628         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    629             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
    630             break;
    631         case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    632             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
    633             break;
    634         case HAL_PIXEL_FORMAT_BLOB:
    635         case HAL_PIXEL_FORMAT_RAW_OPAQUE:
    636             if(height != 1) {
    637                 ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
    638                       must have height==1 ", __FUNCTION__);
    639                 return 0;
    640             }
    641             size = width;
    642             break;
    643         case HAL_PIXEL_FORMAT_NV21_ZSL:
    644             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
    645             break;
    646         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
    647         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
    648         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
    649         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
    650         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
    651         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
    652         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
    653         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
    654         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
    655         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
    656         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
    657         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
    658         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
    659         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
    660         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
    661         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
    662         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
    663         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
    664         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
    665         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
    666         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
    667         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
    668         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
    669         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
    670         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
    671         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
    672         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
    673         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
    674             size = alignedw * alignedh * ASTC_BLOCK_SIZE;
    675             break;
    676         default:
    677             ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
    678             return 0;
    679     }
    680     return size;
    681 }
    682 
    683 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
    684         int& alignedw, int &alignedh)
    685 {
    686     unsigned int size;
    687 
    688     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    689             height,
    690             format,
    691             0,
    692             alignedw,
    693             alignedh);
    694 
    695     size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
    696 
    697     return size;
    698 }
    699 
    700 
    701 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
    702         int usage, int& alignedw, int &alignedh)
    703 {
    704     unsigned int size;
    705 
    706     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    707             height,
    708             format,
    709             usage,
    710             alignedw,
    711             alignedh);
    712 
    713     size = getSize(format, width, height, usage, alignedw, alignedh);
    714 
    715     return size;
    716 }
    717 
    718 
    719 void getBufferAttributes(int width, int height, int format, int usage,
    720         int& alignedw, int &alignedh, int& tiled, unsigned int& size)
    721 {
    722     tiled = isUBwcEnabled(format, usage) || isMacroTileEnabled(format, usage);
    723 
    724     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    725             height,
    726             format,
    727             usage,
    728             alignedw,
    729             alignedh);
    730     size = getSize(format, width, height, usage, alignedw, alignedh);
    731 }
    732 
    733 void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int height,
    734                            int color_format, struct android_ycbcr* ycbcr)
    735 {
    736     // UBWC buffer has these 4 planes in the following sequence:
    737     // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
    738     unsigned int y_meta_stride, y_meta_height, y_meta_size;
    739     unsigned int y_stride, y_height, y_size;
    740     unsigned int c_meta_stride, c_meta_height, c_meta_size;
    741     unsigned int alignment = 4096;
    742 
    743     y_meta_stride = VENUS_Y_META_STRIDE(color_format, width);
    744     y_meta_height = VENUS_Y_META_SCANLINES(color_format, height);
    745     y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);
    746 
    747     y_stride = VENUS_Y_STRIDE(color_format, width);
    748     y_height = VENUS_Y_SCANLINES(color_format, height);
    749     y_size = ALIGN((y_stride * y_height), alignment);
    750 
    751     c_meta_stride = VENUS_UV_META_STRIDE(color_format, width);
    752     c_meta_height = VENUS_UV_META_SCANLINES(color_format, height);
    753     c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);
    754 
    755     ycbcr->y  = (void*)(base + y_meta_size);
    756     ycbcr->cb = (void*)(base + y_meta_size + y_size + c_meta_size);
    757     ycbcr->cr = (void*)(base + y_meta_size + y_size +
    758                         c_meta_size + 1);
    759     ycbcr->ystride = y_stride;
    760     ycbcr->cstride = VENUS_UV_STRIDE(color_format, width);
    761 }
    762 
    763 void getYuvSPPlaneInfo(uint64_t base, int width, int height, int bpp,
    764                        struct android_ycbcr* ycbcr)
    765 {
    766     unsigned int ystride, cstride;
    767 
    768     ystride = cstride = width * bpp;
    769     ycbcr->y  = (void*)base;
    770     ycbcr->cb = (void*)(base + ystride * height);
    771     ycbcr->cr = (void*)(base + ystride * height + 1);
    772     ycbcr->ystride = ystride;
    773     ycbcr->cstride = cstride;
    774     ycbcr->chroma_step = 2 * bpp;
    775 }
    776 
    777 int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
    778 {
    779     int err = 0;
    780     int width = hnd->width;
    781     int height = hnd->height;
    782     int format = hnd->format;
    783 
    784     unsigned int ystride, cstride;
    785 
    786     memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
    787     MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
    788 
    789     // Check if UBWC buffer has been rendered in linear format.
    790     if (metadata && (metadata->operation & LINEAR_FORMAT)) {
    791         format = metadata->linearFormat;
    792     }
    793 
    794     // Check metadata if the geometry has been updated.
    795     if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
    796         int usage = 0;
    797 
    798         if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
    799             usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
    800         }
    801 
    802         AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
    803                    metadata->bufferDim.sliceHeight, format, usage, width, height);
    804     }
    805 
    806     // Get the chroma offsets from the handle width/height. We take advantage
    807     // of the fact the width _is_ the stride
    808     switch (format) {
    809         //Semiplanar
    810         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    811         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    812         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    813         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
    814             getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
    815         break;
    816 
    817         case HAL_PIXEL_FORMAT_YCbCr_420_P010:
    818             getYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
    819         break;
    820 
    821         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    822             getYuvUbwcSPPlaneInfo(hnd->base, width, height,
    823                                   COLOR_FMT_NV12_UBWC, ycbcr);
    824             ycbcr->chroma_step = 2;
    825         break;
    826 
    827         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    828             getYuvUbwcSPPlaneInfo(hnd->base, width, height,
    829                                   COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
    830             ycbcr->chroma_step = 3;
    831         break;
    832 
    833         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    834         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    835         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    836         case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
    837         case HAL_PIXEL_FORMAT_NV21_ZSL:
    838         case HAL_PIXEL_FORMAT_RAW16:
    839         case HAL_PIXEL_FORMAT_RAW10:
    840             getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
    841             std::swap(ycbcr->cb, ycbcr->cr);
    842         break;
    843 
    844         //Planar
    845         case HAL_PIXEL_FORMAT_YV12:
    846             ystride = width;
    847             cstride = ALIGN(width/2, 16);
    848             ycbcr->y  = (void*)hnd->base;
    849             ycbcr->cr = (void*)(hnd->base + ystride * height);
    850             ycbcr->cb = (void*)(hnd->base + ystride * height +
    851                     cstride * height/2);
    852             ycbcr->ystride = ystride;
    853             ycbcr->cstride = cstride;
    854             ycbcr->chroma_step = 1;
    855         break;
    856         //Unsupported formats
    857         case HAL_PIXEL_FORMAT_YCbCr_422_I:
    858         case HAL_PIXEL_FORMAT_YCrCb_422_I:
    859         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    860         default:
    861         ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
    862         err = -EINVAL;
    863     }
    864     return err;
    865 
    866 }
    867 
    868 
    869 
    870 // Allocate buffer from width, height and format into a
    871 // private_handle_t. It is the responsibility of the caller
    872 // to free the buffer using the free_buffer function
    873 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
    874 {
    875     alloc_data data;
    876     int alignedw, alignedh;
    877     gralloc::IAllocController* sAlloc =
    878         gralloc::IAllocController::getInstance();
    879     data.base = 0;
    880     data.fd = -1;
    881     data.offset = 0;
    882     data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
    883                                             alignedh);
    884 
    885     data.align = getpagesize();
    886     data.uncached = useUncached(usage);
    887     int allocFlags = usage;
    888 
    889     int err = sAlloc->allocate(data, allocFlags);
    890     if (0 != err) {
    891         ALOGE("%s: allocate failed", __FUNCTION__);
    892         return -ENOMEM;
    893     }
    894 
    895     if(isUBwcEnabled(format, usage)) {
    896       data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
    897     }
    898 
    899     private_handle_t* hnd = new private_handle_t(data.fd, data.size,
    900                                                  data.allocType, 0, format,
    901                                                  alignedw, alignedh);
    902     hnd->base = (uint64_t) data.base;
    903     hnd->offset = data.offset;
    904     hnd->gpuaddr = 0;
    905     *pHnd = hnd;
    906     return 0;
    907 }
    908 
    909 void free_buffer(private_handle_t *hnd)
    910 {
    911     gralloc::IAllocController* sAlloc =
    912         gralloc::IAllocController::getInstance();
    913     if (hnd && hnd->fd > 0) {
    914         IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
    915         memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
    916     }
    917     if(hnd)
    918         delete hnd;
    919 
    920 }
    921 
    922 // UBWC helper functions
    923 static bool isUBwcFormat(int format)
    924 {
    925     // Explicitly defined UBWC formats
    926     switch(format)
    927     {
    928         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    929         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
    930             return true;
    931         default:
    932             return false;
    933     }
    934 }
    935 
    936 static bool isUBwcSupported(int format)
    937 {
    938     if (MDPCapabilityInfo::getInstance().isUBwcSupportedByMDP()) {
    939         // Existing HAL formats with UBWC support
    940         switch(format)
    941         {
    942             case HAL_PIXEL_FORMAT_BGR_565:
    943             case HAL_PIXEL_FORMAT_RGBA_8888:
    944             case HAL_PIXEL_FORMAT_RGBX_8888:
    945             case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    946             case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    947             case HAL_PIXEL_FORMAT_RGBA_1010102:
    948             case HAL_PIXEL_FORMAT_RGBX_1010102:
    949                 return true;
    950             default:
    951                 break;
    952         }
    953     }
    954     return false;
    955 }
    956 
    957 bool isUBwcEnabled(int format, int usage)
    958 {
    959     // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
    960     if (isUBwcFormat(format))
    961         return true;
    962 
    963     if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
    964         gralloc::IAllocController::getInstance()->isDisableUBWCForEncoder()) {
    965             return false;
    966     }
    967 
    968     // Workaround for bug 30191188/ CR 1047578
    969     if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) && (usage & GRALLOC_USAGE_HW_COMPOSER)) {
    970         return false;
    971     }
    972 
    973     // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
    974     // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
    975     // usage flag and MDP supports the format.
    976     if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) {
    977         bool enable = true;
    978         // Query GPU for UBWC only if buffer is intended to be used by GPU.
    979         if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) {
    980             enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format);
    981         }
    982         // Allow UBWC, only if CPU usage flags are not set
    983         if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK |
    984             GRALLOC_USAGE_SW_WRITE_MASK))) {
    985             return true;
    986         }
    987     }
    988     return false;
    989 }
    990 
    991 static void getYuvUBwcWidthHeight(int width, int height, int format,
    992         int& aligned_w, int& aligned_h)
    993 {
    994     switch (format)
    995     {
    996         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    997         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    998         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    999             aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
   1000             aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
   1001             break;
   1002         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
   1003             aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width);
   1004             aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
   1005             break;
   1006         default:
   1007             ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
   1008             aligned_w = 0;
   1009             aligned_h = 0;
   1010             break;
   1011     }
   1012 }
   1013 
   1014 static void getRgbUBwcBlockSize(int bpp, int& block_width, int& block_height)
   1015 {
   1016     block_width = 0;
   1017     block_height = 0;
   1018 
   1019     switch(bpp)
   1020     {
   1021          case 2:
   1022          case 4:
   1023              block_width = 16;
   1024              block_height = 4;
   1025              break;
   1026          case 8:
   1027              block_width = 8;
   1028              block_height = 4;
   1029              break;
   1030          case 16:
   1031              block_width = 4;
   1032              block_height = 4;
   1033              break;
   1034          default:
   1035              ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
   1036              break;
   1037     }
   1038 }
   1039 
   1040 static unsigned int getRgbUBwcMetaBufferSize(int width, int height, int bpp)
   1041 {
   1042     unsigned int size = 0;
   1043     int meta_width, meta_height;
   1044     int block_width, block_height;
   1045 
   1046     getRgbUBwcBlockSize(bpp, block_width, block_height);
   1047 
   1048     if (!block_width || !block_height) {
   1049         ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
   1050         return size;
   1051     }
   1052 
   1053     // Align meta buffer height to 16 blocks
   1054     meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
   1055 
   1056     // Align meta buffer width to 64 blocks
   1057     meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
   1058 
   1059     // Align meta buffer size to 4K
   1060     size = ALIGN((meta_width * meta_height), 4096);
   1061     return size;
   1062 }
   1063 
   1064 static unsigned int getUBwcSize(int width, int height, int format,
   1065         const int alignedw, const int alignedh) {
   1066 
   1067     unsigned int size = 0;
   1068     switch (format) {
   1069         case HAL_PIXEL_FORMAT_BGR_565:
   1070             size = alignedw * alignedh * 2;
   1071             size += getRgbUBwcMetaBufferSize(width, height, 2);
   1072             break;
   1073         case HAL_PIXEL_FORMAT_RGBA_8888:
   1074         case HAL_PIXEL_FORMAT_RGBX_8888:
   1075         case HAL_PIXEL_FORMAT_RGBA_1010102:
   1076         case HAL_PIXEL_FORMAT_RGBX_1010102:
   1077             size = alignedw * alignedh * 4;
   1078             size += getRgbUBwcMetaBufferSize(width, height, 4);
   1079             break;
   1080         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
   1081         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
   1082         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
   1083             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
   1084             break;
   1085         case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
   1086             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
   1087             break;
   1088         default:
   1089             ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
   1090             break;
   1091     }
   1092     return size;
   1093 }
   1094 
   1095 int getRgbDataAddress(private_handle_t* hnd, void** rgb_data)
   1096 {
   1097     int err = 0;
   1098 
   1099     // This api is for RGB* formats
   1100     if (!isUncompressedRgbFormat(hnd->format)) {
   1101         return -EINVAL;
   1102     }
   1103 
   1104     // linear buffer
   1105     if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
   1106         *rgb_data = (void*)hnd->base;
   1107         return err;
   1108     }
   1109 
   1110     unsigned int meta_size = 0;
   1111     switch (hnd->format) {
   1112         case HAL_PIXEL_FORMAT_BGR_565:
   1113             meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 2);
   1114             break;
   1115         case HAL_PIXEL_FORMAT_RGBA_8888:
   1116         case HAL_PIXEL_FORMAT_RGBX_8888:
   1117             meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 4);
   1118             break;
   1119         default:
   1120             ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
   1121             err = -EINVAL;
   1122             break;
   1123     }
   1124 
   1125     *rgb_data = (void*)(hnd->base + meta_size);
   1126     return err;
   1127 }
   1128