/*
 * Copyright (c) 2011 - 2016, The Linux Foundation. All rights reserved.

 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of The Linux Foundation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <cutils/log.h>
#include <fcntl.h>
#include <dlfcn.h>
#include "gralloc_priv.h"
#include "alloc_controller.h"
#include "memalloc.h"
#include "ionalloc.h"
#include "gr.h"
#include "qd_utils.h"
#include <qdMetaData.h>
#include <utils/Singleton.h>
#include <utils/Mutex.h>


#ifdef VENUS_COLOR_FORMAT
#include <media/msm_media_info.h>
#else
#define VENUS_Y_STRIDE(args...) 0
#define VENUS_Y_SCANLINES(args...) 0
#define VENUS_BUFFER_SIZE(args...) 0
#endif

#define ASTC_BLOCK_SIZE 16

#ifndef ION_FLAG_CP_PIXEL
#define ION_FLAG_CP_PIXEL 0
#endif

#ifndef ION_FLAG_ALLOW_NON_CONTIG
#define ION_FLAG_ALLOW_NON_CONTIG 0
#endif

#ifdef MASTER_SIDE_CP
#define CP_HEAP_ID ION_SECURE_HEAP_ID
#define SD_HEAP_ID ION_SECURE_DISPLAY_HEAP_ID
#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_CP_PIXEL)
#define ION_SD_FLAGS (ION_SECURE | ION_FLAG_CP_SEC_DISPLAY)
#else // SLAVE_SIDE_CP
#define CP_HEAP_ID ION_CP_MM_HEAP_ID
#define SD_HEAP_ID CP_HEAP_ID
#define ION_CP_FLAGS (ION_SECURE | ION_FLAG_ALLOW_NON_CONTIG)
#define ION_SD_FLAGS ION_SECURE
#endif

using namespace gralloc;
using namespace qdutils;
using namespace android;

ANDROID_SINGLETON_STATIC_INSTANCE(AdrenoMemInfo);
ANDROID_SINGLETON_STATIC_INSTANCE(MDPCapabilityInfo);

static void getYuvUBwcWidthHeight(int, int, int, int&, int&);
static unsigned int getUBwcSize(int, int, int, const int, const int);

//Common functions

/* The default policy is to return cached buffers unless the client explicity
 * sets the PRIVATE_UNCACHED flag or indicates that the buffer will be rarely
 * read or written in software. Any combination with a _RARELY_ flag will be
 * treated as uncached. */
static bool useUncached(const int& usage) {
    if ((usage & GRALLOC_USAGE_PROTECTED) or
        (usage & GRALLOC_USAGE_PRIVATE_UNCACHED) or
        ((usage & GRALLOC_USAGE_SW_WRITE_MASK) == GRALLOC_USAGE_SW_WRITE_RARELY) or
        ((usage & GRALLOC_USAGE_SW_READ_MASK) ==  GRALLOC_USAGE_SW_READ_RARELY))
        return true;

    return false;
}

//------------- MDPCapabilityInfo-----------------------//
MDPCapabilityInfo :: MDPCapabilityInfo() {
  isMacroTileSupported = false;
  qdutils::querySDEInfo(HAS_MACRO_TILE, &isMacroTileSupported);
}

int MDPCapabilityInfo :: isMacroTilingSupportedByMDP(){
    return isMacroTileSupported;
 }

//------------- AdrenoMemInfo-----------------------//
AdrenoMemInfo::AdrenoMemInfo()
{
    LINK_adreno_compute_aligned_width_and_height = NULL;
    LINK_adreno_compute_padding = NULL;
    LINK_adreno_isMacroTilingSupportedByGpu = NULL;
    LINK_adreno_compute_compressedfmt_aligned_width_and_height = NULL;
    LINK_adreno_isUBWCSupportedByGpu = NULL;
    LINK_adreno_get_gpu_pixel_alignment = NULL;

    libadreno_utils = ::dlopen("libadreno_utils.so", RTLD_NOW);
    if (libadreno_utils) {
        *(void **)&LINK_adreno_compute_aligned_width_and_height =
                ::dlsym(libadreno_utils, "compute_aligned_width_and_height");
        *(void **)&LINK_adreno_compute_padding =
                ::dlsym(libadreno_utils, "compute_surface_padding");
        *(void **)&LINK_adreno_isMacroTilingSupportedByGpu =
                ::dlsym(libadreno_utils, "isMacroTilingSupportedByGpu");
        *(void **)&LINK_adreno_compute_compressedfmt_aligned_width_and_height =
                ::dlsym(libadreno_utils,
                        "compute_compressedfmt_aligned_width_and_height");
        *(void **)&LINK_adreno_isUBWCSupportedByGpu =
                ::dlsym(libadreno_utils, "isUBWCSupportedByGpu");
        *(void **)&LINK_adreno_get_gpu_pixel_alignment =
                ::dlsym(libadreno_utils, "get_gpu_pixel_alignment");
    }

    // Check if the overriding property debug.gralloc.gfx_ubwc_disable
    // that disables UBWC allocations for the graphics stack is set
    gfx_ubwc_disable = 0;
    char property[PROPERTY_VALUE_MAX];
    property_get("debug.gralloc.gfx_ubwc_disable", property, "0");
    if(!(strncmp(property, "1", PROPERTY_VALUE_MAX)) ||
       !(strncmp(property, "true", PROPERTY_VALUE_MAX))) {
        gfx_ubwc_disable = 1;
    }
}

AdrenoMemInfo::~AdrenoMemInfo()
{
    if (libadreno_utils) {
        ::dlclose(libadreno_utils);
    }
}

int AdrenoMemInfo::isMacroTilingSupportedByGPU()
{
    if ((libadreno_utils)) {
        if(LINK_adreno_isMacroTilingSupportedByGpu) {
            return LINK_adreno_isMacroTilingSupportedByGpu();
        }
    }
    return 0;
}

void AdrenoMemInfo::getAlignedWidthAndHeight(const private_handle_t *hnd, int& aligned_w,
                          int& aligned_h) {
    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
        int w = metadata->bufferDim.sliceWidth;
        int h = metadata->bufferDim.sliceHeight;
        int f = hnd->format;
        int usage = 0;

        if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
            usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
        }

        getAlignedWidthAndHeight(w, h, f, usage, aligned_w, aligned_h);
    } else {
        aligned_w = hnd->width;
        aligned_h = hnd->height;
    }

}

bool isUncompressedRgbFormat(int format)
{
    bool is_rgb_format = false;

    switch (format)
    {
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_RGB_888:
        case HAL_PIXEL_FORMAT_RGB_565:
        case HAL_PIXEL_FORMAT_BGR_565:
        case HAL_PIXEL_FORMAT_BGRA_8888:
        case HAL_PIXEL_FORMAT_RGBA_5551:
        case HAL_PIXEL_FORMAT_RGBA_4444:
        case HAL_PIXEL_FORMAT_R_8:
        case HAL_PIXEL_FORMAT_RG_88:
        case HAL_PIXEL_FORMAT_BGRX_8888:
        case HAL_PIXEL_FORMAT_RGBA_1010102:
        case HAL_PIXEL_FORMAT_ARGB_2101010:
        case HAL_PIXEL_FORMAT_RGBX_1010102:
        case HAL_PIXEL_FORMAT_XRGB_2101010:
        case HAL_PIXEL_FORMAT_BGRA_1010102:
        case HAL_PIXEL_FORMAT_ABGR_2101010:
        case HAL_PIXEL_FORMAT_BGRX_1010102:
        case HAL_PIXEL_FORMAT_XBGR_2101010:    // Intentional fallthrough
            is_rgb_format = true;
            break;
        default:
            break;
    }

    return is_rgb_format;
}

void AdrenoMemInfo::getAlignedWidthAndHeight(int width, int height, int format,
                            int usage, int& aligned_w, int& aligned_h)
{
    bool ubwc_enabled = isUBwcEnabled(format, usage);

    // Currently surface padding is only computed for RGB* surfaces.
    if (isUncompressedRgbFormat(format) == true) {
        int tileEnabled = ubwc_enabled || isMacroTileEnabled(format, usage);
        getGpuAlignedWidthHeight(width, height, format, tileEnabled, aligned_w, aligned_h);
    } else if (ubwc_enabled) {
        getYuvUBwcWidthHeight(width, height, format, aligned_w, aligned_h);
    } else {
        aligned_w = width;
        aligned_h = height;
        int alignment = 32;
        switch (format)
        {
            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            case HAL_PIXEL_FORMAT_YCbCr_420_SP:
                if (LINK_adreno_get_gpu_pixel_alignment) {
                  alignment = LINK_adreno_get_gpu_pixel_alignment();
                }
                aligned_w = ALIGN(width, alignment);
                break;
            case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
                aligned_w = ALIGN(width, alignment);
                break;
            case HAL_PIXEL_FORMAT_RAW16:
                aligned_w = ALIGN(width, 16);
                break;
            case HAL_PIXEL_FORMAT_RAW10:
                aligned_w = ALIGN(width * 10 / 8, 8);
                break;
            case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
                aligned_w = ALIGN(width, 128);
                break;
            case HAL_PIXEL_FORMAT_YV12:
            case HAL_PIXEL_FORMAT_YCbCr_422_SP:
            case HAL_PIXEL_FORMAT_YCrCb_422_SP:
            case HAL_PIXEL_FORMAT_YCbCr_422_I:
            case HAL_PIXEL_FORMAT_YCrCb_422_I:
                aligned_w = ALIGN(width, 16);
                break;
            case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
            case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
                aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
                aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
                break;
            case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
                aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV21, width);
                aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV21, height);
                break;
            case HAL_PIXEL_FORMAT_BLOB:
            case HAL_PIXEL_FORMAT_RAW_OPAQUE:
                break;
            case HAL_PIXEL_FORMAT_NV21_ZSL:
                aligned_w = ALIGN(width, 64);
                aligned_h = ALIGN(height, 64);
                break;
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
            case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
                if(LINK_adreno_compute_compressedfmt_aligned_width_and_height) {
                    int bytesPerPixel = 0;
                    int raster_mode         = 0;   //Adreno unknown raster mode.
                    int padding_threshold   = 512; //Threshold for padding
                    //surfaces.

                    LINK_adreno_compute_compressedfmt_aligned_width_and_height(
                        width, height, format, 0,raster_mode, padding_threshold,
                        &aligned_w, &aligned_h, &bytesPerPixel);
                } else {
                    ALOGW("%s: Warning!! Symbols" \
                          " compute_compressedfmt_aligned_width_and_height" \
                          " not found", __FUNCTION__);
                }
                break;
            default: break;
        }
    }
}

void AdrenoMemInfo::getGpuAlignedWidthHeight(int width, int height, int format,
                            int tile_enabled, int& aligned_w, int& aligned_h)
{
    aligned_w = ALIGN(width, 32);
    aligned_h = ALIGN(height, 32);

    // Don't add any additional padding if debug.gralloc.map_fb_memory
    // is enabled
    char property[PROPERTY_VALUE_MAX];
    if((property_get("debug.gralloc.map_fb_memory", property, NULL) > 0) &&
       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
       (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
        return;
    }

    int bpp = 4;
    switch(format)
    {
        case HAL_PIXEL_FORMAT_RGB_888:
            bpp = 3;
            break;
        case HAL_PIXEL_FORMAT_RGB_565:
        case HAL_PIXEL_FORMAT_BGR_565:
        case HAL_PIXEL_FORMAT_RGBA_5551:
        case HAL_PIXEL_FORMAT_RGBA_4444:
            bpp = 2;
            break;
        default: break;
    }

    if (libadreno_utils) {
        int raster_mode         = 0;   // Adreno unknown raster mode.
        int padding_threshold   = 512; // Threshold for padding surfaces.
        // the function below computes aligned width and aligned height
        // based on linear or macro tile mode selected.
        if(LINK_adreno_compute_aligned_width_and_height) {
            LINK_adreno_compute_aligned_width_and_height(width,
                                 height, bpp, tile_enabled,
                                 raster_mode, padding_threshold,
                                 &aligned_w, &aligned_h);

        } else if(LINK_adreno_compute_padding) {
            int surface_tile_height = 1;   // Linear surface
            aligned_w = LINK_adreno_compute_padding(width, bpp,
                                 surface_tile_height, raster_mode,
                                 padding_threshold);
            ALOGW("%s: Warning!! Old GFX API is used to calculate stride",
                                                            __FUNCTION__);
        } else {
            ALOGW("%s: Warning!! Symbols compute_surface_padding and " \
                 "compute_aligned_width_and_height not found", __FUNCTION__);
        }
   }
}

int AdrenoMemInfo::isUBWCSupportedByGPU(int format)
{
    if (!gfx_ubwc_disable && libadreno_utils) {
        if (LINK_adreno_isUBWCSupportedByGpu) {
            ADRENOPIXELFORMAT gpu_format = getGpuPixelFormat(format);
            return LINK_adreno_isUBWCSupportedByGpu(gpu_format);
        }
    }
    return 0;
}

ADRENOPIXELFORMAT AdrenoMemInfo::getGpuPixelFormat(int hal_format)
{
    switch (hal_format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
            return ADRENO_PIXELFORMAT_R8G8B8A8;
        case HAL_PIXEL_FORMAT_RGBX_8888:
            return ADRENO_PIXELFORMAT_R8G8B8X8;
        case HAL_PIXEL_FORMAT_RGB_565:
            return ADRENO_PIXELFORMAT_B5G6R5;
        case HAL_PIXEL_FORMAT_BGR_565:
            return ADRENO_PIXELFORMAT_R5G6B5;
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
            return ADRENO_PIXELFORMAT_NV12;
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
            return ADRENO_PIXELFORMAT_NV12_EXT;
        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
            return ADRENO_PIXELFORMAT_TP10;
        case HAL_PIXEL_FORMAT_RGBA_1010102:
            return ADRENO_PIXELFORMAT_R10G10B10A2_UNORM;
        case HAL_PIXEL_FORMAT_RGBX_1010102:
            return ADRENO_PIXELFORMAT_R10G10B10X2_UNORM;
        case HAL_PIXEL_FORMAT_ABGR_2101010:
            return ADRENO_PIXELFORMAT_A2B10G10R10_UNORM;
        default:
            ALOGE("%s: No map for format: 0x%x", __FUNCTION__, hal_format);
            break;
    }
    return ADRENO_PIXELFORMAT_UNKNOWN;
}

//-------------- IAllocController-----------------------//
IAllocController* IAllocController::sController = NULL;
IAllocController* IAllocController::getInstance(void)
{
    if(sController == NULL) {
        sController = new IonController();
    }
    return sController;
}


//-------------- IonController-----------------------//
IonController::IonController()
{
    allocateIonMem();

    char property[PROPERTY_VALUE_MAX];
    property_get("video.disable.ubwc", property, "0");
    mDisableUBWCForEncode = atoi(property);
}

void IonController::allocateIonMem()
{
   mIonAlloc = new IonAlloc();
}

int IonController::allocate(alloc_data& data, int usage)
{
    int ionFlags = 0;
    int ionHeapId = 0;
    int ret;

    data.uncached = useUncached(usage);
    data.allocType = 0;

    if(usage & GRALLOC_USAGE_PROTECTED) {
        if (usage & GRALLOC_USAGE_PRIVATE_SECURE_DISPLAY) {
            ionHeapId = ION_HEAP(SD_HEAP_ID);
            /*
             * There is currently no flag in ION for Secure Display
             * VM. Please add it to the define once available.
             */
            ionFlags |= ION_SD_FLAGS;
        } else {
            ionHeapId = ION_HEAP(CP_HEAP_ID);
            ionFlags |= ION_CP_FLAGS;
        }
    } else if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP) {
        //MM Heap is exclusively a secure heap.
        //If it is used for non secure cases, fallback to IOMMU heap
        ALOGW("GRALLOC_USAGE_PRIVATE_MM_HEAP \
                                cannot be used as an insecure heap!\
                                trying to use system heap instead !!");
        ionHeapId |= ION_HEAP(ION_SYSTEM_HEAP_ID);
    }

    if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
        ionHeapId |= ION_HEAP(ION_CAMERA_HEAP_ID);

    if(usage & GRALLOC_USAGE_PRIVATE_ADSP_HEAP)
        ionHeapId |= ION_HEAP(ION_ADSP_HEAP_ID);

    if(ionFlags & ION_SECURE)
         data.allocType |= private_handle_t::PRIV_FLAGS_SECURE_BUFFER;

    // if no ion heap flags are set, default to system heap
    if(!ionHeapId)
        ionHeapId = ION_HEAP(ION_SYSTEM_HEAP_ID);

    //At this point we should have the right heap set, there is no fallback
    data.flags = ionFlags;
    data.heapId = ionHeapId;
    ret = mIonAlloc->alloc_buffer(data);

    if(ret >= 0 ) {
        data.allocType |= private_handle_t::PRIV_FLAGS_USES_ION;
    } else {
        ALOGE("%s: Failed to allocate buffer - heap: 0x%x flags: 0x%x",
                __FUNCTION__, ionHeapId, ionFlags);
    }

    return ret;
}

IMemAlloc* IonController::getAllocator(int flags)
{
    IMemAlloc* memalloc = NULL;
    if (flags & private_handle_t::PRIV_FLAGS_USES_ION) {
        memalloc = mIonAlloc;
    } else {
        ALOGE("%s: Invalid flags passed: 0x%x", __FUNCTION__, flags);
    }

    return memalloc;
}

bool isMacroTileEnabled(int format, int usage)
{
    bool tileEnabled = false;
    // Check whether GPU & MDSS supports MacroTiling feature
    if(AdrenoMemInfo::getInstance().isMacroTilingSupportedByGPU() &&
       MDPCapabilityInfo::getInstance().isMacroTilingSupportedByMDP())
    {
        // check the format
        switch(format)
        {
            case  HAL_PIXEL_FORMAT_RGBA_8888:
            case  HAL_PIXEL_FORMAT_RGBX_8888:
            case  HAL_PIXEL_FORMAT_BGRA_8888:
            case  HAL_PIXEL_FORMAT_RGB_565:
            case  HAL_PIXEL_FORMAT_BGR_565:
                {
                    tileEnabled = true;
                    // check the usage flags
                    if (usage & (GRALLOC_USAGE_SW_READ_MASK |
                                GRALLOC_USAGE_SW_WRITE_MASK)) {
                        // Application intends to use CPU for rendering
                        tileEnabled = false;
                    }
                    break;
                }
            default:
                break;
        }
    }
    return tileEnabled;
}

// helper function
unsigned int getSize(int format, int width, int height, int usage,
        const int alignedw, const int alignedh) {

    if (isUBwcEnabled(format, usage)) {
        return getUBwcSize(width, height, format, alignedw, alignedh);
    }

    unsigned int size = 0;
    switch (format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_BGRA_8888:
        case HAL_PIXEL_FORMAT_RGBA_1010102:
        case HAL_PIXEL_FORMAT_ARGB_2101010:
        case HAL_PIXEL_FORMAT_RGBX_1010102:
        case HAL_PIXEL_FORMAT_XRGB_2101010:
        case HAL_PIXEL_FORMAT_BGRA_1010102:
        case HAL_PIXEL_FORMAT_ABGR_2101010:
        case HAL_PIXEL_FORMAT_BGRX_1010102:
        case HAL_PIXEL_FORMAT_XBGR_2101010:
            size = alignedw * alignedh * 4;
            break;
        case HAL_PIXEL_FORMAT_RGB_888:
            size = alignedw * alignedh * 3;
            break;
        case HAL_PIXEL_FORMAT_RGB_565:
        case HAL_PIXEL_FORMAT_BGR_565:
        case HAL_PIXEL_FORMAT_RGBA_5551:
        case HAL_PIXEL_FORMAT_RGBA_4444:
        case HAL_PIXEL_FORMAT_RAW16:
            size = alignedw * alignedh * 2;
            break;
        case HAL_PIXEL_FORMAT_RAW10:
            size = ALIGN(alignedw * alignedh, 4096);
            break;

            // adreno formats
        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:  // NV21
            size  = ALIGN(alignedw*alignedh, 4096);
            size += ALIGN(2 * ALIGN(width/2, 32) * ALIGN(height/2, 32), 4096);
            break;
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:   // NV12
            // The chroma plane is subsampled,
            // but the pitch in bytes is unchanged
            // The GPU needs 4K alignment, but the video decoder needs 8K
            size  = ALIGN( alignedw * alignedh, 8192);
            size += ALIGN( alignedw * ALIGN(height/2, 32), 8192);
            break;
        case HAL_PIXEL_FORMAT_YV12:
            if ((format == HAL_PIXEL_FORMAT_YV12) && ((width&1) || (height&1))) {
                ALOGE("w or h is odd for the YV12 format");
                return 0;
            }
            size = alignedw*alignedh +
                    (ALIGN(alignedw/2, 16) * (alignedh/2))*2;
            size = ALIGN(size, (unsigned int)4096);
            break;
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2 + 1, 4096);
            break;
        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
        case HAL_PIXEL_FORMAT_YCbCr_422_I:
        case HAL_PIXEL_FORMAT_YCrCb_422_I:
            if(width & 1) {
                ALOGE("width is odd for the YUV422_SP format");
                return 0;
            }
            size = ALIGN(alignedw * alignedh * 2, 4096);
            break;
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
            break;
        case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV21, width, height);
            break;
        case HAL_PIXEL_FORMAT_BLOB:
        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
            if(height != 1) {
                ALOGE("%s: Buffers with format HAL_PIXEL_FORMAT_BLOB \
                      must have height==1 ", __FUNCTION__);
                return 0;
            }
            size = width;
            break;
        case HAL_PIXEL_FORMAT_NV21_ZSL:
            size = ALIGN((alignedw*alignedh) + (alignedw* alignedh)/2, 4096);
            break;
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_4x4_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x4_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_5x5_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x5_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_6x6_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x5_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x6_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_8x8_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x5_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x6_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x8_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_10x10_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x10_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_RGBA_ASTC_12x12_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
        case HAL_PIXEL_FORMAT_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
            size = alignedw * alignedh * ASTC_BLOCK_SIZE;
            break;
        default:
            ALOGE("%s: Unrecognized pixel format: 0x%x", __FUNCTION__, format);
            return 0;
    }
    return size;
}

unsigned int getBufferSizeAndDimensions(int width, int height, int format,
        int& alignedw, int &alignedh)
{
    unsigned int size;

    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
            height,
            format,
            0,
            alignedw,
            alignedh);

    size = getSize(format, width, height, 0 /* usage */, alignedw, alignedh);

    return size;
}


unsigned int getBufferSizeAndDimensions(int width, int height, int format,
        int usage, int& alignedw, int &alignedh)
{
    unsigned int size;

    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
            height,
            format,
            usage,
            alignedw,
            alignedh);

    size = getSize(format, width, height, usage, alignedw, alignedh);

    return size;
}


void getBufferAttributes(int width, int height, int format, int usage,
        int& alignedw, int &alignedh, int& tiled, unsigned int& size)
{
    tiled = isUBwcEnabled(format, usage) || isMacroTileEnabled(format, usage);

    AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
            height,
            format,
            usage,
            alignedw,
            alignedh);
    size = getSize(format, width, height, usage, alignedw, alignedh);
}

void getYuvUbwcSPPlaneInfo(uint64_t base, int width, int height,
                           int color_format, struct android_ycbcr* ycbcr)
{
    // UBWC buffer has these 4 planes in the following sequence:
    // Y_Meta_Plane, Y_Plane, UV_Meta_Plane, UV_Plane
    unsigned int y_meta_stride, y_meta_height, y_meta_size;
    unsigned int y_stride, y_height, y_size;
    unsigned int c_meta_stride, c_meta_height, c_meta_size;
    unsigned int alignment = 4096;

    y_meta_stride = VENUS_Y_META_STRIDE(color_format, width);
    y_meta_height = VENUS_Y_META_SCANLINES(color_format, height);
    y_meta_size = ALIGN((y_meta_stride * y_meta_height), alignment);

    y_stride = VENUS_Y_STRIDE(color_format, width);
    y_height = VENUS_Y_SCANLINES(color_format, height);
    y_size = ALIGN((y_stride * y_height), alignment);

    c_meta_stride = VENUS_UV_META_STRIDE(color_format, width);
    c_meta_height = VENUS_UV_META_SCANLINES(color_format, height);
    c_meta_size = ALIGN((c_meta_stride * c_meta_height), alignment);

    ycbcr->y  = (void*)(base + y_meta_size);
    ycbcr->cb = (void*)(base + y_meta_size + y_size + c_meta_size);
    ycbcr->cr = (void*)(base + y_meta_size + y_size +
                        c_meta_size + 1);
    ycbcr->ystride = y_stride;
    ycbcr->cstride = VENUS_UV_STRIDE(color_format, width);
}

void getYuvSPPlaneInfo(uint64_t base, int width, int height, int bpp,
                       struct android_ycbcr* ycbcr)
{
    unsigned int ystride, cstride;

    ystride = cstride = width * bpp;
    ycbcr->y  = (void*)base;
    ycbcr->cb = (void*)(base + ystride * height);
    ycbcr->cr = (void*)(base + ystride * height + 1);
    ycbcr->ystride = ystride;
    ycbcr->cstride = cstride;
    ycbcr->chroma_step = 2 * bpp;
}

int getYUVPlaneInfo(private_handle_t* hnd, struct android_ycbcr* ycbcr)
{
    int err = 0;
    int width = hnd->width;
    int height = hnd->height;
    int format = hnd->format;

    unsigned int ystride, cstride;

    memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;

    // Check if UBWC buffer has been rendered in linear format.
    if (metadata && (metadata->operation & LINEAR_FORMAT)) {
        format = metadata->linearFormat;
    }

    // Check metadata if the geometry has been updated.
    if(metadata && metadata->operation & UPDATE_BUFFER_GEOMETRY) {
        int usage = 0;

        if (hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
            usage = GRALLOC_USAGE_PRIVATE_ALLOC_UBWC;
        }

        AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(metadata->bufferDim.sliceWidth,
                   metadata->bufferDim.sliceHeight, format, usage, width, height);
    }

    // Get the chroma offsets from the handle width/height. We take advantage
    // of the fact the width _is_ the stride
    switch (format) {
        //Semiplanar
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
            getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
        break;

        case HAL_PIXEL_FORMAT_YCbCr_420_P010:
            getYuvSPPlaneInfo(hnd->base, width, height, 2, ycbcr);
        break;

        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
            getYuvUbwcSPPlaneInfo(hnd->base, width, height,
                                  COLOR_FMT_NV12_UBWC, ycbcr);
            ycbcr->chroma_step = 2;
        break;

        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
            getYuvUbwcSPPlaneInfo(hnd->base, width, height,
                                  COLOR_FMT_NV12_BPP10_UBWC, ycbcr);
            ycbcr->chroma_step = 3;
        break;

        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
        case HAL_PIXEL_FORMAT_YCrCb_422_SP:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP_VENUS:
        case HAL_PIXEL_FORMAT_NV21_ZSL:
        case HAL_PIXEL_FORMAT_RAW16:
        case HAL_PIXEL_FORMAT_RAW10:
            getYuvSPPlaneInfo(hnd->base, width, height, 1, ycbcr);
            std::swap(ycbcr->cb, ycbcr->cr);
        break;

        //Planar
        case HAL_PIXEL_FORMAT_YV12:
            ystride = width;
            cstride = ALIGN(width/2, 16);
            ycbcr->y  = (void*)hnd->base;
            ycbcr->cr = (void*)(hnd->base + ystride * height);
            ycbcr->cb = (void*)(hnd->base + ystride * height +
                    cstride * height/2);
            ycbcr->ystride = ystride;
            ycbcr->cstride = cstride;
            ycbcr->chroma_step = 1;
        break;
        //Unsupported formats
        case HAL_PIXEL_FORMAT_YCbCr_422_I:
        case HAL_PIXEL_FORMAT_YCrCb_422_I:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
        default:
        ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__, format);
        err = -EINVAL;
    }
    return err;

}



// Allocate buffer from width, height and format into a
// private_handle_t. It is the responsibility of the caller
// to free the buffer using the free_buffer function
int alloc_buffer(private_handle_t **pHnd, int w, int h, int format, int usage)
{
    alloc_data data;
    int alignedw, alignedh;
    gralloc::IAllocController* sAlloc =
        gralloc::IAllocController::getInstance();
    data.base = 0;
    data.fd = -1;
    data.offset = 0;
    data.size = getBufferSizeAndDimensions(w, h, format, usage, alignedw,
                                            alignedh);

    data.align = getpagesize();
    data.uncached = useUncached(usage);
    int allocFlags = usage;

    int err = sAlloc->allocate(data, allocFlags);
    if (0 != err) {
        ALOGE("%s: allocate failed", __FUNCTION__);
        return -ENOMEM;
    }

    if(isUBwcEnabled(format, usage)) {
      data.allocType |= private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
    }

    private_handle_t* hnd = new private_handle_t(data.fd, data.size,
                                                 data.allocType, 0, format,
                                                 alignedw, alignedh);
    hnd->base = (uint64_t) data.base;
    hnd->offset = data.offset;
    hnd->gpuaddr = 0;
    *pHnd = hnd;
    return 0;
}

void free_buffer(private_handle_t *hnd)
{
    gralloc::IAllocController* sAlloc =
        gralloc::IAllocController::getInstance();
    if (hnd && hnd->fd > 0) {
        IMemAlloc* memalloc = sAlloc->getAllocator(hnd->flags);
        memalloc->free_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd);
    }
    if(hnd)
        delete hnd;

}

// UBWC helper functions
static bool isUBwcFormat(int format)
{
    // Explicitly defined UBWC formats
    switch(format)
    {
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
            return true;
        default:
            return false;
    }
}

static bool isUBwcSupported(int format)
{
    // Existing HAL formats with UBWC support
    switch(format)
    {
        case HAL_PIXEL_FORMAT_BGR_565:
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
        case HAL_PIXEL_FORMAT_RGBA_1010102:
        case HAL_PIXEL_FORMAT_RGBX_1010102:
            return true;
        default:
            return false;
    }
}

bool isUBwcEnabled(int format, int usage)
{
    // Allow UBWC, if client is using an explicitly defined UBWC pixel format.
    if (isUBwcFormat(format))
        return true;

    if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) &&
        gralloc::IAllocController::getInstance()->isDisableUBWCForEncoder()) {
            return false;
    }

    // Allow UBWC, if an OpenGL client sets UBWC usage flag and GPU plus MDP
    // support the format. OR if a non-OpenGL client like Rotator, sets UBWC
    // usage flag and MDP supports the format.
    if ((usage & GRALLOC_USAGE_PRIVATE_ALLOC_UBWC) && isUBwcSupported(format)) {
        bool enable = true;
        // Query GPU for UBWC only if buffer is intended to be used by GPU.
        if (usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_RENDER)) {
            enable = AdrenoMemInfo::getInstance().isUBWCSupportedByGPU(format);
        }
        // Allow UBWC, only if CPU usage flags are not set
        if (enable && !(usage & (GRALLOC_USAGE_SW_READ_MASK |
            GRALLOC_USAGE_SW_WRITE_MASK))) {
            return true;
        }
    }
    return false;
}

static void getYuvUBwcWidthHeight(int width, int height, int format,
        int& aligned_w, int& aligned_h)
{
    switch (format)
    {
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
            aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
            aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height);
            break;
        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
            aligned_w = VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, width);
            aligned_h = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, height);
            break;
        default:
            ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
            aligned_w = 0;
            aligned_h = 0;
            break;
    }
}

static void getRgbUBwcBlockSize(int bpp, int& block_width, int& block_height)
{
    block_width = 0;
    block_height = 0;

    switch(bpp)
    {
         case 2:
         case 4:
             block_width = 16;
             block_height = 4;
             break;
         case 8:
             block_width = 8;
             block_height = 4;
             break;
         case 16:
             block_width = 4;
             block_height = 4;
             break;
         default:
             ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
             break;
    }
}

static unsigned int getRgbUBwcMetaBufferSize(int width, int height, int bpp)
{
    unsigned int size = 0;
    int meta_width, meta_height;
    int block_width, block_height;

    getRgbUBwcBlockSize(bpp, block_width, block_height);

    if (!block_width || !block_height) {
        ALOGE("%s: Unsupported bpp: %d", __FUNCTION__, bpp);
        return size;
    }

    // Align meta buffer height to 16 blocks
    meta_height = ALIGN(((height + block_height - 1) / block_height), 16);

    // Align meta buffer width to 64 blocks
    meta_width = ALIGN(((width + block_width - 1) / block_width), 64);

    // Align meta buffer size to 4K
    size = ALIGN((meta_width * meta_height), 4096);
    return size;
}

static unsigned int getUBwcSize(int width, int height, int format,
        const int alignedw, const int alignedh) {

    unsigned int size = 0;
    switch (format) {
        case HAL_PIXEL_FORMAT_BGR_565:
            size = alignedw * alignedh * 2;
            size += getRgbUBwcMetaBufferSize(width, height, 2);
            break;
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_RGBA_1010102:
        case HAL_PIXEL_FORMAT_RGBX_1010102:
            size = alignedw * alignedh * 4;
            size += getRgbUBwcMetaBufferSize(width, height, 4);
            break;
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC:
            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
            break;
        case HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC:
            size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_BPP10_UBWC, width, height);
            break;
        default:
            ALOGE("%s: Unsupported pixel format: 0x%x", __FUNCTION__, format);
            break;
    }
    return size;
}

int getRgbDataAddress(private_handle_t* hnd, void** rgb_data)
{
    int err = 0;

    // This api is for RGB* formats
    if (!isUncompressedRgbFormat(hnd->format)) {
        return -EINVAL;
    }

    // linear buffer
    if (!(hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)) {
        *rgb_data = (void*)hnd->base;
        return err;
    }

    unsigned int meta_size = 0;
    switch (hnd->format) {
        case HAL_PIXEL_FORMAT_BGR_565:
            meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 2);
            break;
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
            meta_size = getRgbUBwcMetaBufferSize(hnd->width, hnd->height, 4);
            break;
        default:
            ALOGE("%s:Unsupported RGB format: 0x%x", __FUNCTION__, hnd->format);
            err = -EINVAL;
            break;
    }

    *rgb_data = (void*)(hnd->base + meta_size);
    return err;
}
