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