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