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

/*
* 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;
}