Home | History | Annotate | Download | only in libgralloc
      1 /*
      2  * Copyright (c) 2011-2014,2016, The Linux Foundation. All rights reserved.
      3 
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *   * Redistributions of source code must retain the above copyright
      8  *     notice, this list of conditions and the following disclaimer.
      9  *   * Redistributions in binary form must reproduce the above
     10  *     copyright notice, this list of conditions and the following
     11  *     disclaimer in the documentation and/or other materials provided
     12  *     with the distribution.
     13  *   * Neither the name of The Linux Foundation nor the names of its
     14  *     contributors may be used to endorse or promote products derived
     15  *     from this software without specific prior written permission.
     16  *
     17  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28  */
     29 
     30 #include <cutils/log.h>
     31 #include <fcntl.h>
     32 #include <dlfcn.h>
     33 #include "gralloc_priv.h"
     34 #include "alloc_controller.h"
     35 #include "memalloc.h"
     36 #include "ionalloc.h"
     37 #include "gr.h"
     38 #include "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 //Common functions
     57 static bool canFallback(int usage, bool triedSystem)
     58 {
     59     // Fallback to system heap when alloc fails unless
     60     // 1. Composition type is MDP
     61     // 2. Alloc from system heap was already tried
     62     // 3. The heap type is requsted explicitly
     63     // 4. The heap type is protected
     64     // 5. The buffer is meant for external display only
     65 
     66     if(QCCompositionType::getInstance().getCompositionType() &
     67        COMPOSITION_TYPE_MDP)
     68         return false;
     69     if(triedSystem)
     70         return false;
     71     if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PROTECTED))
     72         return false;
     73     if(usage & (GRALLOC_HEAP_MASK | GRALLOC_USAGE_PRIVATE_EXTERNAL_ONLY))
     74         return false;
     75     //Return true by default
     76     return true;
     77 }
     78 
     79 /* The default policy is to return cached buffers unless the client explicity
     80  * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
     81  * read or written in software. Any combination with a _RARELY_ flag will be
     82  * treated as uncached. */
     83 static bool useUncached(const int& usage) {
     84     if((usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
     85             ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ==
     86             GRALLOC_USAGE_SW_WRITE_RARELY) or
     87             ((usage & GRALLOC_USAGE_SW_READ_MASK) ==
     88             GRALLOC_USAGE_SW_READ_RARELY))
     89         return true;
     90 
     91     return false;
     92 }
     93 
     94 //-------------- AdrenoMemInfo-----------------------//
     95 AdrenoMemInfo::AdrenoMemInfo()
     96 {
     97     LINK_adreno_compute_aligned_width_and_height = NULL;
     98     LINK_adreno_compute_padding = NULL;
     99     LINK_adreno_isMacroTilingSupportedByGpu = NULL;
    100     LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
    101     LINK_adreno_get_gpu_pixel_alignment = NULL;
    102 
    103     libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
    104     if (libadreno_utils) {
    105         *(void **)&LINK_adreno_compute_aligned_width_and_height =
    106                 ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
    107         *(void **)&LINK_adreno_compute_padding =
    108                 ::dlsym(libadreno_utils, "compute_surface_padding");
    109         *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
    110                 ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
    111         *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
    112                 ::dlsym(libadreno_utils,
    113                         "compute_compressedfmt_aligned_width_and_height");
    114         *(void **)&LINK_adreno_get_gpu_pixel_alignment =
    115                 ::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
    116     }
    117 }
    118 
    119 AdrenoMemInfo::~AdrenoMemInfo()
    120 {
    121     if (libadreno_utils) {
    122         ::dlclose(libadreno_utils);
    123     }
    124 }
    125 
    126 int AdrenoMemInfo::isMacroTilingSupportedByGPU()
    127 {
    128     if ((libadreno_utils)) {
    129         if(LINK_adreno_isMacroTilingSupportedByGpu) {
    130             return LINK_adreno_isMacroTilingSupportedByGpu();
    131         }
    132     }
    133     return 0;
    134 }
    135 
    136 
    137 void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
    138                             int tile_enabled, int& aligned_w, int& aligned_h)
    139 {
    140     aligned_w = width;
    141     aligned_h = height;
    142     // Currently surface padding is only computed for RGB* surfaces.
    143     if (format <= HAL_PIXEL_FORMAT_BGRA_8888) {
    144         aligned_w = ALIGN(width, 32);
    145         aligned_h = ALIGN(height, 32);
    146         // Don't add any additional padding if debug.gralloc.map_fb_memory
    147         // is enabled
    148         char property[PROPERTY_VALUE_MAX];
    149         if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
    150            (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
    151            (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
    152               return;
    153         }
    154 
    155         int bpp = 4;
    156         switch(format)
    157         {
    158             case HAL_PIXEL_FORMAT_RGB_888:
    159                 bpp = 3;
    160                 break;
    161             case HAL_PIXEL_FORMAT_RGB_565:
    162                 bpp = 2;
    163                 break;
    164             default: break;
    165         }
    166         if (libadreno_utils) {
    167             int raster_mode         = 0;   // Adreno unknown raster mode.
    168             int padding_threshold   = 512; // Threshold for padding surfaces.
    169             // the function below computes aligned width and aligned height
    170             // based on linear or macro tile mode selected.
    171             if(LINK_adreno_compute_aligned_width_and_height) {
    172                 LINK_adreno_compute_aligned_width_and_height(width,
    173                                      height, bpp, tile_enabled,
    174                                      raster_mode, padding_threshold,
    175                                      &aligned_w, &aligned_h);
    176 
    177             } else if(LINK_adreno_compute_padding) {
    178                 int surface_tile_height = 1;   // Linear surface
    179                 aligned_w = LINK_adreno_compute_padding(width, bpp,
    180                                      surface_tile_height, raster_mode,
    181                                      padding_threshold);
    182                 ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
    183                                                             __FUNCTION__);
    184             } else {
    185                 ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
    186                     "compute_aligned_width_and_height not found", __FUNCTION__);
    187             }
    188         }
    189     } else {
    190         int alignment = 32;
    191         switch (format)
    192         {
    193             case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    194             case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    195                 if (LINK_adreno_get_gpu_pixel_alignment) {
    196                     alignment = LINK_adreno_get_gpu_pixel_alignment();
    197                 }
    198                 aligned_w = ALIGN(width, alignment);
    199                 break;
    200             case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    201                 aligned_w = ALIGN(width, alignment);
    202                 break;
    203             case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    204                 aligned_w = ALIGN(width, 128);
    205                 break;
    206             case HAL_PIXEL_FORMAT_YV12:
    207             case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    208             case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    209             case HAL_PIXEL_FORMAT_YCbCr_422_I:
    210             case HAL_PIXEL_FORMAT_YCrCb_422_I:
    211                 aligned_w = ALIGN(width, 16);
    212                 break;
    213             case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    214             case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    215                 aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
    216                 aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
    217                 break;
    218             case HAL_PIXEL_FORMAT_BLOB:
    219                 break;
    220             case HAL_PIXEL_FORMAT_NV21_ZSL:
    221                 aligned_w = ALIGN(width, 64);
    222                 aligned_h = ALIGN(height, 64);
    223                 break;
    224             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
    225             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
    226             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
    227             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
    228             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
    229             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
    230             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
    231             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
    232             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
    233             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
    234             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
    235             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
    236             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
    237             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
    238             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
    239             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
    240             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
    241             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
    242             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
    243             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
    244             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
    245             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
    246             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
    247             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
    248             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
    249             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
    250             case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
    251             case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
    252                 if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
    253                     int bytesPerPixel = 0;
    254                     int raster_mode         = 0;   //Adreno unknown raster mode.
    255                     int padding_threshold   = 512; //Threshold for padding
    256                     //surfaces.
    257 
    258                     LINK_adreno_compute_compressedfmt_aligned_width_and_height(
    259                         width, height, format, 0,raster_mode, padding_threshold,
    260                         &aligned_w, &aligned_h, &bytesPerPixel);
    261 
    262                 } else {
    263                     ALOGW("%s: Warning!! Symbols" \
    264                           " compute_compressedfmt_aligned_width_and_height" \
    265                           " not found", __FUNCTION__);
    266                 }
    267                 break;
    268             default: break;
    269         }
    270     }
    271 }
    272 
    273 //-------------- IAllocController-----------------------//
    274 IAllocController* IAllocController::sController = NULL;
    275 IAllocController* IAllocController::getInstance(void)
    276 {
    277     if(sController == NULL) {
    278         sController = new IonController();
    279     }
    280     return sController;
    281 }
    282 
    283 
    284 //-------------- IonController-----------------------//
    285 IonController::IonController()
    286 {
    287     allocateIonMem();
    288 }
    289 
    290 void IonController::allocateIonMem()
    291 {
    292    mIonAlloc = new IonAlloc();
    293 }
    294 
    295 int IonController::allocate(alloc_data& data, int usage)
    296 {
    297     int ionFlags = 0;
    298     int ret;
    299 
    300     data.uncached = useUncached(usage);
    301     data.allocType = 0;
    302 
    303     if(usage & GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP)
    304         ionFlags |= ION_HEAP(ION_SF_HEAP_ID);
    305 
    306     if(usage & GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP)
    307         ionFlags |= ION_HEAP(ION_SYSTEM_HEAP_ID);
    308 
    309     if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
    310         ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
    311 
    312     if(usage & GRALLOC_USAGE_PROTECTED) {
    313         if (usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
    314             ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
    315             ionFlags |= ION_SECURE;
    316         } else {
    317             // for targets/OEMs which do not need HW level protection
    318             // do not set ion secure flag & MM heap. Fallback to IOMMU heap.
    319             ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
    320         }
    321     } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
    322         //MM Heap is exclusively a secure heap.
    323         //If it is used for non secure cases, fallback to IOMMU heap
    324         ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
    325                                 cannot be used as an insecure heap!\
    326                                 trying to use IOMMU instead !!");
    327         ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
    328     }
    329 
    330     if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
    331         ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
    332 
    333     if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
    334         ionFlags |= ION_HEAP(ION_ADSP_HEAP_ID);
    335 
    336     if(ionFlags & ION_SECURE)
    337          data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;
    338 
    339     // if no flags are set, default to
    340     // SF + IOMMU heaps, so that bypass can work
    341     // we can fall back to system heap if
    342     // we run out.
    343     if(!ionFlags)
    344         ionFlags = ION_HEAP(ION_SF_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID);
    345 
    346     data.flags = ionFlags;
    347     ret = mIonAlloc->alloc_buffer(data);
    348 
    349     // Fallback
    350     if(ret < 0 && canFallback(usage,
    351                               (ionFlags & ION_SYSTEM_HEAP_ID)))
    352     {
    353         ALOGW("Falling back to system heap");
    354         data.flags = ION_HEAP(ION_SYSTEM_HEAP_ID);
    355         ret = mIonAlloc->alloc_buffer(data);
    356     }
    357 
    358     if(ret >= 0 ) {
    359         data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
    360     }
    361 
    362     return ret;
    363 }
    364 
    365 IMemAlloc* IonController::getAllocator(int flags)
    366 {
    367     IMemAlloc* memalloc = NULL;
    368     if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
    369         memalloc = mIonAlloc;
    370     } else {
    371         ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
    372     }
    373 
    374     return memalloc;
    375 }
    376 
    377 bool isMacroTileEnabled(int format, int usage)
    378 {
    379     bool tileEnabled = false;
    380 
    381     // Check whether GPU & MDSS supports MacroTiling feature
    382     if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
    383             qdutils::MDPVersion::getInstance().supportsMacroTile())
    384     {
    385         // check the format
    386         switch(format)
    387         {
    388             case  HAL_PIXEL_FORMAT_RGBA_8888:
    389             case  HAL_PIXEL_FORMAT_RGBX_8888:
    390             case  HAL_PIXEL_FORMAT_BGRA_8888:
    391             case  HAL_PIXEL_FORMAT_RGB_565:
    392                 {
    393                     tileEnabled = true;
    394                     // check the usage flags
    395                     if (usage & (GRALLOC_USAGE_SW_READ_MASK |
    396                                 GRALLOC_USAGE_SW_WRITE_MASK)) {
    397                         // Application intends to use CPU for rendering
    398                         tileEnabled = false;
    399                     }
    400                     break;
    401                 }
    402             default:
    403                 break;
    404         }
    405     }
    406     return tileEnabled;
    407 }
    408 
    409 // helper function
    410 unsigned int getSize(int format, int width, int height, const int alignedw,
    411         const int alignedh) {
    412     unsigned int size = 0;
    413 
    414     switch (format) {
    415         case HAL_PIXEL_FORMAT_RGBA_8888:
    416         case HAL_PIXEL_FORMAT_RGBX_8888:
    417         case HAL_PIXEL_FORMAT_BGRA_8888:
    418             size = alignedw * alignedh * 4;
    419             break;
    420         case HAL_PIXEL_FORMAT_RGB_888:
    421             size = alignedw * alignedh * 3;
    422             break;
    423         case HAL_PIXEL_FORMAT_RGB_565:
    424         case HAL_PIXEL_FORMAT_RAW16:
    425             size = alignedw * alignedh * 2;
    426             break;
    427 
    428             // adreno formats
    429         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
    430             size  = ALIGN(alignedw*alignedh, 4096);
    431             size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
    432             break;
    433         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
    434             // The chroma plane is subsampled,
    435             // but the pitch in bytes is unchanged
    436             // The GPU needs 4K alignment, but the video decoder needs 8K
    437             size  = ALIGN( alignedw * alignedh, 8192);
    438             size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
    439             break;
    440         case HAL_PIXEL_FORMAT_YV12:
    441             if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
    442                 ALOGE("w or h is odd for the YV12 format");
    443                 return 0;
    444             }
    445             size = alignedw*alignedh +
    446                     (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
    447             size = ALIGN(size, (unsigned int)4096);
    448             break;
    449         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    450         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    451             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
    452             break;
    453         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    454         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    455         case HAL_PIXEL_FORMAT_YCbCr_422_I:
    456         case HAL_PIXEL_FORMAT_YCrCb_422_I:
    457             if(width & 1) {
    458                 ALOGE("width is odd for the YUV422_SP format");
    459                 return 0;
    460             }
    461             size = ALIGN(alignedw * alignedh * 2, 4096);
    462             break;
    463         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    464         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
    465             size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
    466             break;
    467         case HAL_PIXEL_FORMAT_BLOB:
    468             if(height != 1) {
    469                 ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
    470                       must have height==1 ", __FUNCTION__);
    471                 return 0;
    472             }
    473             size = width;
    474             break;
    475         case HAL_PIXEL_FORMAT_NV21_ZSL:
    476             size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
    477             break;
    478         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
    479         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
    480         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
    481         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
    482         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
    483         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
    484         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
    485         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
    486         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
    487         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
    488         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
    489         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
    490         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
    491         case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
    492         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
    493         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
    494         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
    495         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
    496         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
    497         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
    498         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
    499         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
    500         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
    501         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
    502         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
    503         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
    504         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
    505         case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
    506             size = alignedw * alignedh * ASTC_BLOCK_SIZE;
    507             break;
    508         default:
    509             ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
    510             return 0;
    511     }
    512     return size;
    513 }
    514 
    515 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
    516         int& alignedw, int &alignedh)
    517 {
    518     unsigned int size;
    519 
    520     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    521             height,
    522             format,
    523             false,
    524             alignedw,
    525             alignedh);
    526 
    527     size = getSize(format, width, height, alignedw, alignedh);
    528 
    529     return size;
    530 }
    531 
    532 
    533 unsigned int getBufferSizeAndDimensions(int width, int height, int format,
    534         int usage, int& alignedw, int &alignedh)
    535 {
    536     unsigned int size;
    537     int tileEnabled = isMacroTileEnabled(format, usage);
    538 
    539     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    540             height,
    541             format,
    542             tileEnabled,
    543             alignedw,
    544             alignedh);
    545 
    546     size = getSize(format, width, height, alignedw, alignedh);
    547 
    548     return size;
    549 }
    550 
    551 
    552 void getBufferAttributes(int width, int height, int format, int usage,
    553         int& alignedw, int &alignedh, int& tileEnabled, unsigned int& size)
    554 {
    555     tileEnabled = isMacroTileEnabled(format, usage);
    556 
    557     AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
    558             height,
    559             format,
    560             tileEnabled,
    561             alignedw,
    562             alignedh);
    563     size = getSize(format, width, height, alignedw, alignedh);
    564 }
    565 
    566 int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
    567 {
    568     int err = 0;
    569     unsigned int ystride, cstride;
    570     memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
    571 
    572     // Get the chroma offsets from the handle width/height. We take advantage
    573     // of the fact the width _is_ the stride
    574     switch (hnd->format) {
    575         //Semiplanar
    576         case HAL_PIXEL_FORMAT_YCbCr_420_SP:
    577         case HAL_PIXEL_FORMAT_YCbCr_422_SP:
    578         case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
    579         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
    580             ystride = cstride = hnd->width;
    581             ycbcr->y  = (void*)hnd->base;
    582             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height);
    583             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height + 1);
    584             ycbcr->ystride = ystride;
    585             ycbcr->cstride = cstride;
    586             ycbcr->chroma_step = 2;
    587         break;
    588 
    589         case HAL_PIXEL_FORMAT_YCrCb_420_SP:
    590         case HAL_PIXEL_FORMAT_YCrCb_422_SP:
    591         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
    592         case HAL_PIXEL_FORMAT_NV21_ZSL:
    593             ystride = cstride = hnd->width;
    594             ycbcr->y  = (void*)hnd->base;
    595             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
    596             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
    597             ycbcr->ystride = ystride;
    598             ycbcr->cstride = cstride;
    599             ycbcr->chroma_step = 2;
    600         break;
    601 
    602         //Planar
    603         case HAL_PIXEL_FORMAT_YV12:
    604             ystride = hnd->width;
    605             cstride = ALIGN(hnd->width/2, 16);
    606             ycbcr->y  = (void*)hnd->base;
    607             ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
    608             ycbcr->cb = (void*)(hnd->base + ystride * hnd->height +
    609                     cstride * hnd->height/2);
    610             ycbcr->ystride = ystride;
    611             ycbcr->cstride = cstride;
    612             ycbcr->chroma_step = 1;
    613 
    614         break;
    615         //Unsupported formats
    616         case HAL_PIXEL_FORMAT_YCbCr_422_I:
    617         case HAL_PIXEL_FORMAT_YCrCb_422_I:
    618         case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
    619         default:
    620         ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
    621                 hnd->format);
    622         err = -EINVAL;
    623     }
    624     return err;
    625 
    626 }
    627 
    628 
    629 
    630 // Allocate buffer from width, height and format into a
    631 // private_handle_t. It is the responsibility of the caller
    632 // to free the buffer using the free_buffer function
    633 int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
    634 {
    635     alloc_data data;
    636     int alignedw, alignedh;
    637     gralloc::IAllocController* sAlloc =
    638         gralloc::IAllocController::getInstance();
    639     data.base = 0;
    640     data.fd = -1;
    641     data.offset = 0;
    642     data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
    643                                             alignedh);
    644 
    645     data.align = getpagesize();
    646     data.uncached = useUncached(usage);
    647     int allocFlags = usage;
    648 
    649     int err = sAlloc->allocate(data, allocFlags);
    650     if (0 != err) {
    651         ALOGE("%s: allocate failed", __FUNCTION__);
    652         return -ENOMEM;
    653     }
    654 
    655     private_handle_t* hnd = new private_handle_t(data.fd, data.size,
    656                                                  data.allocType, 0, format,
    657                                                  alignedw, alignedh);
    658     hnd->base = (uint64_t) data.base;
    659     hnd->offset = data.offset;
    660     hnd->gpuaddr = 0;
    661     *pHnd = hnd;
    662     return 0;
    663 }
    664 
    665 void free_buffer(private_handle_t *hnd)
    666 {
    667     gralloc::IAllocController* sAlloc =
    668         gralloc::IAllocController::getInstance();
    669     if (hnd && hnd->fd > 0) {
    670         IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
    671         memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
    672     }
    673     if(hnd)
    674         delete hnd;
    675 
    676 }
    677