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