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