blob: 3f2b62a77f96e4e0b79c4e2d1c990ae1978490bb [file] [log] [blame]
/*
* Copyright (C) 2016 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.
*/
#ifndef MALI_GRALLOC_BUFFERALLOCATION_H_
#define MALI_GRALLOC_BUFFERALLOCATION_H_
#include "gralloc_helper.h"
int mali_gralloc_buffer_allocate(mali_gralloc_module const* m, int format, uint64_t consumer_usage, uint64_t producer_usage, int w, int h, uint32_t layer_count, buffer_handle_t* pHandle);
int mali_gralloc_buffer_free(mali_gralloc_module const* m, buffer_handle_t pHandle);
static inline unsigned int _select_heap(uint64_t consumer_usage, uint64_t producer_usage)
{
unsigned int heap_mask;
if (producer_usage & GRALLOC1_PRODUCER_USAGE_PROTECTED)
{
if (GRALLOC1_SLSI_USAGE_CHECK(producer_usage, GRALLOC1_PRODUCER_USAGE_PRIVATE_NONSECURE))
heap_mask = EXYNOS_ION_HEAP_SYSTEM_MASK;
else {
if (GRALLOC1_SLSI_USAGE_CHECK(consumer_usage, GRALLOC1_CONSUMER_USAGE_VIDEO_EXT))
heap_mask = EXYNOS_ION_HEAP_VIDEO_STREAM_MASK;
else if ((consumer_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER) &&
!(consumer_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) &&
!(producer_usage & GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))
heap_mask = EXYNOS_ION_HEAP_VIDEO_SCALER_MASK;
else
heap_mask = EXYNOS_ION_HEAP_VIDEO_FRAME_MASK;
}
}
else if (GRALLOC1_SLSI_USAGE_CHECK(producer_usage, GRALLOC1_PRODUCER_USAGE_CAMERA_RESERVED))
{
heap_mask = EXYNOS_ION_HEAP_CAMERA_MASK;
}
else if (GRALLOC1_SLSI_USAGE_CHECK(producer_usage, GRALLOC1_PRODUCER_USAGE_SECURE_CAMERA_RESERVED))
{
heap_mask = EXYNOS_ION_HEAP_SECURE_CAMERA_MASK;
}
else
{
heap_mask = EXYNOS_ION_HEAP_SYSTEM_MASK;
}
return heap_mask;
}
static inline int adjustFrameworkFormats(int frameworkFormat, uint64_t consumer_usage, uint64_t producer_usage)
{
int format = frameworkFormat;
if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED)
{
AINF("HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED : consumer usage(%#" PRIx64 "), producer usage(%#" PRIx64 ")\n", consumer_usage, producer_usage);
if ((consumer_usage & GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE) || (consumer_usage & GRALLOC1_CONSUMER_USAGE_HWCOMPOSER))
{
if(GRALLOC1_SLSI_USAGE_CHECK(consumer_usage, GRALLOC1_CONSUMER_USAGE_YUV_RANGE_FULL))
{
format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL; // NV21M Full
}
else
{
format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; //NV21M narrow
}
}
else if (consumer_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER)
{
format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; //NV21M narrow
}
else if (GRALLOC1_SLSI_USAGE_CHECK(consumer_usage, GRALLOC1_CONSUMER_USAGE_VIDEO_PRIVATE_DATA))
{
format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M;
}
else if ((consumer_usage & GRALLOC1_CONSUMER_USAGE_CAMERA) && (producer_usage & GRALLOC1_PRODUCER_USAGE_CAMERA))
{
format = HAL_PIXEL_FORMAT_YCbCr_422_I; // YUYV
}
else
{
format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M; //NV21M narrow
}
}
else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888)
{
if (consumer_usage & GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER)
{
format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M;
}
else
{
// Flexible framework-accessible YUV format; map to NV21 for now
format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
}
}
return format;
}
static inline int getYUVFdsAndSizes(int ionfd, int planes, int luma_size, int chroma_size, uint64_t producer_usage, uint64_t consumer_usage,
unsigned int heap_mask, unsigned int ion_flags, int flags, int* fd, int* fd1, int* fd2, int* size, int* size1, int* size2, uint32_t layer_count)
{
GRALLOC_UNUSED(consumer_usage);
// fd
*size = luma_size * layer_count;
if (*size <= SIZE_4K)
*size += SIZE_4K;
*fd = exynos_ion_alloc(ionfd, *size, heap_mask, ion_flags);
if (*fd < 0)
{
AERR("failed to get fd from exynos_ion_alloc, %s, %d\n", __func__, __LINE__);
return -EINVAL;
}
// fd1
if (planes > 1)
{
if (GRALLOC1_SLSI_USAGE_CHECK(flags, private_handle_t::PRIV_FLAGS_USES_2PRIVATE_DATA))
{
*size1 = PRIV_SIZE;
heap_mask = EXYNOS_ION_HEAP_SYSTEM_MASK;
ion_flags = 0;
}
else
{
*size1 = chroma_size * layer_count;
if (*size1 <= SIZE_4K)
*size1 += SIZE_4K;
}
*fd1 = exynos_ion_alloc(ionfd, *size1, heap_mask, ion_flags);
if (*fd1 < 0)
{
AERR("failed to get fd1 from exynos_ion_alloc, %s, %d\n", __func__, __LINE__);
close(*fd);
return -EINVAL;
}
// fd2
if (planes == 3)
{
if (GRALLOC1_SLSI_USAGE_CHECK(flags, private_handle_t::PRIV_FLAGS_USES_3PRIVATE_DATA))
{
*size2 = PRIV_SIZE;
heap_mask = EXYNOS_ION_HEAP_SYSTEM_MASK;
ion_flags = 0;
}
else
{
*size2 = chroma_size * layer_count;
if (*size2 <= SIZE_4K)
*size2 += SIZE_4K;
}
*fd2 = exynos_ion_alloc(ionfd, *size2, heap_mask, ion_flags);
if (*fd2 < 0)
{
AERR("failed to get fd2 from exynos_ion_alloc, %s, %d\n", __func__, __LINE__);
close(*fd);
close(*fd1);
return -EINVAL;
}
}
}
return 0;
}
#endif /* MALI_GRALLOC_BUFFERALLOCATION_H_ */