You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
697 lines
21 KiB
697 lines
21 KiB
/*
|
|
* 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 <log/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));
|
|
}
|
|
}
|
|
}
|