/*
 * Copyright (C) 2016-2017 ARM Limited. All rights reserved.
 *
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <string.h>
#include <dlfcn.h>
#include <inttypes.h>
#include <cutils/log.h>

#if GRALLOC_USE_GRALLOC1_API == 1
#include <hardware/gralloc1.h>
#else
#include <hardware/gralloc.h>
#endif

#include "mali_gralloc_module.h"
#include "gralloc_priv.h"

static mali_gralloc_format_caps dpu_runtime_caps;
static mali_gralloc_format_caps vpu_runtime_caps;
static mali_gralloc_format_caps gpu_runtime_caps;
static mali_gralloc_format_caps cam_runtime_caps;
static pthread_mutex_t caps_init_mutex = PTHREAD_MUTEX_INITIALIZER;
static bool runtime_caps_read = false;

#define MALI_GRALLOC_GPU_LIB_NAME "libGLES_mali.so"
#if defined(__LP64__)
#define MALI_GRALLOC_GPU_LIBRARY_PATH1 "/vendor/lib64/egl/"
#define MALI_GRALLOC_GPU_LIBRARY_PATH2 "/system/lib64/egl/"
#else
#define MALI_GRALLOC_GPU_LIBRARY_PATH1 "/vendor/lib/egl/"
#define MALI_GRALLOC_GPU_LIBRARY_PATH2 "/system/lib/egl/"
#endif

#define GRALLOC_AFBC_MIN_SIZE 75

static bool get_block_capabilities(bool hal_module, const char *name, mali_gralloc_format_caps *block_caps)
{
	void *dso_handle = NULL;
	bool rval = false;

	/* Look for MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR symbol in user-space drivers
	 * to determine hw format capabilities.
	 */
	if (!hal_module)
	{
		dso_handle = dlopen(name, RTLD_LAZY);
	}
	else
	{
		/* libhardware does some heuristics to find hal modules
		 * and then stores the dso handle internally. Use this.
		 */
		const struct hw_module_t *module = { NULL };

		if (hw_get_module(name, &module) >= 0)
		{
			dso_handle = module->dso;
		}
	}

	if (dso_handle)
	{
		void *sym = dlsym(dso_handle, MALI_GRALLOC_FORMATCAPS_SYM_NAME_STR);

		if (sym)
		{
			memcpy((void *)block_caps, sym, sizeof(mali_gralloc_format_caps));
			rval = true;
		}

		if (!hal_module)
		{
			dlclose(dso_handle);
		}
	}

	return rval;
}

static int map_flex_formats(uint64_t req_format)
{
    /* Map Android flexible formats to internal base formats */
    if(req_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
       req_format == HAL_PIXEL_FORMAT_YCbCr_420_888)
    {
        req_format = MALI_GRALLOC_FORMAT_INTERNAL_NV12;

    }
    return req_format;
}

static bool is_afbc_supported(int req_format_mapped)
{
	bool rval = true;

	/* These base formats we currently don't support with compression */
	switch (req_format_mapped)
	{
	case MALI_GRALLOC_FORMAT_INTERNAL_RAW16:
	case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
	case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
	case MALI_GRALLOC_FORMAT_INTERNAL_BLOB:
	case MALI_GRALLOC_FORMAT_INTERNAL_P010:
	case MALI_GRALLOC_FORMAT_INTERNAL_P210:
	case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
	case HAL_PIXEL_FORMAT_YCbCr_422_I:
		rval = false;
		break;
	}

	return rval;
}

static bool is_android_yuv_format(int req_format)
{
	bool rval = false;

	switch (req_format)
	{
	case HAL_PIXEL_FORMAT_YV12:
	case HAL_PIXEL_FORMAT_Y8:
	case HAL_PIXEL_FORMAT_Y16:
	case HAL_PIXEL_FORMAT_YCbCr_420_888:
	case HAL_PIXEL_FORMAT_YCbCr_422_888:
	case HAL_PIXEL_FORMAT_YCbCr_444_888:
	case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
	case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
		rval = true;
		break;
	}

	return rval;
}

static bool is_afbc_allowed(int buffer_size)
{
	bool afbc_allowed = false;

	(void)buffer_size;

#if MALI_DISPLAY_VERSION == 550 || MALI_DISPLAY_VERSION == 650
#if GRALLOC_DISP_W != 0 && GRALLOC_DISP_H != 0
	afbc_allowed = ((buffer_size * 100) / (GRALLOC_DISP_W * GRALLOC_DISP_H)) >= GRALLOC_AFBC_MIN_SIZE;

#else
	/* If display size is not valid then always allow AFBC */
	afbc_allowed = true;

#endif
#else
	/* For cetus, always allow AFBC */
	afbc_allowed = true;
#endif
	return afbc_allowed;
}

static bool is_afbc_format(uint64_t internal_format)
{
	return (internal_format & MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK) != 0;
}

static uint64_t determine_best_format(int req_format, mali_gralloc_producer_type producer,
                                      mali_gralloc_consumer_type consumer, uint64_t producer_runtime_mask,
                                      uint64_t consumer_runtime_mask)
{
	/* Default is to return the requested format */
	uint64_t internal_format = req_format;
	uint64_t dpu_mask = dpu_runtime_caps.caps_mask;
	uint64_t gpu_mask = gpu_runtime_caps.caps_mask;
	uint64_t vpu_mask = vpu_runtime_caps.caps_mask;
	uint64_t cam_mask = cam_runtime_caps.caps_mask;

	if (producer == MALI_GRALLOC_PRODUCER_GPU &&
	    gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
	{
		gpu_mask &= producer_runtime_mask;

		if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
		{
			gpu_mask &= consumer_runtime_mask;
			dpu_mask &= consumer_runtime_mask;

			if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK &&
			    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK)
			{
				internal_format |= MALI_GRALLOC_INTFMT_AFBC_SPLITBLK;
			}
			else if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
			         dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
			{
				internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;

				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
				    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
				{
					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
				}
			}
		}
		else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
		{
			gpu_mask &= consumer_runtime_mask;

			/* When GPU acts as both producer and consumer it prefers 16x16 superblocks */
			if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
			{
				internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
			}

			if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
			{
				internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
			}
		}
		else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
		{
			vpu_mask &= consumer_runtime_mask;

			if (internal_format == HAL_PIXEL_FORMAT_YV12 || internal_format == MALI_GRALLOC_FORMAT_INTERNAL_NV12)
			{
				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
				{
					internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
				}

				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
				{
					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
				}
			}
		}
	}
	else if (producer == MALI_GRALLOC_PRODUCER_VIDEO_DECODER &&
	         vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
	{
		vpu_mask &= producer_runtime_mask;

		if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
		{
			gpu_mask &= consumer_runtime_mask;
			dpu_mask &= consumer_runtime_mask;

			if (internal_format == HAL_PIXEL_FORMAT_YV12)
			{
				if (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
				    gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
				    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
				{
					internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
				}

				if (vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
				    gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
				    dpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
				{
					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
				}
			}
		}
		else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
		{
			gpu_mask &= consumer_runtime_mask;

			if (internal_format == HAL_PIXEL_FORMAT_YV12)
			{
				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC &&
				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC)
				{
					internal_format |= MALI_GRALLOC_INTFMT_AFBC_BASIC;
				}

				if (gpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS &&
				    vpu_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS)
				{
					internal_format |= MALI_GRALLOC_INTFMT_AFBC_TILED_HEADERS;
				}
			}
		}
		else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
		{
			/* Fall-through. To be decided.*/
		}
	}
	else if (producer == MALI_GRALLOC_PRODUCER_CAMERA &&
	         cam_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
	{
		if (consumer == MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY)
		{
			/* Fall-through. To be decided.*/
		}
		else if (consumer == MALI_GRALLOC_CONSUMER_GPU_EXCL)
		{
			/* Fall-through. To be decided.*/
		}
		else if (consumer == MALI_GRALLOC_CONSUMER_VIDEO_ENCODER)
		{
			/* Fall-through. To be decided.*/
		}
	}

	return internal_format;
}

static uint64_t decode_internal_format(uint64_t req_format, mali_gralloc_format_type type)
{
	uint64_t internal_format, me_mask, base_format, mapped_base_format;

	if (type == MALI_GRALLOC_FORMAT_TYPE_USAGE)
	{
		internal_format = GRALLOC_PRIVATE_FORMAT_UNWRAP((int)req_format);
	}
	else if (type == MALI_GRALLOC_FORMAT_TYPE_INTERNAL)
	{
		internal_format = req_format;
	}
	else
	{
		internal_format = 0;
		goto out;
	}

	me_mask = internal_format & MALI_GRALLOC_INTFMT_ME_EXT_MASK;

	if (me_mask > 0 && ((me_mask - 1) & me_mask) != 0)
	{
		ALOGE("Internal format contains multiple mutually exclusive modifier bits: %" PRIx64, internal_format);
		internal_format = 0;
		goto out;
	}

	base_format = internal_format & MALI_GRALLOC_INTFMT_FMT_MASK;

	/* Even though private format allocations are intended to be for specific
	 * formats, certain test cases uses the flexible formats that needs to be mapped
	 * to internal ones.
	 */
	mapped_base_format = map_flex_formats((uint32_t)base_format);

	/* Validate the internal base format passed in */
	switch (mapped_base_format)
	{
	case MALI_GRALLOC_FORMAT_INTERNAL_RGBA_8888:
	case MALI_GRALLOC_FORMAT_INTERNAL_RGBX_8888:
	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_888:
	case MALI_GRALLOC_FORMAT_INTERNAL_RGB_565:
	case MALI_GRALLOC_FORMAT_INTERNAL_BGRA_8888:
	case MALI_GRALLOC_FORMAT_INTERNAL_YV12:
	case MALI_GRALLOC_FORMAT_INTERNAL_Y8:
	case MALI_GRALLOC_FORMAT_INTERNAL_Y16:
	case MALI_GRALLOC_FORMAT_INTERNAL_RAW16:
	case MALI_GRALLOC_FORMAT_INTERNAL_RAW12:
	case MALI_GRALLOC_FORMAT_INTERNAL_RAW10:
	case MALI_GRALLOC_FORMAT_INTERNAL_BLOB:
	case MALI_GRALLOC_FORMAT_INTERNAL_NV12:
	case MALI_GRALLOC_FORMAT_INTERNAL_NV21:
	case MALI_GRALLOC_FORMAT_INTERNAL_YUV422_8BIT:
	case MALI_GRALLOC_FORMAT_INTERNAL_Y0L2:
	case MALI_GRALLOC_FORMAT_INTERNAL_P010:
	case MALI_GRALLOC_FORMAT_INTERNAL_P210:
	case MALI_GRALLOC_FORMAT_INTERNAL_Y210:
	case MALI_GRALLOC_FORMAT_INTERNAL_Y410:
		if (mapped_base_format != base_format)
		{
			internal_format = (internal_format & MALI_GRALLOC_INTFMT_EXT_MASK) | mapped_base_format;
		}

		break;

	default:
		ALOGE("Internal base format requested is unrecognized: %" PRIx64, internal_format);
		internal_format = 0;
		break;
	}

out:
	return internal_format;
}

static bool determine_producer(mali_gralloc_producer_type *producer, uint64_t *producer_runtime_mask, int req_format,
                               int usage)
{
	bool rval = true;

	/* Default to GPU */
	*producer = MALI_GRALLOC_PRODUCER_GPU;

	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
	{
		rval = false;
	}
	else if (usage & GRALLOC_USAGE_HW_RENDER)
	{
		if (is_android_yuv_format(req_format))
		{
			if (gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE)
			{
				*producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
			}
			else
			{
				/* All GPUs that can write YUV AFBC can only do it in 16x16, optionally with tiled */
				*producer_runtime_mask &=
				    ~(MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK | MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK);
			}
		}

		*producer = MALI_GRALLOC_PRODUCER_GPU;
	}
	else if (usage & GRALLOC_USAGE_HW_CAMERA_MASK)
	{
		*producer = MALI_GRALLOC_PRODUCER_CAMERA;
	}
	/* HW_TEXTURE+HW_COMPOSER+EXTERNAL_DISP is a definition set by
	 * stagefright for "video decoder". We check for it here.
	 */
	else if ((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP)) ==
	         (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_EXTERNAL_DISP))
	{
		*producer = MALI_GRALLOC_PRODUCER_VIDEO_DECODER;
	}

	return rval;
}

static bool determine_consumer(mali_gralloc_consumer_type *consumer, uint64_t *consumer_runtime_mask, int req_format,
                               int usage)
{
	bool rval = true;

	/* Default to GPU */
	*consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL;

	if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK))
	{
		rval = false;
	}
	/* When usage explicitly targets a consumer, as it does with GRALLOC_USAGE_HW_FB,
	 * we pick DPU even if there are no runtime capabilities present.
	 */
	else if (usage & GRALLOC_USAGE_HW_FB)
	{
		*consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY;
	}
	else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
	{
		if (is_android_yuv_format(req_format))
		{
			if (vpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD)
				*consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
		}
		else
		{
			*consumer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
		}
		*consumer = MALI_GRALLOC_CONSUMER_VIDEO_ENCODER;
	}
	/* GRALLOC_USAGE_HW_COMPOSER is by default applied by SurfaceFlinger so we can't exclusively rely on it
	 * to determine consumer. When a buffer is targeted for either we reject the DPU when it lacks
	 * runtime capabilities, in favor of the more capable GPU.
	 */
	else if ((usage & (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER)) ==
	             (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER) &&
	         dpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT)
	{
		*consumer = MALI_GRALLOC_CONSUMER_GPU_OR_DISPLAY;
	}
	else if (usage & GRALLOC_USAGE_HW_TEXTURE)
	{
		*consumer = MALI_GRALLOC_CONSUMER_GPU_EXCL;
	}

	return rval;
}

/*
 * Here we determine format capabilities for the 4 IPs we support.
 * For now these are controlled by build defines, but in the future
 * they should be read out from each user-space driver.
 */
static void determine_format_capabilities()
{
	/* Loading libraries can take some time and
	 * we may see many allocations at boot.
	 */
	pthread_mutex_lock(&caps_init_mutex);

	if (runtime_caps_read)
	{
		goto already_init;
	}

	memset((void *)&dpu_runtime_caps, 0, sizeof(dpu_runtime_caps));
	memset((void *)&vpu_runtime_caps, 0, sizeof(vpu_runtime_caps));
	memset((void *)&gpu_runtime_caps, 0, sizeof(gpu_runtime_caps));
	memset((void *)&cam_runtime_caps, 0, sizeof(cam_runtime_caps));

	/* Determine DPU format capabilities */
	if (!get_block_capabilities(true, "hwcomposer", &dpu_runtime_caps))
	{
#if MALI_DISPLAY_VERSION >= 500
		dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
		dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;

#if MALI_DISPLAY_VERSION >= 550
		dpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
#endif
#endif
	}

	/* Determine GPU format capabilities */
	if (access(MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, R_OK) == 0)
	{
		get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH1 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps);
	}
	else if (access(MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, R_OK) == 0)
	{
		get_block_capabilities(false, MALI_GRALLOC_GPU_LIBRARY_PATH2 MALI_GRALLOC_GPU_LIB_NAME, &gpu_runtime_caps);
	}

	if ((gpu_runtime_caps.caps_mask & MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT) == 0)
	{
		ALOGW("Failed to find GPU block configuration in %s. Using static build configuration.",
		      MALI_GRALLOC_GPU_LIB_NAME);

#if MALI_GPU_SUPPORT_AFBC_BASIC == 1
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;

		/* Need to verify when to remove this */
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOWRITE;

#if MALI_SUPPORT_AFBC_SPLITBLK == 1
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
#endif

#if MALI_SUPPORT_AFBC_WIDEBLK == 1
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK;
#endif

#if MALI_USE_YUV_AFBC_WIDEBLK != 1
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK_YUV_DISABLE;
#endif

#if MALI_SUPPORT_AFBC_TILED_HEADERS == 1
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_SPLITBLK;
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_WIDEBLK;
		gpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS;
#endif
#endif /* MALI_GPU_SUPPORT_AFBC_BASIC == 1 */
	}

/* Determine VPU format capabilities */
#if MALI_VIDEO_VERSION == 500 || MALI_VIDEO_VERSION == 550
	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_YUV_NOREAD;
#endif

#if MALI_VIDEO_VERSION == 61
	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_OPTIONS_PRESENT;
	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_BASIC;
	vpu_runtime_caps.caps_mask |= MALI_GRALLOC_FORMAT_CAPABILITY_AFBC_TILED_HEADERS;
#endif

/* Build specific capability changes */
#if GRALLOC_ARM_NO_EXTERNAL_AFBC == 1
	{
		dpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
		gpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
		vpu_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
		cam_runtime_caps.caps_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
	}
#endif

	runtime_caps_read = true;

already_init:
	pthread_mutex_unlock(&caps_init_mutex);

	ALOGV("GPU format capabilities 0x%" PRIx64, gpu_runtime_caps.caps_mask);
	ALOGV("DPU format capabilities 0x%" PRIx64, dpu_runtime_caps.caps_mask);
	ALOGV("VPU format capabilities 0x%" PRIx64, vpu_runtime_caps.caps_mask);
	ALOGV("CAM format capabilities 0x%" PRIx64, cam_runtime_caps.caps_mask);
}

uint64_t mali_gralloc_select_format(uint64_t req_format, mali_gralloc_format_type type, uint64_t usage, int buffer_size)
{
	uint64_t internal_format = 0;
	mali_gralloc_consumer_type consumer;
	mali_gralloc_producer_type producer;
	uint64_t producer_runtime_mask = ~(0ULL);
	uint64_t consumer_runtime_mask = ~(0ULL);
	uint64_t req_format_mapped = 0;

	if (!runtime_caps_read)
	{
		/*
		 * It is better to initialize these when needed because
		 * not all processes allocates memory.
		 */
		determine_format_capabilities();
	}

	/* A unique usage specifies that an internal format is in req_format */
	if (usage & MALI_GRALLOC_USAGE_PRIVATE_FORMAT || type == MALI_GRALLOC_FORMAT_TYPE_INTERNAL)
	{
		internal_format = decode_internal_format(req_format, type);
		goto out;
	}

	/* Re-map special Android formats */
	req_format_mapped = map_flex_formats(req_format);

	/* Determine producer/consumer */
	if (!determine_producer(&producer, &producer_runtime_mask, req_format, usage) ||
	    !determine_consumer(&consumer, &consumer_runtime_mask, req_format, usage))
	{
		/* Failing to determine producer/consumer usually means
		 * client has requested sw rendering.
		 */
		internal_format = req_format_mapped;
		goto out;
	}

	/*
	 * Determine runtime capability limitations
	 */

	/* Disable AFBC based on unique usage */
	if ((usage & MALI_GRALLOC_USAGE_NO_AFBC) == MALI_GRALLOC_USAGE_NO_AFBC)
	{
		if (is_android_yuv_format(req_format_mapped))
		{
			ALOGE("It is invalid to specify NO_AFBC usage flags when allocating YUV formats.\
                   Requested fmt: 0x%" PRIx64 " Re-Mapped fmt: 0x%" PRIx64,
			      req_format, req_format_mapped);
			internal_format = 0;
			goto out;
		}

		producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
	}
	/* Disable AFBC based on buffer dimensions */
	else if (!is_afbc_allowed(buffer_size))
	{
		producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
	}
	else if (!is_afbc_supported(req_format_mapped))
	{
		producer_runtime_mask &= ~MALI_GRALLOC_FORMAT_CAPABILITY_AFBCENABLE_MASK;
	}

	/* Automatically select format in case producer/consumer identified */
	internal_format =
	    determine_best_format(req_format_mapped, producer, consumer, producer_runtime_mask, consumer_runtime_mask);

out:
	ALOGV("mali_gralloc_select_format: req_format=0x%08" PRIx64 " req_fmt_mapped=0x%" PRIx64
	      " internal_format=0x%" PRIx64 " usage=0x%" PRIx64,
	      req_format, req_format_mapped, internal_format, usage);

	return internal_format;
}

extern "C" {
void mali_gralloc_get_gpu_caps(struct mali_gralloc_format_caps *gpu_caps)
{
	if (gpu_caps != NULL)
	{
		if (!runtime_caps_read)
		{
			determine_format_capabilities();
		}

		memcpy(gpu_caps, (void *)&gpu_runtime_caps, sizeof(struct mali_gralloc_format_caps));
	}
}
}
