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