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.
235 lines
6.1 KiB
235 lines
6.1 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd.. 2018-2019. All rights reserved.
|
|
* Description: Gralloc
|
|
* Author: Hisilicon
|
|
* Created: 2019.11.07
|
|
*/
|
|
|
|
#include "gralloc_attribute.h"
|
|
|
|
#include <securec.h>
|
|
#include <ion/ion.h>
|
|
#ifdef GRALLOC_NEED_SMMU_MAP
|
|
#include "ion_ext.h"
|
|
#endif
|
|
|
|
#include "gralloc_ion.h"
|
|
#include "mali_gralloc_formats.h"
|
|
|
|
int gralloc_buffer_attr_allocate(const private_module_t *m, struct private_internal_handle_t *handle)
|
|
{
|
|
int ret;
|
|
int attr_fd = -1;
|
|
int attr_size = ATTR_BUFFER_SIZE;
|
|
|
|
if (m == nullptr || handle == nullptr) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
#ifdef GRALLOC_NEED_SMMU_MAP
|
|
ion_user_handle_t attr_hnd = -1;
|
|
void *attr_base = nullptr;
|
|
|
|
ret = ion_alloc(m->client, attr_size, 0, ION_HEAP_SYSTEM_MASK, 0, &attr_hnd);
|
|
#else
|
|
ret = ion_alloc_fd(m->client, attr_size, 0, ION_HEAP_SMMU_MASK, 0, &attr_fd);
|
|
#endif
|
|
if (ret < 0) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
#ifdef GRALLOC_NEED_SMMU_MAP
|
|
ret = ion_share(m->client, attr_hnd, &attr_fd);
|
|
if (ret < 0) {
|
|
GRALLOC_ERROR_INFO();
|
|
ion_free(m->client, attr_hnd);
|
|
close(attr_fd);
|
|
handle->attr_hnd = -1;
|
|
handle->attr_fd = -1;
|
|
handle->attr_size = 0;
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
attr_base = mmap(nullptr, attr_size, PROT_READ | PROT_WRITE, MAP_SHARED, attr_fd, 0);
|
|
if (attr_base != MAP_FAILED) {
|
|
memset_s(attr_base, attr_size, 0, attr_size);
|
|
munmap(attr_base, attr_size);
|
|
} else {
|
|
GRALLOC_ERROR_INFO();
|
|
ion_free(m->client, attr_hnd);
|
|
close(attr_fd);
|
|
handle->attr_hnd = -1;
|
|
handle->attr_fd = -1;
|
|
handle->attr_size = 0;
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
handle->attr_hnd = attr_hnd;
|
|
#endif
|
|
handle->attr_fd = attr_fd;
|
|
handle->attr_size = attr_size;
|
|
|
|
return GRALLOC_SUCCESS;
|
|
}
|
|
|
|
int gralloc_buffer_attr_free(const private_module_t *m, struct private_internal_handle_t *handle)
|
|
{
|
|
if (m == nullptr || handle == nullptr) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
int attr_fd = handle->attr_fd;
|
|
#ifdef GRALLOC_NEED_SMMU_MAP
|
|
int ret = 0;
|
|
ion_user_handle_t attr_hnd = handle->attr_hnd;
|
|
|
|
if (attr_hnd != -1) {
|
|
ret = ion_free(m->client, attr_hnd);
|
|
if (ret < 0) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
handle->attr_hnd = -1;
|
|
} else {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
#endif
|
|
GRALLOC_IGNORE(m);
|
|
|
|
if (attr_fd != -1) {
|
|
close(attr_fd);
|
|
}
|
|
handle->attr_fd = -1;
|
|
handle->attr_size = 0;
|
|
|
|
return GRALLOC_SUCCESS;
|
|
}
|
|
|
|
int gralloc_buffer_attr_map(const private_module_t *m, struct private_internal_handle_t *handle)
|
|
{
|
|
if (m == nullptr || handle == nullptr) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
int attr_fd = handle->attr_fd;
|
|
void *attr_base = nullptr;
|
|
size_t attr_size = handle->attr_size;
|
|
|
|
#ifdef GRALLOC_NEED_SMMU_MAP
|
|
int ret;
|
|
unsigned int attr_addr = (unsigned int)-1;
|
|
ion_user_handle_t attr_hnd = -1;
|
|
|
|
ret = ion_import(m->client, attr_fd, &attr_hnd);
|
|
if (ret != 0) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
ret = ion_map_iommu(m->client, attr_hnd, &attr_addr, &attr_size, 0);
|
|
if (ret != 0) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
if (attr_size <= 0) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
handle->attr_hnd = attr_hnd;
|
|
handle->attr_addr = attr_addr;
|
|
handle->attr_size = attr_size;
|
|
#endif
|
|
attr_base = mmap(nullptr, attr_size, PROT_READ | PROT_WRITE, MAP_SHARED, attr_fd, 0);
|
|
if (attr_base == MAP_FAILED) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
handle->attr_base = attr_base;
|
|
|
|
return GRALLOC_SUCCESS;
|
|
}
|
|
|
|
int gralloc_buffer_attr_unmap(const private_module_t *m, struct private_internal_handle_t *handle)
|
|
{
|
|
if (m == nullptr || handle == nullptr || handle->attr_base == nullptr) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
munmap(handle->attr_base, handle->attr_size);
|
|
handle->attr_base = MAP_FAILED;
|
|
|
|
#ifdef GRALLOC_NEED_SMMU_MAP
|
|
int ret;
|
|
ion_user_handle_t attr_hnd = handle->attr_hnd;
|
|
|
|
if (handle->attr_addr != (unsigned int)-1) {
|
|
ret = ion_unmap_iommu(m->client, attr_hnd, 0);
|
|
if (ret < 0) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
ret = ion_free(m->client, attr_hnd);
|
|
if (ret < 0) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
}
|
|
|
|
handle->attr_hnd = -1;
|
|
handle->attr_addr = (unsigned int)-1;
|
|
handle->attr_size = 0;
|
|
#else
|
|
GRALLOC_IGNORE(m);
|
|
#endif
|
|
|
|
return GRALLOC_SUCCESS;
|
|
}
|
|
|
|
int gralloc_init_attribute_buffer(const private_module_t *m, private_internal_handle_t *handle)
|
|
{
|
|
if (m == nullptr || handle == nullptr) {
|
|
GRALLOC_ERROR_INFO();
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
if (gralloc_buffer_attr_map(m, handle) != GRALLOC_SUCCESS) {
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
int val;
|
|
/* init compression flag */
|
|
if ((handle->internal_format & MALI_GRALLOC_INTFMT_AFBC_BASIC) != 0) {
|
|
val = COMPRESSION_FLAG_AFBC;
|
|
} else if ((handle->internal_format & MALI_GRALLOC_INTFMT_HFBC_BASIC) != 0) {
|
|
val = COMPRESSION_FLAG_HFBC;
|
|
} else {
|
|
val = COMPRESSION_FLAG_LINEAR;
|
|
}
|
|
|
|
if (gralloc_buffer_attr_write(reinterpret_cast<private_handle_t*>(handle),
|
|
GRALLOC_BUFFER_ATTR_COMPRESSION, &val) != GRALLOC_SUCCESS) {
|
|
gralloc_buffer_attr_unmap(m, handle);
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
/* init attr private buffer for media */
|
|
struct attr_private_buffer buf = {-1, ATTR_REGION_SIZE, ATTR_MEDIA_PRIVATE_BUFFER_SIZE, nullptr};
|
|
if (gralloc_buffer_attr_write(reinterpret_cast<private_handle_t*>(handle),
|
|
GRALLOC_BUFFER_ATTR_MEDIA, &buf) != GRALLOC_SUCCESS) {
|
|
gralloc_buffer_attr_unmap(m, handle);
|
|
return GRALLOC_FAILURE;
|
|
}
|
|
|
|
gralloc_buffer_attr_unmap(m, handle);
|
|
return GRALLOC_SUCCESS;
|
|
}
|