Home | History | Annotate | Download | only in libgralloc
      1 /*
      2  * Copyright (c) 2011-2014, 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 "comptype.h"
     39 #include "mdp_version.h"
     40 
     41 #ifdef VENUS_COLOR_FORMAT
     42 #include <media/msm_media_info.h>
     43 #else
     44 #define VENUS_Y_STRIDE(args...) 0
     45 #define VENUS_Y_SCANLINES(args...) 0
     46 #define VENUS_BUFFER_SIZE(args...) 0
     47 #endif
     48 
     49 #define ASTC_BLOCK_SIZE 16
     50 
     51 using namespace gralloc;
     52 using namespace qdutils;
     53 
     54 ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
     55 
     56 static void getUBwcWidthAndHeight(int, int, int, int&, int&);
     57 static unsigned int getUBwcSize(int, int, int, const int, const int);
     58 
     59 //Common functions
     60 static bool canFallback(int usage, bool triedSystem)
     61 {
     62     // Fallback to system heap when alloc fails unless
     63     // 1. Composition type is MDP
     64     // 2. Alloc from system heap was already tried
     65     // 3. The heap type is requsted explicitly
     66     // 4. The heap type is protected
     67     // 5. The buffer is meant for external display only
     68 
     69     if(QCCompositionType::getInstance().getCompositionType() &
     70        COMPOSITION_TYPE_MDP)
     71         return false;
     72     if(triedSystem)
     73         return false;
     74     if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
     75         return false;
     76     if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
     77         return false;
     78     //Return true by default
     79     return true;
     80 }
     81 
     82 /* The default policy is to return cached buffers unless the client explicity
     83  * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
     84  * read or written in software. Any combination with a _RARELY_ flag will be
     85  * treated as uncached. */
     86 static bool useUncached(const int& usage) {
     87     if((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
     88             ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ==
     89             GRALLOC_USAGE_SW_WRITE_RARELY) or
     90             ((usage & GRALLOC_USAGE_SW_READ_MASK) ==
     91             GRALLOC_USAGE_SW_READ_RARELY))
     92         return true;
     93 
     94     return false;
     95 }
     96 
     97 //-------------- AdrenoMemInfo-----------------------//
     98 AdrenoMemInfo::AdrenoMemInfo()
     99 {
    100     LINK_adreno_compute_aligned_width_and_height = NULL;
    101     LINK_adreno_compute_padding = NULL;
    102     LINK_adreno_isMacroTilingSupportedByGpu = NULL;
    103     LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
    104     LINK_adreno_isUBWCSupportedByGpu = NULL;
    105 
    106     libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
    107     if (libadreno_utils) {
    108         *(void **)&LINK_adreno_compute_aligned_width_and_height =
    109                 ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
    110         *(void **)&LINK_adreno_compute_padding =
    111                 ::dlsym(libadreno_utils, "compute_surface_padding");
    112         *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
    113                 ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
    114         *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
    115                 ::dlsym(libadreno_utils,
    116                         "compute_compressedfmt_aligned_width_and_height");
    117         *(void **)&LINK_adreno_isUBWCSupportedByGpu =
    118                 ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
    119     }
    120 }
    121 
    122 AdrenoMemInfo::~AdrenoMemInfo()
    123 {
    124     if (libadreno_utils) {
    125         ::dlclose(libadreno_utils);
    126     }
    127 }
    128 
    129 int AdrenoMemInfo::isMacroTilingSupportedByGPU()
    130 {
    131     if ((libadreno_utils)) {
    132         if(LINK_adreno_isMacroTilingSupportedByGpu) {
    133             return LINK_adreno_isMacroTilingSupportedByGpu();
    134         }
    135     }
    136     return 0;
    137 }
    138 
    139 
    140 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
    141                             int usage, int& aligned_w, int& aligned_h)
    142 {
    143 
    144     // Currently surface padding is only computed for RGB* surfaces.
    145     if (format <= HAL_PIXEL_FORMAT_BGRA_8888) {
    146         int tileEnabled = isMacroTileEnabled(format, usage);
    147         AdrenoMemInfo::getInstance().getGpuAlignedWidthHeight(width,
    148             height, format, tileEnabled, aligned_w, aligned_h);
    149         return;
    150     }
    151 
    152     if (isUBwcEnabled(format, usage)) {
    153         getUBwcWidthAndHeight(width, height, format, aligned_w, aligned_h);
    154         return;
    155     }
    156 
    157     aligned_w = width;
    158     aligned_h = height;
    159     switch (format)
    160     {
    161         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    162         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    163             aligned_w = ALIGN(width, 32);
    164             break;
    165         case HAL_PIXEL_FORMAT_RAW16:
    166             aligned_w = ALIGN(width, 16);
    167             break;
    168         case HAL_PIXEL_FORMAT_RAW10:
    169             aligned_w = ALIGN(width * 10 /8, 8);
    170             break;
    171         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    172             aligned_w = ALIGN(width, 128);
    173             break;
    174         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    175         case HAL_PIXEL_FORMAT_YV12:
    176         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    177         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    178         case HAL_PIXEL_FORMAT_YCbCr_422_I:
    179         case HAL_PIXEL_FORMAT_YCrCb_422_I:
    180             aligned_w = ALIGN(width, 16);
    181             break;
    182         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    183         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    184             aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
    185             aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
    186             break;
    187         case HAL_PIXEL_FORMAT_BLOB:
    188             break;
    189         case HAL_PIXEL_FORMAT_NV21_ZSL:
    190             aligned_w = ALIGN(width, 64);
    191             aligned_h = ALIGN(height, 64);
    192             break;
    193         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
    194         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
    195         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
    196         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
    197         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
    198         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
    199         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
    200         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
    201         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
    202         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
    203         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
    204         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
    205         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
    206         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
    207         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
    208         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
    209         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
    210         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
    211         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
    212         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
    213         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
    214         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
    215         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
    216         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
    217         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
    218         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
    219         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
    220         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
    221             if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
    222                 int bytesPerPixel = 0;
    223                 int raster_mode         = 0;   //Adreno unknown raster mode.
    224                 int padding_threshold   = 512; //Threshold for padding
    225                 //surfaces.
    226 
    227                 LINK_adreno_compute_compressedfmt_aligned_width_and_height(
    228                     width, height, format, 0,raster_mode, padding_threshold,
    229                     &aligned_w, &aligned_h, &bytesPerPixel);
    230             } else {
    231                 ALOGW("%s: Warning!! Symbols" \
    232                       " compute_compressedfmt_aligned_width_and_height" \
    233                       " not found", __FUNCTION__);
    234             }
    235             break;
    236         default: break;
    237     }
    238 }
    239 
    240 void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
    241                             int tile_enabled, int& aligned_w, int& aligned_h)
    242 {
    243     aligned_w = ALIGN(width, 32);
    244     aligned_h = ALIGN(height, 32);
    245 
    246     // Don't add any additional padding if debug.gralloc.map_fb_memory
    247     // is enabled
    248     char property[PROPERTY_VALUE_MAX];
    249     if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
    250        (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
    251        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
    252         return;
    253     }
    254 
    255     int bpp = 4;
    256     switch(format)
    257     {
    258         case HAL_PIXEL_FORMAT_RGB_888:
    259             bpp = 3;
    260             break;
    261         case HAL_PIXEL_FORMAT_RGB_565:
    262         case HAL_PIXEL_FORMAT_RGBA_5551:
    263         case HAL_PIXEL_FORMAT_RGBA_4444:
    264             bpp = 2;
    265             break;
    266         default: break;
    267     }
    268 
    269     if (libadreno_utils) {
    270         int raster_mode         = 0;   // Adreno unknown raster mode.
    271         int padding_threshold   = 512; // Threshold for padding surfaces.
    272         // the function below computes aligned width and aligned height
    273         // based on linear or macro tile mode selected.
    274         if(LINK_adreno_compute_aligned_width_and_height) {
    275             LINK_adreno_compute_aligned_width_and_height(width,
    276                                  height, bpp, tile_enabled,
    277                                  raster_mode, padding_threshold,
    278                                  &aligned_w, &aligned_h);
    279 
    280         } else if(LINK_adreno_compute_padding) {
    281             int surface_tile_height = 1;   // Linear surface
    282             aligned_w = LINK_adreno_compute_padding(width, bpp,
    283                                  surface_tile_height, raster_mode,
    284                                  padding_threshold);
    285             ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
    286                                                             __FUNCTION__);
    287         } else {
    288             ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
    289                  "compute_aligned_width_and_height not found", __FUNCTION__);
    290         }
    291    }
    292 }
    293 
    294 int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
    295 {
    296     if (libadreno_utils) {
    297         if (LINK_adreno_isUBWCSupportedByGpu) {
    298             ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
    299             return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
    300         }
    301     }
    302     return 0;
    303 }
    304 
    305 ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
    306 {
    307     switch (hal_format) {
    308         case HAL_PIXEL_FORMAT_RGBA_8888:
    309             return ADRENO_PIXELFORMAT_R8G8B8A8;
    310         case HAL_PIXEL_FORMAT_RGB_565:
    311             return ADRENO_PIXELFORMAT_B5G6R5;
    312         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    313         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    314         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    315             return ADRENO_PIXELFORMAT_NV12;
    316         default:
    317             ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
    318             break;
    319     }
    320     return ADRENO_PIXELFORMAT_UNKNOWN;
    321 }
    322 
    323 //-------------- IAllocController-----------------------//
    324 IAllocController* IAllocController::sController = NULL;
    325 IAllocController* IAllocController::getInstance(void)
    326 {
    327     if(sController == NULL) {
    328         sController = new IonController();
    329     }
    330     return sController;
    331 }
    332 
    333 
    334 //-------------- IonController-----------------------//
    335 IonController::IonController()
    336 {
    337     allocateIonMem();
    338 }
    339 
    340 void IonController::allocateIonMem()
    341 {
    342    mIonAlloc = new IonAlloc();
    343 }
    344 
    345 int IonController::allocate(alloc_data& data, int usage)
    346 {
    347     int ionFlags = 0;
    348     int ret;
    349 
    350     data.uncached = useUncached(usage);
    351     data.allocType = 0;
    352 
    353     if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
    354         ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
    355 
    356     if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
    357         ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
    358 
    359     if(usage & GRALLOC_USAGE_PROTECTED) {
    360         if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
    361             ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
    362             ionFlags |= ION_SECURE;
    363 #ifdef ION_FLAG_ALLOW_NON_CONTIG
    364             if (!(usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY)) {
    365                 ionFlags |= ION_FLAG_ALLOW_NON_CONTIG;
    366             }
    367 #endif
    368         } else {
    369             // for targets/OEMs which do not need HW level protection
    370             // do not set ion secure flag & MM heap. Fallback to IOMMU heap.
    371             ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
    372             data.allocType |= private_handle_t::PRIV_FLAGS_PROTECTED_BUFFER;
    373         }
    374     } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
    375         //MM Heap is exclusively a secure heap.
    376         //If it is used for non secure cases, fallback to IOMMU heap
    377         ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
    378                                 cannot be used as an insecure heap!\
    379                                 trying to use IOMMU instead !!");
    380         ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
    381     }
    382 
    383     if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
    384         ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
    385 
    386     if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
    387         ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
    388 
    389     if(ionFlags & ION_SECURE)
    390          data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
    391 
    392     // if no flags are set, default to
    393     // SF + IOMMU heaps, so that bypass can work
    394     // we can fall back to system heap if
    395     // we run out.
    396     if(!ionFlags)
    397         ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
    398 
    399     data.flags = ionFlags;
    400     ret = mIonAlloc->alloc_buffer(data);
    401 
    402     // Fallback
    403     if(ret < 0 && canFallback(usage,
    404                               (ionFlags & ION_SYSTEM_HEAP_ID)))
    405     {
    406         ALOGW("Falling back to system heap");
    407         data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
    408         ret = mIonAlloc->alloc_buffer(data);
    409     }
    410 
    411     if(ret >= 0 ) {
    412         data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
    413     }
    414 
    415     return ret;
    416 }
    417 
    418 IMemAlloc* IonController::getAllocator(int flags)
    419 {
    420     IMemAlloc* memalloc = NULL;
    421     if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
    422         memalloc = mIonAlloc;
    423     } else {
    424         ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
    425     }
    426 
    427     return memalloc;
    428 }
    429 
    430 bool isMacroTileEnabled(int format, int usage)
    431 {
    432     bool tileEnabled = false;
    433 
    434     // Check whether GPU & MDSS supports MacroTiling feature
    435     if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
    436             qdutils::MDPVersion::getInstance().supportsMacroTile())
    437     {
    438         // check the format
    439         switch(format)
    440         {
    441             case  HAL_PIXEL_FORMAT_RGBA_8888:
    442             case  HAL_PIXEL_FORMAT_RGBX_8888:
    443             case  HAL_PIXEL_FORMAT_BGRA_8888:
    444             case  HAL_PIXEL_FORMAT_RGB_565:
    445                 {
    446                     tileEnabled = true;
    447                     // check the usage flags
    448                     if (usage & (GRALLOC_USAGE_SW_READ_MASK |
    449                                 GRALLOC_USAGE_SW_WRITE_MASK)) {
    450                         // Application intends to use CPU for rendering
    451                         tileEnabled = false;
    452                     }
    453                     break;
    454                 }
    455             default:
    456                 break;
    457         }
    458     }
    459     return tileEnabled;
    460 }
    461 
    462 // helper function
    463 unsigned int getSize(int format, int width, int height, int usage,
    464         const int alignedw, const int alignedh) {
    465 
    466     if (isUBwcEnabled(format, usage)) {
    467         return getUBwcSize(width, height, format, alignedw, alignedh);
    468     }
    469 
    470     unsigned int size = 0;
    471     switch (format) {
    472         case HAL_PIXEL_FORMAT_RGBA_8888:
    473         case HAL_PIXEL_FORMAT_RGBX_8888:
    474         case HAL_PIXEL_FORMAT_BGRA_8888:
    475             size = alignedw * alignedh * 4;
    476             break;
    477         case HAL_PIXEL_FORMAT_RGB_888:
    478             size = alignedw * alignedh * 3;
    479             break;
    480         case HAL_PIXEL_FORMAT_RGB_565:
    481         case HAL_PIXEL_FORMAT_RGBA_5551:
    482         case HAL_PIXEL_FORMAT_RGBA_4444:
    483         case HAL_PIXEL_FORMAT_RAW16:
    484             size = alignedw * alignedh * 2;
    485             break;
    486         case HAL_PIXEL_FORMAT_RAW10:
    487             size = ALIGN(alignedw * alignedh, 4096);
    488             break;
    489             // adreno formats
    490         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
    491             size  = ALIGN(alignedw*alignedh, 4096);
    492             size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
    493             break;
    494         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
    495             // The chroma plane is subsampled,
    496             // but the pitch in bytes is unchanged
    497             // The GPU needs 4K alignment, but the video decoder needs 8K
    498             size  = ALIGN( alignedw * alignedh, 8192);
    499             size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
    500             break;
    501         case HAL_PIXEL_FORMAT_YV12:
    502             if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
    503                 ALOGE("w or h is odd for the YV12 format");
    504                 return 0;
    505             }
    506             size = alignedw*alignedh +
    507                     (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
    508             size = ALIGN(size, (unsigned int)4096);
    509             break;
    510         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    511         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    512             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
    513             break;
    514         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    515         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    516         case HAL_PIXEL_FORMAT_YCbCr_422_I:
    517         case HAL_PIXEL_FORMAT_YCrCb_422_I:
    518             if(width & 1) {
    519                 ALOGE("width is odd for the YUV422_SP format");
    520                 return 0;
    521             }
    522             size = ALIGN(alignedw * alignedh * 2, 4096);
    523             break;
    524         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    525         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    526             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
    527             break;
    528         case HAL_PIXEL_FORMAT_BLOB:
    529             if(height != 1) {
    530                 ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
    531                       must have height==1 ", __FUNCTION__);
    532                 return 0;
    533             }
    534             size = width;
    535             break;
    536         case HAL_PIXEL_FORMAT_NV21_ZSL:
    537             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
    538             break;
    539         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
    540         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
    541         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
    542         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
    543         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
    544         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
    545         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
    546         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
    547         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
    548         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
    549         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
    550         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
    551         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
    552         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
    553         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
    554         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
    555         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
    556         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
    557         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
    558         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
    559         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
    560         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
    561         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
    562         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
    563         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
    564         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
    565         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
    566         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
    567             size = alignedw * alignedh * ASTC_BLOCK_SIZE;
    568             break;
    569         default:
    570             ALOGE("Unrecognized pixel format: 0x%x", __FUNCTION__, format);
    571             return 0;
    572     }
    573     return size;
    574 }
    575 
    576 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
    577         int& alignedw, int &alignedh)
    578 {
    579     unsigned int size;
    580 
    581     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    582             height,
    583             format,
    584             0,
    585             alignedw,
    586             alignedh);
    587 
    588     size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);
    589 
    590     return size;
    591 }
    592 
    593 
    594 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
    595         int usage, int& alignedw, int &alignedh)
    596 {
    597     unsigned int size;
    598 
    599     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    600             height,
    601             format,
    602             usage,
    603             alignedw,
    604             alignedh);
    605 
    606     size = getSize(format, width, height, usage, alignedw, alignedh);
    607 
    608     return size;
    609 }
    610 
    611 
    612 void getBufferAttributes(int width, int height, int format, int usage,
    613         int& alignedw, int &alignedh, int& tileEnabled, unsigned int& size)
    614 {
    615     tileEnabled = isMacroTileEnabled(format, usage);
    616 
    617     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    618             height,
    619             format,
    620             usage,
    621             alignedw,
    622             alignedh);
    623     size = getSize(format, width, height, usage, alignedw, alignedh);
    624 }
    625 
    626 int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
    627 {
    628     int err = 0;
    629     unsigned int ystride, cstride;
    630     memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
    631 
    632     // Get the chroma offsets from the handle width/height. We take advantage
    633     // of the fact the width _is_ the stride
    634     switch (hnd->format) {
    635         //Semiplanar
    636         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    637         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    638         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    639         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
    640             ystride = cstride = hnd->width;
    641             ycbcr->y  = (void*)hnd->base;
    642             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height);
    643             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1);
    644             ycbcr->ystride = ystride;
    645             ycbcr->cstride = cstride;
    646             ycbcr->chroma_step = 2;
    647         break;
    648 
    649         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    650         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    651         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    652         case HAL_PIXEL_FORMAT_NV21_ZSL:
    653         case HAL_PIXEL_FORMAT_RAW10:
    654         case HAL_PIXEL_FORMAT_RAW16:
    655             ystride = cstride = hnd->width;
    656             ycbcr->y  = (void*)hnd->base;
    657             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
    658             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
    659             ycbcr->ystride = ystride;
    660             ycbcr->cstride = cstride;
    661             ycbcr->chroma_step = 2;
    662         break;
    663 
    664         //Planar
    665         case HAL_PIXEL_FORMAT_YV12:
    666             ystride = hnd->width;
    667             cstride = ALIGN(hnd->width/2, 16);
    668             ycbcr->y  = (void*)hnd->base;
    669             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
    670             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height +
    671                     cstride * hnd->height/2);
    672             ycbcr->ystride = ystride;
    673             ycbcr->cstride = cstride;
    674             ycbcr->chroma_step = 1;
    675 
    676         break;
    677         //Unsupported formats
    678         case HAL_PIXEL_FORMAT_YCbCr_422_I:
    679         case HAL_PIXEL_FORMAT_YCrCb_422_I:
    680         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    681         default:
    682         ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
    683                 hnd->format);
    684         err = -EINVAL;
    685     }
    686     return err;
    687 
    688 }
    689 
    690 
    691 
    692 // Allocate buffer from width, height and format into a
    693 // private_handle_t. It is the responsibility of the caller
    694 // to free the buffer using the free_buffer function
    695 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
    696 {
    697     alloc_data data;
    698     int alignedw, alignedh;
    699     gralloc::IAllocController* sAlloc =
    700         gralloc::IAllocController::getInstance();
    701     data.base = 0;
    702     data.fd = -1;
    703     data.offset = 0;
    704     data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
    705                                             alignedh);
    706 
    707     data.align = getpagesize();
    708     data.uncached = useUncached(usage);
    709     int allocFlags = usage;
    710 
    711     int err = sAlloc->allocate(data, allocFlags);
    712     if (0 != err) {
    713         ALOGE("%s: allocate failed", __FUNCTION__);
    714         return -ENOMEM;
    715     }
    716 
    717     private_handle_t* hnd = new private_handle_t(data.fd, data.size,
    718                                                  data.allocType, 0, format,
    719                                                  alignedw, alignedh);
    720     hnd->base = (uint64_t) data.base;
    721     hnd->offset = data.offset;
    722     hnd->gpuaddr = 0;
    723     *pHnd = hnd;
    724     return 0;
    725 }
    726 
    727 void free_buffer(private_handle_t *hnd)
    728 {
    729     gralloc::IAllocController* sAlloc =
    730         gralloc::IAllocController::getInstance();
    731     if (hnd && hnd->fd > 0) {
    732         IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
    733         memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
    734     }
    735     if(hnd)
    736         delete hnd;
    737 
    738 }
    739 
    740 // UBWC helper functions
    741 static bool isUBwcFormat(int format)
    742 {
    743     // Explicitly defined UBWC formats
    744     switch(format)
    745     {
    746         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    747             return true;
    748         default:
    749             return false;
    750     }
    751 }
    752 
    753 static bool isUBwcSupported(int format)
    754 {
    755     // Existing HAL formats with UBWC support
    756     switch(format)
    757     {
    758         case HAL_PIXEL_FORMAT_RGB_565:
    759         case HAL_PIXEL_FORMAT_RGBA_8888:
    760         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    761         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    762             return true;
    763         default:
    764             return false;
    765     }
    766 }
    767 
    768 bool isUBwcEnabled(int format, int usage)
    769 {
    770     if (isUBwcFormat(format) ||
    771         ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)))
    772     {
    773         // Allow UBWC, only if GPU supports it and CPU usage flags are not set
    774         if (AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format) &&
    775             !(usage & (GRALLOC_USAGE_SW_READ_MASK |
    776                       GRALLOC_USAGE_SW_WRITE_MASK))) {
    777             return true;
    778         }
    779     }
    780     return false;
    781 }
    782 
    783 static void getUBwcWidthAndHeight(int width, int height, int format,
    784         int& aligned_w, int& aligned_h)
    785 {
    786     switch (format)
    787     {
    788         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    789         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    790         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    791             aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
    792             aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
    793             break;
    794         default:
    795             ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
    796             aligned_w = 0;
    797             aligned_h = 0;
    798             break;
    799     }
    800 }
    801 
    802 static void getUBwcBlockSize(int bpp, int& block_width, int& block_height)
    803 {
    804     block_width = 0;
    805     block_height = 0;
    806 
    807     switch(bpp)
    808     {
    809          case 2:
    810          case 4:
    811              block_width = 16;
    812              block_height = 4;
    813              break;
    814          case 8:
    815              block_width = 8;
    816              block_height = 4;
    817              break;
    818          case 16:
    819              block_width = 4;
    820              block_height = 4;
    821              break;
    822          default:
    823              ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
    824              break;
    825     }
    826 }
    827 
    828 static unsigned int getUBwcMetaBufferSize(int width, int height, int bpp)
    829 {
    830     unsigned int size = 0;
    831     int meta_width, meta_height;
    832     int block_width, block_height;
    833 
    834     getUBwcBlockSize(bpp, block_width, block_height);
    835 
    836     if (!block_width || !block_height) {
    837         ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
    838         return size;
    839     }
    840 
    841     // Align meta buffer height to 16 blocks
    842     meta_height = ALIGN(((height + block_height - 1) / block_height), 16);
    843 
    844     // Align meta buffer width to 64 blocks
    845     meta_width = ALIGN(((width + block_width - 1) / block_width), 64);
    846 
    847     // Align meta buffer size to 4K
    848     size = ((meta_width * meta_height), 4096);
    849     return size;
    850 }
    851 
    852 static unsigned int getUBwcSize(int width, int height, int format,
    853         const int alignedw, const int alignedh) {
    854 
    855     unsigned int size = 0;
    856     switch (format) {
    857         case HAL_PIXEL_FORMAT_RGB_565:
    858             size = alignedw * alignedh * 2;
    859             size += getUBwcMetaBufferSize(width, height, 2);
    860             break;
    861         case HAL_PIXEL_FORMAT_RGBA_8888:
    862             size = alignedw * alignedh * 4;
    863             size += getUBwcMetaBufferSize(width, height, 4);
    864             break;
    865         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    866         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    867         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
    868             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
    869             break;
    870         default:
    871             ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
    872             break;
    873     }
    874     return size;
    875 }
    876