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.
265 lines
6.9 KiB
265 lines
6.9 KiB
/*
|
|
* Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#define LOG_TAG "CamGraBuf"
|
|
#define LOG_NDEBUG 0
|
|
#include <log/log.h>
|
|
#include <utils/threads.h>
|
|
#include <utils/Log.h>
|
|
#include <ui/GraphicBufferAllocator.h>
|
|
#include <ui/GraphicBufferMapper.h>
|
|
#include <ui/GraphicBuffer.h>
|
|
#include <linux/videodev2.h>
|
|
#include "ExternalCameraGralloc.h"
|
|
|
|
using namespace android;
|
|
|
|
struct dma_buf_sync {
|
|
__u64 flags;
|
|
};
|
|
|
|
#define DMA_BUF_SYNC_READ (1 << 0)
|
|
#define DMA_BUF_SYNC_WRITE (2 << 0)
|
|
#define DMA_BUF_SYNC_RW (DMA_BUF_SYNC_READ | DMA_BUF_SYNC_WRITE)
|
|
#define DMA_BUF_SYNC_START (0 << 2)
|
|
#define DMA_BUF_SYNC_END (1 << 2)
|
|
#define DMA_BUF_SYNC_VALID_FLAGS_MASK \
|
|
(DMA_BUF_SYNC_RW | DMA_BUF_SYNC_END)
|
|
#define DMA_BUF_BASE 'b'
|
|
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
|
|
|
|
static cam_mem_handle_t* cam_mem_gralloc_ops_init(
|
|
int iommu_enabled, unsigned int mem_flag, int phy_continuos)
|
|
{
|
|
int ret = 0;
|
|
const hw_module_t *allocMod = NULL;
|
|
gralloc_module_t const* gm;
|
|
cam_mem_handle_t* handle = NULL;
|
|
ret= hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &allocMod);
|
|
if (ret == 0)
|
|
gm = reinterpret_cast<gralloc_module_t const *>(allocMod);
|
|
else
|
|
goto init_error;
|
|
handle = (cam_mem_handle_t*)malloc(sizeof(cam_mem_handle_t));
|
|
if (!handle) {
|
|
LOGE("%s:can't alloc handle!",__FUNCTION__);
|
|
goto init_error;
|
|
}
|
|
memset(handle, 0x0, sizeof(*handle));
|
|
|
|
handle->mem_type = CAM_MEM_TYPE_GRALLOC;
|
|
handle->iommu_enabled = iommu_enabled;
|
|
handle->phy_continuos = phy_continuos;
|
|
handle->priv = (void*)gm;
|
|
|
|
if (mem_flag & CAM_MEM_FLAG_HW_WRITE)
|
|
handle->flag |= GRALLOC_USAGE_HW_CAMERA_WRITE;
|
|
if (mem_flag & CAM_MEM_FLAG_HW_READ)
|
|
handle->flag |= GRALLOC_USAGE_HW_CAMERA_READ;
|
|
if (mem_flag & CAM_MEM_FLAG_SW_WRITE)
|
|
handle->flag |= GRALLOC_USAGE_SW_WRITE_OFTEN;
|
|
if (mem_flag & CAM_MEM_FLAG_SW_READ)
|
|
handle->flag |= GRALLOC_USAGE_SW_READ_OFTEN;
|
|
|
|
return handle;
|
|
init_error:
|
|
if (!handle)
|
|
free(handle);
|
|
return NULL;
|
|
}
|
|
|
|
//alloc GraphicBuffer
|
|
static cam_mem_info_t* cam_mem_gralloc_ops_alloc(
|
|
cam_mem_handle_t* handle, size_t size)
|
|
{
|
|
int ret;
|
|
unsigned int grallocFlags = 0;
|
|
unsigned int halPixFmt;
|
|
void* mem_addr = NULL;
|
|
GraphicBuffer* mgraphicbuf;
|
|
cam_mem_info_t* mem = NULL;
|
|
gralloc_module_t* mGrallocModule;
|
|
|
|
if (!handle) {
|
|
LOGE("invalid ion mem handle!");
|
|
return NULL;
|
|
}
|
|
mGrallocModule = (gralloc_module_t*)(handle->priv);
|
|
|
|
mem = (cam_mem_info_t*)malloc(sizeof(cam_mem_info_t));
|
|
if (!mem) {
|
|
LOGE("can't alloc cam_mem_info_t!");
|
|
goto error_alloc;
|
|
}
|
|
halPixFmt = HAL_PIXEL_FORMAT_RGB_565;
|
|
// use rgb565 format to alloce buffer size, so size should be divided 2
|
|
|
|
grallocFlags = handle->flag;
|
|
mgraphicbuf = new GraphicBuffer(size/2, 1, halPixFmt,grallocFlags);
|
|
mgraphicbuf->incStrong(mgraphicbuf);
|
|
if (mgraphicbuf->initCheck()) {
|
|
LOGE("GraphicBuffer error : %s", strerror(errno));
|
|
goto error_alloc;
|
|
}
|
|
|
|
ret = mgraphicbuf->lock(grallocFlags, (void**)&mem_addr);
|
|
if (ret) {
|
|
LOGE("lock buffer error : %s", strerror(errno));
|
|
goto lock_error;
|
|
}
|
|
mgraphicbuf->unlock();
|
|
ret = mGrallocModule->perform(
|
|
mGrallocModule,
|
|
GRALLOC_MODULE_PERFORM_GET_HADNLE_PRIME_FD,
|
|
mgraphicbuf->handle,
|
|
&mem->fd);
|
|
if (ret) {
|
|
LOGE("get handle error : %s", strerror(errno));
|
|
goto lock_error;
|
|
}
|
|
|
|
mem->vir_addr = (unsigned long)mem_addr;
|
|
mem->handlle = handle;
|
|
mem->iommu_maped = 0;
|
|
mem->mmu_addr = 0;
|
|
mem->phy_addr = 0;
|
|
mem->size = size;
|
|
mem->priv = (void*)(mgraphicbuf);
|
|
|
|
LOGD("alloc graphic buffer sucess,mem %p, vir_addr %p, fd %d",
|
|
mem, mem_addr, mem->fd);
|
|
|
|
return mem;
|
|
lock_error:
|
|
//delete mgraphicbuf;
|
|
mgraphicbuf->decStrong(mgraphicbuf);
|
|
mgraphicbuf = NULL;
|
|
error_alloc:
|
|
if (mem)
|
|
free(mem);
|
|
return NULL;
|
|
}
|
|
|
|
//free
|
|
static int cam_mem_gralloc_ops_free(
|
|
cam_mem_handle_t* handle, cam_mem_info_t* mem)
|
|
{
|
|
int ret = 0;
|
|
GraphicBuffer* mgraphicbuf;
|
|
|
|
if (!handle || !mem) {
|
|
LOGE("invalid ion mem handle!");
|
|
return -1;
|
|
}
|
|
|
|
if (mem->iommu_maped) {
|
|
LOGE("ion mem is mmumaped, should be unmapped firstly!");
|
|
return -1;
|
|
}
|
|
mgraphicbuf = (GraphicBuffer*)(mem->priv);
|
|
mgraphicbuf->decStrong(mgraphicbuf);
|
|
free(mem);
|
|
|
|
return ret;
|
|
}
|
|
|
|
//flush cache
|
|
static int cam_mem_gralloc_ops_flush_cache(
|
|
cam_mem_handle_t* handle, cam_mem_info_t* mem)
|
|
{
|
|
struct dma_buf_sync sync_args;
|
|
int ret = 0;
|
|
void* mem_addr;
|
|
|
|
GraphicBuffer* mgraphicbuf = (GraphicBuffer*)(mem->priv);
|
|
if (!handle || !mem) {
|
|
LOGE("invalid ion mem handle!");
|
|
return -1;
|
|
}
|
|
|
|
ret = mgraphicbuf->lock(handle->flag, (void**)&mem_addr);
|
|
if (ret) {
|
|
LOGE("lock buffer error : %s",strerror(errno));
|
|
return -1;
|
|
}
|
|
|
|
sync_args.flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
|
|
ret = ioctl(mem->fd, DMA_BUF_IOCTL_SYNC, &sync_args);
|
|
if (ret != 0)
|
|
LOGE("ret %d ,DMA_BUF_IOCTL_SYNC failed!", ret);
|
|
mgraphicbuf->unlock();
|
|
|
|
return ret;
|
|
}
|
|
|
|
//deinit
|
|
static int cam_mem_gralloc_ops_deInit(cam_mem_handle_t* handle)
|
|
{
|
|
int ret = 0;
|
|
|
|
if (!handle) {
|
|
LOGE("invalid ion mem handle!");
|
|
return -1;
|
|
}
|
|
free(handle);
|
|
|
|
return ret;
|
|
}
|
|
|
|
cam_mem_ops_t g_rk_gralloc_mem_ops {
|
|
//init
|
|
.init = cam_mem_gralloc_ops_init,
|
|
//alloc
|
|
.alloc = cam_mem_gralloc_ops_alloc,
|
|
//free
|
|
.free = cam_mem_gralloc_ops_free,
|
|
//flush cache
|
|
.flush_cache = cam_mem_gralloc_ops_flush_cache,
|
|
//deinit
|
|
.deInit = cam_mem_gralloc_ops_deInit,
|
|
};
|
|
|
|
static struct cam_mem_ops_des_s cam_mem_ops_array[] = {
|
|
{"ion",CAM_MEM_TYPE_ION,NULL},
|
|
{"ionDma",CAM_MEM_TYPE_IONDMA,NULL},
|
|
{"gralloc",CAM_MEM_TYPE_GRALLOC,&g_rk_gralloc_mem_ops},
|
|
};
|
|
|
|
cam_mem_ops_t* get_cam_ops(enum cam_mem_type_e mem_type)
|
|
{
|
|
int ops_index = -1;
|
|
switch(mem_type) {
|
|
case CAM_MEM_TYPE_ION:
|
|
ops_index = 0;
|
|
break;
|
|
case CAM_MEM_TYPE_IONDMA:
|
|
ops_index = 1;
|
|
break;
|
|
case CAM_MEM_TYPE_GRALLOC:
|
|
ops_index = 2;
|
|
break;
|
|
default:
|
|
ops_index = -1;
|
|
break;
|
|
}
|
|
|
|
if (ops_index != -1)
|
|
return cam_mem_ops_array[ops_index].ops;
|
|
else
|
|
return NULL;
|
|
}
|
|
|