refactor[allocator]: Refactor allocator flow

1. Allocator api is determined by buffer type.
2. Allocator ctx is determined by both buffer type and buffer flags.
3. All allocator dma_heap / drm / ion / ext_dma should support different
buffer flags.
4. The buffer flag supports cacheable / 32-bit / contig options.
5. Add flags update flow on allocator create process.
6. Add mpp_dmabuf_has_partial_ops to disable dmabuf partial ops when the
kernel driver has bug.

Signed-off-by: Herman Chen <herman.chen@rock-chips.com>
Change-Id: If36a05c6704112cad3ab46861023597ff02bf14c
This commit is contained in:
Herman Chen
2023-11-21 18:14:13 +08:00
parent 630bcb9000
commit 6ce3007994
23 changed files with 337 additions and 444 deletions

View File

@@ -119,12 +119,12 @@ struct MppBufferGroupImpl_t {
/* parameter store for MppBuffer */ /* parameter store for MppBuffer */
MppAllocator allocator; MppAllocator allocator;
MppAllocatorApi *alloc_api; MppAllocatorApi *alloc_api;
MppAllocFlagType flags;
RK_U32 log_runtime_en; RK_U32 log_runtime_en;
RK_U32 log_history_en; RK_U32 log_history_en;
RK_U32 group_id; RK_U32 group_id;
MppBufferMode mode; MppBufferMode mode;
MppBufferType type; MppBufferType type;
RK_U32 type_flags;
/* group status flag */ /* group status flag */
// buffer force clear mode flag // buffer force clear mode flag

View File

@@ -400,7 +400,7 @@ MPP_RET mpp_buffer_create(const char *tag, const char *caller,
p->group_id = group->group_id; p->group_id = group->group_id;
p->mode = group->mode; p->mode = group->mode;
p->type = group->type; p->type = group->type;
p->uncached = (group->type_flags & MPP_BUFFER_FLAGS_CACHABLE) ? 0 : 1; p->uncached = (group->flags & MPP_ALLOC_FLAG_CACHABLE) ? 0 : 1;
p->logs = group->logs; p->logs = group->logs;
p->info = *info; p->info = *info;
@@ -770,6 +770,8 @@ MppBufferService::MppBufferService()
INIT_LIST_HEAD(&mListGroup); INIT_LIST_HEAD(&mListGroup);
INIT_LIST_HEAD(&mListOrphan); INIT_LIST_HEAD(&mListOrphan);
mpp_env_get_u32("mpp_buffer_debug", &mpp_buffer_debug, 0);
// NOTE: Do not create misc group at beginning. Only create on when needed. // NOTE: Do not create misc group at beginning. Only create on when needed.
for (i = 0; i < MPP_BUFFER_MODE_BUTT; i++) for (i = 0; i < MPP_BUFFER_MODE_BUTT; i++)
for (j = 0; j < MPP_BUFFER_TYPE_BUTT; j++) for (j = 0; j < MPP_BUFFER_TYPE_BUTT; j++)
@@ -869,20 +871,65 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
RK_U32 is_misc) RK_U32 is_misc)
{ {
MppBufferType buffer_type = (MppBufferType)(type & MPP_BUFFER_TYPE_MASK); MppBufferType buffer_type = (MppBufferType)(type & MPP_BUFFER_TYPE_MASK);
RK_U32 flags = (type & MPP_BUFFER_FLAGS_MASK); MppBufferGroupImpl *p = NULL;
RK_U32 allocator_idx = 0; RK_U32 flag = MPP_ALLOC_FLAG_NONE;
MppBufferGroupImpl *p = (MppBufferGroupImpl *)mpp_mem_pool_get_f(caller, mpp_buf_grp_pool);
if (NULL == p) { /* env update */
mpp_env_get_u32("mpp_buffer_debug", &mpp_buffer_debug, mpp_buffer_debug);
if (mode >= MPP_BUFFER_MODE_BUTT || buffer_type >= MPP_BUFFER_TYPE_BUTT) {
mpp_err("MppBufferService get_group found invalid mode %d type %x\n", mode, type);
return NULL;
}
p = (MppBufferGroupImpl *)mpp_mem_pool_get_f(caller, mpp_buf_grp_pool);
if (!p) {
mpp_err("MppBufferService failed to allocate group context\n"); mpp_err("MppBufferService failed to allocate group context\n");
return NULL; return NULL;
} }
if (type & MPP_BUFFER_FLAGS_DMA32)
flag += MPP_ALLOC_FLAG_DMA32;
if (type & MPP_BUFFER_FLAGS_CACHABLE)
flag += MPP_ALLOC_FLAG_CACHABLE;
if (type & MPP_BUFFER_FLAGS_CONTIG)
flag += MPP_ALLOC_FLAG_CMA;
p->flags = (MppAllocFlagType)flag;
{
AutoMutex auto_lock(get_lock());
MppAllocator allocator = NULL;
MppAllocatorApi *alloc_api = NULL;
allocator = mAllocator[buffer_type][flag];
alloc_api = mAllocatorApi[buffer_type];
// allocate general buffer first
if (!allocator) {
mpp_allocator_get(&allocator, &alloc_api, type, p->flags);
mAllocator[buffer_type][flag] = allocator;
mAllocatorApi[buffer_type] = alloc_api;
}
p->allocator = allocator;
p->alloc_api = alloc_api;
p->flags = mpp_allocator_get_flags(allocator);
}
if (!p->allocator || !p->alloc_api) {
mpp_mem_pool_put_f(caller, mpp_buf_grp_pool, p);
mpp_err("MppBufferService get_group failed to get allocater with mode %d type %x\n", mode, type);
return NULL;
}
INIT_LIST_HEAD(&p->list_group); INIT_LIST_HEAD(&p->list_group);
INIT_LIST_HEAD(&p->list_used); INIT_LIST_HEAD(&p->list_used);
INIT_LIST_HEAD(&p->list_unused); INIT_LIST_HEAD(&p->list_unused);
INIT_HLIST_NODE(&p->hlist); INIT_HLIST_NODE(&p->hlist);
mpp_env_get_u32("mpp_buffer_debug", &mpp_buffer_debug, 0);
p->log_runtime_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_RUNTIME) ? (1) : (0); p->log_runtime_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_RUNTIME) ? (1) : (0);
p->log_history_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_HISTORY) ? (1) : (0); p->log_history_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_HISTORY) ? (1) : (0);
@@ -890,7 +937,6 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
p->mode = mode; p->mode = mode;
p->type = buffer_type; p->type = buffer_type;
p->limit = BUFFER_GROUP_SIZE_DEFAULT; p->limit = BUFFER_GROUP_SIZE_DEFAULT;
p->type_flags = flags;
p->clear_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_CLR_ON_EXIT) ? (1) : (0); p->clear_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_CLR_ON_EXIT) ? (1) : (0);
p->dump_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_DUMP_ON_EXIT) ? (1) : (0); p->dump_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_DUMP_ON_EXIT) ? (1) : (0);
@@ -900,35 +946,9 @@ MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *cal
pthread_mutex_init(&p->buf_lock, &attr); pthread_mutex_init(&p->buf_lock, &attr);
pthread_mutexattr_destroy(&attr); pthread_mutexattr_destroy(&attr);
{
AutoMutex auto_lock(get_lock());
if (flags & MPP_BUFFER_FLAGS_CONTIG)
allocator_idx |= 1 << 0;
if (flags & MPP_BUFFER_FLAGS_CACHABLE)
allocator_idx |= 1 << 1;
if (flags & MPP_BUFFER_FLAGS_DMA32)
allocator_idx |= 1 << 2;
// allocate general buffer first
if (!mAllocator[buffer_type][allocator_idx])
mpp_allocator_get(&mAllocator[buffer_type][allocator_idx], &mAllocatorApi[buffer_type], type);
p->allocator = mAllocator[buffer_type][allocator_idx];
p->alloc_api = mAllocatorApi[buffer_type];
}
mpp_assert(p->allocator);
mpp_assert(p->alloc_api);
if (p->log_history_en) if (p->log_history_en)
p->logs = buf_logs_init(BUFFER_OPS_MAX_COUNT); p->logs = buf_logs_init(BUFFER_OPS_MAX_COUNT);
mpp_assert(mode < MPP_BUFFER_MODE_BUTT);
mpp_assert(buffer_type < MPP_BUFFER_TYPE_BUTT);
AutoMutex auto_lock(get_lock()); AutoMutex auto_lock(get_lock());
RK_U32 id = get_group_id(); RK_U32 id = get_group_id();

View File

@@ -123,7 +123,7 @@ int main()
mpp_log("mpp_buffer_test commit mode with used status start\n"); mpp_log("mpp_buffer_test commit mode with used status start\n");
ret = mpp_allocator_get(&allocator, &api, MPP_BUFFER_TYPE_ION); ret = mpp_allocator_get(&allocator, &api, MPP_BUFFER_TYPE_ION, 0);
if (MPP_OK != ret) { if (MPP_OK != ret) {
mpp_err("mpp_buffer_test mpp_allocator_get ion failed\n"); mpp_err("mpp_buffer_test mpp_allocator_get ion failed\n");
goto MPP_BUFFER_failed; goto MPP_BUFFER_failed;

View File

@@ -56,15 +56,12 @@ add_library(osal STATIC
osal_2str.c osal_2str.c
# Those files have a compiler marco protection, so only target # Those files have a compiler marco protection, so only target
# OS will be built # OS will be built
android/os_allocator.c
android/os_mem.c android/os_mem.c
android/os_env.c android/os_env.c
android/os_log.c android/os_log.c
linux/os_allocator.c
linux/os_mem.c linux/os_mem.c
linux/os_env.c linux/os_env.c
linux/os_log.cpp linux/os_log.cpp
windows/os_allocator.c
windows/os_mem.c windows/os_mem.c
windows/os_env.c windows/os_env.c
windows/os_log.c windows/os_log.c

View File

@@ -68,29 +68,21 @@ typedef struct {
RK_U32 flags; RK_U32 flags;
} allocator_ctx_dmaheap; } allocator_ctx_dmaheap;
typedef enum DmaHeapType_e {
DMA_HEAP_CACHABLE = (1 << 0),
DMA_HEAP_DMA32 = (1 << 1),
DMA_HEAP_CMA = (1 << 2),
DMA_HEAP_TYPE_MASK = DMA_HEAP_CMA | DMA_HEAP_CACHABLE | DMA_HEAP_DMA32,
DMA_HEAP_TYPE_NB,
} DmaHeapType;
typedef struct DmaHeapInfo_t { typedef struct DmaHeapInfo_t {
const char *name; const char *name;
RK_S32 fd; RK_S32 fd;
RK_U32 flags; RK_U32 flags;
} DmaHeapInfo; } DmaHeapInfo;
static DmaHeapInfo heap_infos[DMA_HEAP_TYPE_NB] = { static DmaHeapInfo heap_infos[MPP_ALLOC_FLAG_TYPE_NB] = {
{ "system-uncached", -1, 0, }, /* 0 */ { "system-uncached", -1, MPP_ALLOC_FLAG_NONE , }, /* 0 */
{ "system-uncached-dma32", -1, DMA_HEAP_DMA32, }, /* 1 */ { "system-uncached-dma32", -1, MPP_ALLOC_FLAG_DMA32, }, /* 1 */
{ "system", -1, DMA_HEAP_CACHABLE , }, /* 2 */ { "system", -1, MPP_ALLOC_FLAG_CACHABLE , }, /* 2 */
{ "system-dma32", -1, DMA_HEAP_CACHABLE | DMA_HEAP_DMA32, }, /* 3 */ { "system-dma32", -1, MPP_ALLOC_FLAG_CACHABLE | MPP_ALLOC_FLAG_DMA32, }, /* 3 */
{ "cma-uncached", -1, DMA_HEAP_CMA , }, /* 4 */ { "cma-uncached", -1, MPP_ALLOC_FLAG_CMA , }, /* 4 */
{ "cma-uncached-dma32", -1, DMA_HEAP_CMA | DMA_HEAP_DMA32, }, /* 5 */ { "cma-uncached-dma32", -1, MPP_ALLOC_FLAG_CMA | MPP_ALLOC_FLAG_DMA32, }, /* 5 */
{ "cma", -1, DMA_HEAP_CMA | DMA_HEAP_CACHABLE , }, /* 6 */ { "cma", -1, MPP_ALLOC_FLAG_CMA | MPP_ALLOC_FLAG_CACHABLE , }, /* 6 */
{ "cma-dma32", -1, DMA_HEAP_CMA | DMA_HEAP_CACHABLE | DMA_HEAP_DMA32, }, /* 7 */ { "cma-dma32", -1, MPP_ALLOC_FLAG_CMA | MPP_ALLOC_FLAG_CACHABLE | MPP_ALLOC_FLAG_DMA32, }, /* 7 */
}; };
static int try_open_path(const char *name) static int try_open_path(const char *name)
@@ -107,16 +99,16 @@ static int try_open_path(const char *name)
return fd; return fd;
} }
static MPP_RET try_flip_flag(DmaHeapType orig, DmaHeapType flag) static MPP_RET try_flip_flag(RK_U32 orig, RK_U32 flag)
{ {
DmaHeapInfo *dst = &heap_infos[orig]; DmaHeapInfo *dst = &heap_infos[orig];
DmaHeapInfo *src; DmaHeapInfo *src;
DmaHeapType used; RK_U32 used;
if (orig & flag) if (orig & flag)
used = (DmaHeapType)(orig & (~flag)); used = (RK_U32)(orig & (~flag));
else else
used = (DmaHeapType)(orig | flag); used = (RK_U32)(orig | flag);
src = &heap_infos[used]; src = &heap_infos[used];
if (src->fd > 0) { if (src->fd > 0) {
@@ -141,7 +133,7 @@ void dma_heap_init(void)
mpp_env_get_u32("dma_heap_debug", &dma_heap_debug, 0); mpp_env_get_u32("dma_heap_debug", &dma_heap_debug, 0);
/* go through all heap first */ /* go through all heap first */
for (i = 0; i < DMA_HEAP_TYPE_NB; i++) { for (i = 0; i < MPP_ARRAY_ELEMS(heap_infos); i++) {
info = &heap_infos[i]; info = &heap_infos[i];
if (info->fd > 0) if (info->fd > 0)
@@ -154,22 +146,22 @@ void dma_heap_init(void)
if (!all_success) { if (!all_success) {
/* check remaining failed heap mapping */ /* check remaining failed heap mapping */
for (i = 0; i < DMA_HEAP_TYPE_NB; i++) { for (i = 0; i < MPP_ARRAY_ELEMS(heap_infos); i++) {
info = &heap_infos[i]; info = &heap_infos[i];
if (info->fd > 0) if (info->fd > 0)
continue; continue;
/* if original heap failed then try revert cacheable flag */ /* if original heap failed then try revert cacheable flag */
if (MPP_OK == try_flip_flag((DmaHeapType)i, DMA_HEAP_CACHABLE)) if (MPP_OK == try_flip_flag((RK_U32)i, MPP_ALLOC_FLAG_CACHABLE))
continue; continue;
/* if cacheable heap failed then try revert dma32 flag */ /* if cacheable heap failed then try revert dma32 flag */
if (MPP_OK == try_flip_flag((DmaHeapType)i, DMA_HEAP_DMA32)) if (MPP_OK == try_flip_flag((RK_U32)i, MPP_ALLOC_FLAG_DMA32))
continue; continue;
/* if dma32 heap failed then try revert both cacheable and dma32 flag */ /* if dma32 heap failed then try revert both cacheable and dma32 flag */
if (MPP_OK == try_flip_flag((DmaHeapType)i, DMA_HEAP_CACHABLE | DMA_HEAP_DMA32)) if (MPP_OK == try_flip_flag((RK_U32)i, MPP_ALLOC_FLAG_CACHABLE | MPP_ALLOC_FLAG_DMA32))
continue; continue;
dma_heap_dbg_chk("dma-heap type %x - %s remap failed\n", i, info->name); dma_heap_dbg_chk("dma-heap type %x - %s remap failed\n", i, info->name);
@@ -182,7 +174,7 @@ void dma_heap_deinit(void)
{ {
RK_U32 i; RK_U32 i;
for (i = 0; i < DMA_HEAP_TYPE_NB; i++) { for (i = 0; i < MPP_ARRAY_ELEMS(heap_infos); i++) {
DmaHeapInfo *info = &heap_infos[i]; DmaHeapInfo *info = &heap_infos[i];
if (info->fd > 0) { if (info->fd > 0) {
@@ -216,11 +208,11 @@ static int dma_heap_alloc(int fd, size_t len, RK_S32 *dmabuf_fd, RK_U32 flags)
return ret; return ret;
} }
static MPP_RET os_allocator_dma_heap_open(void **ctx, MppAllocatorCfg *cfg) static MPP_RET os_allocator_dma_heap_open(void **ctx, size_t alignment, MppAllocFlagType flags)
{ {
allocator_ctx_dmaheap *p; allocator_ctx_dmaheap *p;
DmaHeapInfo *info = NULL; DmaHeapInfo *info = NULL;
DmaHeapType type = 0; RK_U32 type = 0;
mpp_env_get_u32("dma_heap_debug", &dma_heap_debug, dma_heap_debug); mpp_env_get_u32("dma_heap_debug", &dma_heap_debug, dma_heap_debug);
@@ -231,16 +223,7 @@ static MPP_RET os_allocator_dma_heap_open(void **ctx, MppAllocatorCfg *cfg)
*ctx = NULL; *ctx = NULL;
if (cfg->flags & (MPP_BUFFER_FLAGS_CONTIG >> 16)) info = &heap_infos[flags];
type |= DMA_HEAP_CMA;
if (cfg->flags & (MPP_BUFFER_FLAGS_CACHABLE >> 16))
type |= DMA_HEAP_CACHABLE;
if (cfg->flags & (MPP_BUFFER_FLAGS_DMA32 >> 16))
type |= DMA_HEAP_DMA32;
info = &heap_infos[type];
if (info->fd <= 0) { if (info->fd <= 0) {
mpp_err_f("open dma heap type %x %s failed!\n", type, info->name); mpp_err_f("open dma heap type %x %s failed!\n", type, info->name);
return MPP_ERR_UNKNOW; return MPP_ERR_UNKNOW;
@@ -251,27 +234,13 @@ static MPP_RET os_allocator_dma_heap_open(void **ctx, MppAllocatorCfg *cfg)
mpp_err_f("failed to allocate context\n"); mpp_err_f("failed to allocate context\n");
return MPP_ERR_MALLOC; return MPP_ERR_MALLOC;
} else { } else {
p->alignment = cfg->alignment; p->alignment = alignment;
p->flags = info->flags; p->flags = info->flags;
p->device = info->fd; p->device = info->fd;
*ctx = p; *ctx = p;
} }
dma_heap_dbg_ops("dev %d open heap type %x:%x\n", p->device, cfg->flags, info->flags); dma_heap_dbg_ops("dev %d open heap type %x:%x\n", p->device, flags, info->flags);
if (type != info->flags) {
type = cfg->flags;
/* update read dma_heap back to config */
if (info->flags & DMA_HEAP_CACHABLE)
cfg->flags |= (MPP_BUFFER_FLAGS_CACHABLE >> 16);
else
cfg->flags &= ~(MPP_BUFFER_FLAGS_CACHABLE >> 16);
if (info->flags & DMA_HEAP_DMA32)
cfg->flags |= (MPP_BUFFER_FLAGS_DMA32 >> 16);
else
cfg->flags &= ~(MPP_BUFFER_FLAGS_DMA32 >> 16);
}
return MPP_OK; return MPP_OK;
} }
@@ -389,6 +358,13 @@ static MPP_RET os_allocator_dma_heap_mmap(void *ctx, MppBufferInfo *data)
return ret; return ret;
} }
static MppAllocFlagType os_allocator_dma_heap_flags(void *ctx)
{
allocator_ctx_dmaheap *p = (allocator_ctx_dmaheap *)ctx;
return p ? (MppAllocFlagType)p->flags : MPP_ALLOC_FLAG_NONE;
}
os_allocator allocator_dma_heap = { os_allocator allocator_dma_heap = {
.type = MPP_BUFFER_TYPE_DMA_HEAP, .type = MPP_BUFFER_TYPE_DMA_HEAP,
.open = os_allocator_dma_heap_open, .open = os_allocator_dma_heap_open,
@@ -398,4 +374,5 @@ os_allocator allocator_dma_heap = {
.import = os_allocator_dma_heap_import, .import = os_allocator_dma_heap_import,
.release = os_allocator_dma_heap_free, .release = os_allocator_dma_heap_free,
.mmap = os_allocator_dma_heap_mmap, .mmap = os_allocator_dma_heap_mmap,
.flags = os_allocator_dma_heap_flags,
}; };

View File

@@ -17,7 +17,7 @@
#ifndef __ALLOCATOR_DMA_HEAP_H__ #ifndef __ALLOCATOR_DMA_HEAP_H__
#define __ALLOCATOR_DMA_HEAP_H__ #define __ALLOCATOR_DMA_HEAP_H__
#include "os_allocator.h" #include "mpp_allocator_api.h"
extern os_allocator allocator_dma_heap; extern os_allocator allocator_dma_heap;

View File

@@ -39,11 +39,30 @@ static RK_U32 drm_debug = 0;
#define DRM_FUNCTION (0x00000001) #define DRM_FUNCTION (0x00000001)
#define DRM_DEVICE (0x00000002) #define DRM_DEVICE (0x00000002)
#define DRM_CLIENT (0x00000004) #define DRM_IOCTL (0x00000004)
#define DRM_IOCTL (0x00000008)
#define drm_dbg(flag, fmt, ...) _mpp_dbg_f(drm_debug, flag, fmt, ## __VA_ARGS__) #define drm_dbg(flag, fmt, ...) _mpp_dbg_f(drm_debug, flag, fmt, ## __VA_ARGS__)
#define drm_dbg_func(fmt, ...) drm_dbg(DRM_FUNCTION, fmt, ## __VA_ARGS__) #define drm_dbg_func(fmt, ...) drm_dbg(DRM_FUNCTION, fmt, ## __VA_ARGS__)
#define drm_dbg_dev(fmt, ...) drm_dbg(DRM_DEVICE, fmt, ## __VA_ARGS__)
#define drm_dbg_ioctl(fmt, ...) drm_dbg(DRM_IOCTL, fmt, ## __VA_ARGS__)
/* memory type definitions. */
enum drm_rockchip_gem_mem_type {
/* Physically Continuous memory. */
ROCKCHIP_BO_CONTIG = 1 << 0,
/* cachable mapping. */
ROCKCHIP_BO_CACHABLE = 1 << 1,
/* write-combine mapping. */
ROCKCHIP_BO_WC = 1 << 2,
ROCKCHIP_BO_SECURE = 1 << 3,
/* keep kmap for cma buffer or alloc kmap for other type memory */
ROCKCHIP_BO_ALLOC_KMAP = 1 << 4,
/* alloc page with gfp_dma32 */
ROCKCHIP_BO_DMA32 = 1 << 5,
ROCKCHIP_BO_MASK = ROCKCHIP_BO_CONTIG | ROCKCHIP_BO_CACHABLE |
ROCKCHIP_BO_WC | ROCKCHIP_BO_SECURE | ROCKCHIP_BO_ALLOC_KMAP |
ROCKCHIP_BO_DMA32,
};
typedef struct { typedef struct {
RK_U32 alignment; RK_U32 alignment;
@@ -53,6 +72,22 @@ typedef struct {
static const char *dev_drm = "/dev/dri/card0"; static const char *dev_drm = "/dev/dri/card0";
static RK_U32 to_rockchip_gem_mem_flag(RK_U32 flags)
{
RK_U32 ret = 0;
if (flags & MPP_ALLOC_FLAG_DMA32)
ret |= ROCKCHIP_BO_DMA32;
if (flags & MPP_ALLOC_FLAG_CACHABLE)
ret |= ROCKCHIP_BO_CACHABLE;
if (flags & MPP_ALLOC_FLAG_CMA)
ret |= ROCKCHIP_BO_CONTIG;
return ret;
}
static int drm_ioctl(int fd, int req, void *arg) static int drm_ioctl(int fd, int req, void *arg)
{ {
int ret; int ret;
@@ -61,8 +96,7 @@ static int drm_ioctl(int fd, int req, void *arg)
ret = ioctl(fd, req, arg); ret = ioctl(fd, req, arg);
} while (ret == -1 && (errno == EINTR || errno == EAGAIN)); } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
drm_dbg(DRM_IOCTL, "%x with code %d: %s\n", req, drm_dbg_ioctl("%x ret %d: %s\n", req, ret, strerror(errno));
ret, strerror(errno));
return ret; return ret;
} }
@@ -86,7 +120,7 @@ static int drm_handle_to_fd(int fd, RK_U32 handle, int *map_fd, RK_U32 flags)
*map_fd = dph.fd; *map_fd = dph.fd;
drm_dbg_func("dev %d handle %d get fd %d\n", fd, handle, *map_fd); drm_dbg_func("dev %d handle %d flags %x get fd %d\n", fd, handle, dph.flags, *map_fd);
if (*map_fd < 0) { if (*map_fd < 0) {
mpp_err_f("map ioctl returned negative fd\n"); mpp_err_f("map ioctl returned negative fd\n");
@@ -105,7 +139,7 @@ static int drm_alloc(int fd, size_t len, size_t align, RK_U32 *handle, RK_U32 fl
dmcb.bpp = 8; dmcb.bpp = 8;
dmcb.width = (len + align - 1) & (~(align - 1)); dmcb.width = (len + align - 1) & (~(align - 1));
dmcb.height = 1; dmcb.height = 1;
dmcb.flags = flags; dmcb.flags = to_rockchip_gem_mem_flag(flags);
if (handle == NULL) if (handle == NULL)
return -EINVAL; return -EINVAL;
@@ -115,8 +149,8 @@ static int drm_alloc(int fd, size_t len, size_t align, RK_U32 *handle, RK_U32 fl
return ret; return ret;
*handle = dmcb.handle; *handle = dmcb.handle;
drm_dbg_func("dev %d alloc aligned %d handle %d size %lld\n", fd, drm_dbg_func("dev %d alloc aligned %d flags %x handle %d size %lld\n", fd,
align, dmcb.handle, dmcb.size); align, dmcb.flags, dmcb.handle, dmcb.size);
return ret; return ret;
} }
@@ -129,13 +163,11 @@ static int drm_free(int fd, RK_U32 handle)
return drm_ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &data); return drm_ioctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &data);
} }
static MPP_RET os_allocator_drm_open(void **ctx, MppAllocatorCfg *cfg) static MPP_RET os_allocator_drm_open(void **ctx, size_t alignment, MppAllocFlagType flags)
{ {
RK_S32 fd; RK_S32 fd;
allocator_ctx_drm *p; allocator_ctx_drm *p;
drm_dbg_func("enter\n");
if (NULL == ctx) { if (NULL == ctx) {
mpp_err_f("does not accept NULL input\n"); mpp_err_f("does not accept NULL input\n");
return MPP_ERR_NULL_PTR; return MPP_ERR_NULL_PTR;
@@ -151,7 +183,7 @@ static MPP_RET os_allocator_drm_open(void **ctx, MppAllocatorCfg *cfg)
return MPP_ERR_UNKNOW; return MPP_ERR_UNKNOW;
} }
drm_dbg(DRM_DEVICE, "open drm dev fd %d\n", fd); drm_dbg_dev("open drm dev fd %d flags %x\n", fd, flags);
p = mpp_malloc(allocator_ctx_drm, 1); p = mpp_malloc(allocator_ctx_drm, 1);
if (NULL == p) { if (NULL == p) {
@@ -162,14 +194,12 @@ static MPP_RET os_allocator_drm_open(void **ctx, MppAllocatorCfg *cfg)
/* /*
* default drm use cma, do nothing here * default drm use cma, do nothing here
*/ */
p->alignment = cfg->alignment; p->alignment = alignment;
p->flags = cfg->flags; p->flags = flags;
p->drm_device = fd; p->drm_device = fd;
*ctx = p; *ctx = p;
} }
drm_dbg_func("leave dev %d\n", fd);
return MPP_OK; return MPP_OK;
} }
@@ -321,6 +351,13 @@ static MPP_RET os_allocator_drm_mmap(void *ctx, MppBufferInfo *data)
return ret; return ret;
} }
static MppAllocFlagType os_allocator_drm_flags(void *ctx)
{
allocator_ctx_drm *p = (allocator_ctx_drm *)ctx;
return p ? (MppAllocFlagType)p->flags : MPP_ALLOC_FLAG_NONE;
}
os_allocator allocator_drm = { os_allocator allocator_drm = {
.type = MPP_BUFFER_TYPE_DRM, .type = MPP_BUFFER_TYPE_DRM,
.open = os_allocator_drm_open, .open = os_allocator_drm_open,
@@ -330,4 +367,5 @@ os_allocator allocator_drm = {
.import = os_allocator_drm_import, .import = os_allocator_drm_import,
.release = os_allocator_drm_free, .release = os_allocator_drm_free,
.mmap = os_allocator_drm_mmap, .mmap = os_allocator_drm_mmap,
.flags = os_allocator_drm_flags,
}; };

View File

@@ -17,7 +17,7 @@
#ifndef __ALLOCATOR_DRM_H__ #ifndef __ALLOCATOR_DRM_H__
#define __ALLOCATOR_DRM_H__ #define __ALLOCATOR_DRM_H__
#include "os_allocator.h" #include "mpp_allocator_api.h"
extern os_allocator allocator_drm; extern os_allocator allocator_drm;

View File

@@ -24,9 +24,10 @@
typedef struct { typedef struct {
size_t alignment; size_t alignment;
MppAllocFlagType flags;
} allocator_ctx; } allocator_ctx;
static MPP_RET allocator_ext_dma_open(void **ctx, MppAllocatorCfg *cfg) static MPP_RET allocator_ext_dma_open(void **ctx, size_t alignment, MppAllocFlagType flags)
{ {
MPP_RET ret = MPP_OK; MPP_RET ret = MPP_OK;
allocator_ctx *p = NULL; allocator_ctx *p = NULL;
@@ -41,7 +42,8 @@ static MPP_RET allocator_ext_dma_open(void **ctx, MppAllocatorCfg *cfg)
mpp_err_f("failed to allocate context\n"); mpp_err_f("failed to allocate context\n");
ret = MPP_ERR_MALLOC; ret = MPP_ERR_MALLOC;
} else { } else {
p->alignment = cfg->alignment; p->alignment = alignment;
p->flags = flags;
} }
*ctx = p; *ctx = p;
@@ -134,6 +136,13 @@ static MPP_RET allocator_ext_dma_close(void *ctx)
return MPP_ERR_VALUE; return MPP_ERR_VALUE;
} }
static MppAllocFlagType os_allocator_ext_dma_flags(void *ctx)
{
allocator_ctx *p = (allocator_ctx *)ctx;
return p ? (MppAllocFlagType)p->flags : MPP_ALLOC_FLAG_NONE;
}
os_allocator allocator_ext_dma = { os_allocator allocator_ext_dma = {
.type = MPP_BUFFER_TYPE_EXT_DMA, .type = MPP_BUFFER_TYPE_EXT_DMA,
.open = allocator_ext_dma_open, .open = allocator_ext_dma_open,
@@ -143,4 +152,5 @@ os_allocator allocator_ext_dma = {
.import = allocator_ext_dma_import, .import = allocator_ext_dma_import,
.release = allocator_ext_dma_release, .release = allocator_ext_dma_release,
.mmap = allocator_ext_dma_mmap, .mmap = allocator_ext_dma_mmap,
.flags = os_allocator_ext_dma_flags,
}; };

View File

@@ -17,7 +17,7 @@
#ifndef __ALLOCATOR_EXT_DMA_H__ #ifndef __ALLOCATOR_EXT_DMA_H__
#define __ALLOCATOR_EXT_DMA_H__ #define __ALLOCATOR_EXT_DMA_H__
#include "os_allocator.h" #include "mpp_allocator_api.h"
extern os_allocator allocator_ext_dma; extern os_allocator allocator_ext_dma;

View File

@@ -272,8 +272,9 @@ static RK_S32 check_sysfs_iommu()
} }
typedef struct { typedef struct {
RK_U32 alignment; size_t alignment;
RK_S32 ion_device; RK_S32 ion_device;
MppAllocFlagType flags;
} allocator_ctx_ion; } allocator_ctx_ion;
static const char *dev_ion = "/dev/ion"; static const char *dev_ion = "/dev/ion";
@@ -281,7 +282,7 @@ static RK_S32 ion_heap_id = -1;
static RK_U32 ion_heap_mask = (1 << ION_HEAP_TYPE_SYSTEM); static RK_U32 ion_heap_mask = (1 << ION_HEAP_TYPE_SYSTEM);
static pthread_mutex_t lock; static pthread_mutex_t lock;
static MPP_RET allocator_ion_open(void **ctx, MppAllocatorCfg *cfg) static MPP_RET allocator_ion_open(void **ctx, size_t alignment, MppAllocFlagType flags)
{ {
RK_S32 fd; RK_S32 fd;
allocator_ctx_ion *p; allocator_ctx_ion *p;
@@ -343,7 +344,8 @@ static MPP_RET allocator_ion_open(void **ctx, MppAllocatorCfg *cfg)
mpp_log("using ion heap %s\n", heap_name); mpp_log("using ion heap %s\n", heap_name);
} }
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
p->alignment = cfg->alignment; p->alignment = alignment;
p->flags = flags;
p->ion_device = fd; p->ion_device = fd;
*ctx = p; *ctx = p;
} }
@@ -481,6 +483,13 @@ static MPP_RET allocator_ion_close(void *ctx)
return ret; return ret;
} }
static MppAllocFlagType os_allocator_ion_flags(void *ctx)
{
allocator_ctx_ion *p = (allocator_ctx_ion *)ctx;
return p ? p->flags : MPP_ALLOC_FLAG_NONE;
}
os_allocator allocator_ion = { os_allocator allocator_ion = {
.type = MPP_BUFFER_TYPE_ION, .type = MPP_BUFFER_TYPE_ION,
.open = allocator_ion_open, .open = allocator_ion_open,
@@ -490,5 +499,5 @@ os_allocator allocator_ion = {
.import = allocator_ion_import, .import = allocator_ion_import,
.release = allocator_ion_free, .release = allocator_ion_free,
.mmap = allocator_ion_mmap, .mmap = allocator_ion_mmap,
.flags = os_allocator_ion_flags,
}; };

View File

@@ -17,7 +17,7 @@
#ifndef __ALLOCATOR_ION_H__ #ifndef __ALLOCATOR_ION_H__
#define __ALLOCATOR_ION_H__ #define __ALLOCATOR_ION_H__
#include "os_allocator.h" #include "mpp_allocator_api.h"
extern os_allocator allocator_ion; extern os_allocator allocator_ion;

View File

@@ -24,21 +24,30 @@
typedef struct { typedef struct {
size_t alignment; size_t alignment;
MppAllocFlagType flags;
RK_S32 fd_count; RK_S32 fd_count;
} allocator_ctx; } allocator_ctx;
static MPP_RET allocator_std_open(void **ctx, MppAllocatorCfg *cfg) static MPP_RET allocator_std_open(void **ctx, size_t alignment, MppAllocFlagType flags)
{ {
allocator_ctx *p = NULL;
if (NULL == ctx) { if (NULL == ctx) {
mpp_err_f("do not accept NULL input\n"); mpp_err_f("do not accept NULL input\n");
return MPP_ERR_NULL_PTR; return MPP_ERR_NULL_PTR;
} }
mpp_err_f("Warning: std allocator should be used on simulation mode only\n"); mpp_err_f("Warning: std allocator should be used on simulation mode only\n");
(void)cfg;
*ctx = NULL; p = mpp_malloc(allocator_ctx, 1);
return MPP_NOK; if (p) {
p->alignment = alignment;
p->flags = flags;
p->fd_count = 0;
}
*ctx = p;
return p ? MPP_OK : MPP_NOK;
} }
static MPP_RET allocator_std_alloc(void *ctx, MppBufferInfo *info) static MPP_RET allocator_std_alloc(void *ctx, MppBufferInfo *info)
@@ -95,12 +104,14 @@ static MPP_RET allocator_std_mmap(void *ctx, MppBufferInfo *info)
static MPP_RET allocator_std_close(void *ctx) static MPP_RET allocator_std_close(void *ctx)
{ {
if (ctx) { MPP_FREE(ctx);
mpp_free(ctx);
return MPP_OK; return MPP_OK;
} }
mpp_err_f("found NULL context input\n");
return MPP_NOK; static MppAllocFlagType os_allocator_std_flags(void *ctx)
{
(void) ctx;
return MPP_ALLOC_FLAG_NONE;
} }
os_allocator allocator_std = { os_allocator allocator_std = {
@@ -112,5 +123,5 @@ os_allocator allocator_std = {
.import = allocator_std_import, .import = allocator_std_import,
.release = allocator_std_release, .release = allocator_std_release,
.mmap = allocator_std_mmap, .mmap = allocator_std_mmap,
.flags = os_allocator_std_flags,
}; };

View File

@@ -17,7 +17,7 @@
#ifndef __ALLOCATOR_STD_H__ #ifndef __ALLOCATOR_STD_H__
#define __ALLOCATOR_STD_H__ #define __ALLOCATOR_STD_H__
#include "os_allocator.h" #include "mpp_allocator_api.h"
extern os_allocator allocator_std; extern os_allocator allocator_std;

View File

@@ -1,61 +0,0 @@
/*
* Copyright 2015 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.
*/
#if defined(__ANDROID__)
#include "allocator_dma_heap.h"
#include "allocator_drm.h"
#include "allocator_ext_dma.h"
#include "allocator_ion.h"
#include "allocator_std.h"
#include "mpp_runtime.h"
MPP_RET os_allocator_get(os_allocator *api, MppBufferType type)
{
MPP_RET ret = MPP_OK;
switch (type) {
case MPP_BUFFER_TYPE_NORMAL :
*api = allocator_std;
case MPP_BUFFER_TYPE_ION : {
*api = (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DMA_HEAP)) ? allocator_dma_heap :
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_ION)) ? allocator_ion :
#if HAVE_DRM
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DRM)) ? allocator_drm :
#endif
allocator_std;
} break;
case MPP_BUFFER_TYPE_EXT_DMA: {
*api = allocator_ext_dma;
} break;
case MPP_BUFFER_TYPE_DRM : {
*api = (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DMA_HEAP)) ? allocator_dma_heap :
#if HAVE_DRM
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DRM)) ? allocator_drm :
#endif
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_ION)) ? allocator_ion :
allocator_std;
} break;
case MPP_BUFFER_TYPE_DMA_HEAP: {
*api = (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DMA_HEAP)) ? allocator_dma_heap :
allocator_std;
} break;
default : {
ret = MPP_NOK;
} break;
}
return ret;
}
#endif

View File

@@ -17,16 +17,18 @@
#ifndef __MPP_ALLOCATOR_H__ #ifndef __MPP_ALLOCATOR_H__
#define __MPP_ALLOCATOR_H__ #define __MPP_ALLOCATOR_H__
#include "rk_type.h"
#include "mpp_buffer.h" #include "mpp_buffer.h"
typedef void *MppAllocator; typedef enum MppAllocFlagType_e {
MPP_ALLOC_FLAG_NONE = 0,
MPP_ALLOC_FLAG_DMA32 = (1 << 0),
MPP_ALLOC_FLAG_CACHABLE = (1 << 1),
MPP_ALLOC_FLAG_CMA = (1 << 2),
MPP_ALLOC_FLAG_TYPE_MASK = MPP_ALLOC_FLAG_CMA | MPP_ALLOC_FLAG_CACHABLE | MPP_ALLOC_FLAG_DMA32,
MPP_ALLOC_FLAG_TYPE_NB,
} MppAllocFlagType;
typedef struct MppAllocatorCfg_t { typedef void *MppAllocator;
// input
size_t alignment;
RK_U32 flags;
} MppAllocatorCfg;
typedef struct MppAllocatorApi_t { typedef struct MppAllocatorApi_t {
RK_U32 size; RK_U32 size;
@@ -43,14 +45,14 @@ typedef struct MppAllocatorApi_t {
extern "C" { extern "C" {
#endif #endif
MPP_RET mpp_allocator_get(MppAllocator *allocator, /* NOTE: flag may be updated by allocator */
MppAllocatorApi **api, MppBufferType type); MPP_RET mpp_allocator_get(MppAllocator *allocator, MppAllocatorApi **api,
MppBufferType type, MppAllocFlagType flag);
MPP_RET mpp_allocator_put(MppAllocator *allocator); MPP_RET mpp_allocator_put(MppAllocator *allocator);
MppBufferType get_real_allocator_type(const MppAllocator allocator); MppAllocFlagType mpp_allocator_get_flags(const MppAllocator allocator);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /*__MPP_ALLOCATOR_H__*/ #endif /*__MPP_ALLOCATOR_H__*/

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2015 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.
*/
#if defined(linux) && !defined(__ANDROID__)
#include "mpp_log.h"
#include "mpp_runtime.h"
#include "allocator_dma_heap.h"
#include "allocator_drm.h"
#include "allocator_ext_dma.h"
#include "allocator_ion.h"
#include "allocator_std.h"
/*
* Linux only support MPP_BUFFER_TYPE_NORMAL so far
* we can support MPP_BUFFER_TYPE_V4L2 later
*/
MPP_RET os_allocator_get(os_allocator *api, MppBufferType type)
{
MPP_RET ret = MPP_OK;
switch (type) {
case MPP_BUFFER_TYPE_NORMAL : {
*api = allocator_std;
} break;
case MPP_BUFFER_TYPE_ION : {
*api = (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DMA_HEAP)) ? allocator_dma_heap :
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_ION)) ? allocator_ion :
#if HAVE_DRM
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DRM)) ? allocator_drm :
#endif
allocator_std;
} break;
case MPP_BUFFER_TYPE_EXT_DMA: {
*api = allocator_ext_dma;
} break;
case MPP_BUFFER_TYPE_DRM : {
*api = (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DMA_HEAP)) ? allocator_dma_heap :
#if HAVE_DRM
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DRM)) ? allocator_drm :
#endif
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_ION)) ? allocator_ion :
allocator_std;
} break;
case MPP_BUFFER_TYPE_DMA_HEAP: {
*api = (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DMA_HEAP)) ? allocator_dma_heap :
allocator_std;
} break;
default : {
ret = MPP_NOK;
} break;
}
return ret;
}
#endif

View File

@@ -19,10 +19,15 @@
#include "mpp_mem.h" #include "mpp_mem.h"
#include "mpp_debug.h" #include "mpp_debug.h"
#include "mpp_common.h" #include "mpp_common.h"
#include "mpp_runtime.h"
#include "mpp_thread.h"
#include "mpp_allocator.h" #include "mpp_allocator.h"
#include "mpp_allocator_impl.h"
#include "os_allocator.h" #include "allocator_std.h"
#include "allocator_ion.h"
#include "allocator_drm.h"
#include "allocator_ext_dma.h"
#include "allocator_dma_heap.h"
#include <linux/drm.h> #include <linux/drm.h>
@@ -38,6 +43,15 @@ typedef enum OsAllocatorApiId_e {
ALLOC_API_BUTT, ALLOC_API_BUTT,
} OsAllocatorApiId; } OsAllocatorApiId;
typedef struct MppAllocatorImpl_t {
pthread_mutex_t lock;
MppBufferType type;
MppAllocFlagType flags;
size_t alignment;
os_allocator os_api;
void *ctx;
} MppAllocatorImpl;
static MPP_RET mpp_allocator_api_wrapper(MppAllocator allocator, static MPP_RET mpp_allocator_api_wrapper(MppAllocator allocator,
MppBufferInfo *info, MppBufferInfo *info,
OsAllocatorApiId id) OsAllocatorApiId id)
@@ -118,56 +132,83 @@ static MppAllocatorApi mpp_allocator_api = {
.mmap = mpp_allocator_mmap, .mmap = mpp_allocator_mmap,
}; };
MPP_RET mpp_allocator_get(MppAllocator *allocator, MPP_RET mpp_allocator_get(MppAllocator *allocator, MppAllocatorApi **api,
MppAllocatorApi **api, MppBufferType type) MppBufferType type, MppAllocFlagType flags)
{ {
MppBufferType buffer_type = (MppBufferType)(type & MPP_BUFFER_TYPE_MASK); MppBufferType buffer_type = (MppBufferType)(type & MPP_BUFFER_TYPE_MASK);
RK_U32 flags = (type & MPP_BUFFER_FLAGS_MASK) >> 16; MppAllocatorImpl *p = NULL;
do {
if (NULL == allocator || NULL == api || buffer_type >= MPP_BUFFER_TYPE_BUTT) { if (NULL == allocator || NULL == api || buffer_type >= MPP_BUFFER_TYPE_BUTT) {
mpp_err_f("invalid input: allocator %p api %p type %d\n", mpp_err_f("invalid input: allocator %p api %p type %d\n",
allocator, api, buffer_type); allocator, api, buffer_type);
return MPP_ERR_UNKNOW; break;
}
p = mpp_malloc(MppAllocatorImpl, 1);
if (!p) {
mpp_err_f("failed to malloc allocator context\n");
break;
} }
MppAllocatorImpl *p = mpp_malloc(MppAllocatorImpl, 1);
if (NULL == p) {
mpp_err("mpp_allocator_get failed to malloc allocator context\n");
return MPP_ERR_NULL_PTR;
} else {
p->type = buffer_type; p->type = buffer_type;
p->flags = flags; p->flags = flags;
switch (buffer_type) {
case MPP_BUFFER_TYPE_NORMAL : {
p->os_api = allocator_std;
} break;
case MPP_BUFFER_TYPE_ION : {
p->os_api = (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DMA_HEAP)) ? allocator_dma_heap :
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_ION)) ? allocator_ion :
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DRM)) ? allocator_drm :
allocator_std;
} break;
case MPP_BUFFER_TYPE_EXT_DMA: {
p->os_api = allocator_ext_dma;
} break;
case MPP_BUFFER_TYPE_DRM : {
p->os_api = (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DMA_HEAP)) ? allocator_dma_heap :
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DRM)) ? allocator_drm :
(mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_ION)) ? allocator_ion :
allocator_std;
} break;
case MPP_BUFFER_TYPE_DMA_HEAP: {
p->os_api = (mpp_rt_allcator_is_valid(MPP_BUFFER_TYPE_DMA_HEAP)) ? allocator_dma_heap :
allocator_std;
} break;
default : {
} break;
} }
MPP_RET ret = os_allocator_get(&p->os_api, buffer_type); if (p->os_api.open(&p->ctx, SZ_4K, flags))
break;
if (MPP_OK == ret) { /* update the real buffer type and flags */
MppAllocatorCfg cfg = { p->type = p->os_api.type;
.alignment = SZ_4K, if (p->os_api.flags)
.flags = flags, p->flags = p->os_api.flags(p->ctx);
};
ret = p->os_api.open(&p->ctx, &cfg);
/* NOTE: allocator may update the flags for compatibility */ {
p->flags = cfg.flags;
}
if (MPP_OK == ret) {
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr); pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&p->lock, &attr); pthread_mutex_init(&p->lock, &attr);
pthread_mutexattr_destroy(&attr); pthread_mutexattr_destroy(&attr);
}
*allocator = p; *allocator = p;
*api = &mpp_allocator_api; *api = &mpp_allocator_api;
} else {
mpp_err("mpp_allocator_get type %d failed\n", type); return MPP_OK;
mpp_free(p); } while (0);
MPP_FREE(p);
*allocator = NULL; *allocator = NULL;
*api = NULL; *api = NULL;
}
return ret; return MPP_NOK;
} }
MPP_RET mpp_allocator_put(MppAllocator *allocator) MPP_RET mpp_allocator_put(MppAllocator *allocator)
@@ -191,10 +232,9 @@ MPP_RET mpp_allocator_put(MppAllocator *allocator)
return MPP_OK; return MPP_OK;
} }
MppBufferType get_real_allocator_type(const MppAllocator allocator) MppAllocFlagType mpp_allocator_get_flags(const MppAllocator allocator)
{ {
MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; MppAllocatorImpl *p = (MppAllocatorImpl *)allocator;
MppBufferType type = allocator ? p->os_api.type : MPP_BUFFER_TYPE_BUTT;
return type; return p ? p->flags : MPP_ALLOC_FLAG_NONE;
} }

29
osal/mpp_allocator_api.h Normal file
View File

@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: Apache-2.0 OR MIT */
/*
* Copyright (c) 2023 Rockchip Electronics Co., Ltd.
*/
#ifndef __MPP_ALLOCATOR_API_H__
#define __MPP_ALLOCATOR_API_H__
#include "mpp_allocator.h"
typedef MPP_RET (*OsAllocatorFunc)(void *ctx, MppBufferInfo *info);
typedef struct os_allocator_t {
MppBufferType type;
MPP_RET (*open)(void **ctx, size_t alignment, MppAllocFlagType flags);
MPP_RET (*close)(void *ctx);
OsAllocatorFunc alloc;
OsAllocatorFunc free;
OsAllocatorFunc import;
OsAllocatorFunc release;
OsAllocatorFunc mmap;
/* allocator real flag update callback */
MppAllocFlagType (*flags)(void *ctx);
} os_allocator;
#endif /* __MPP_ALLOCATOR_API_H__ */

View File

@@ -1,33 +0,0 @@
/*
* Copyright 2015 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.
*/
#ifndef __MPP_ALLOCATOR_IMPL_H__
#define __MPP_ALLOCATOR_IMPL_H__
#include "mpp_thread.h"
#include "os_allocator.h"
typedef struct MppAllocatorImpl_t {
pthread_mutex_t lock;
MppBufferType type;
RK_U32 flags;
size_t alignment;
os_allocator os_api;
void *ctx;
} MppAllocatorImpl;
#endif /*__MPP_ALLOCATOR_IMPL_H__*/

View File

@@ -8,6 +8,7 @@
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <linux/dma-buf.h> #include <linux/dma-buf.h>
#include "mpp_env.h"
#include "mpp_log.h" #include "mpp_log.h"
#include "mpp_dmabuf.h" #include "mpp_dmabuf.h"
@@ -38,6 +39,18 @@ struct dma_buf_sync_partial {
static RK_U32 has_partial_ops = 1; static RK_U32 has_partial_ops = 1;
__attribute__ ((constructor))
void mpp_dmabuf_init(void)
{
/*
* update has_partial_ops by env
* NOTE: When dmaheap is enabled the dmaheap fd partial ops is fine.
* But the drm fd partial ops may have error when kernel version above 4.19
* So we provide the mpp_dmabuf_has_partial_ops env to disable partial ops.
*/
mpp_env_get_u32("mpp_dmabuf_has_partial_ops", &has_partial_ops, has_partial_ops);
}
MPP_RET mpp_dmabuf_sync_begin(RK_S32 fd, RK_S32 ro, const char *caller) MPP_RET mpp_dmabuf_sync_begin(RK_S32 fd, RK_S32 ro, const char *caller)
{ {
struct dma_buf_sync sync; struct dma_buf_sync sync;

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2015 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.
*/
#ifndef __OS_ALLOCATOR_H__
#define __OS_ALLOCATOR_H__
#include "mpp_allocator.h"
typedef MPP_RET (*OsAllocatorFunc)(void *ctx, MppBufferInfo *info);
typedef struct os_allocator_t {
MppBufferType type;
MPP_RET (*open)(void **ctx, MppAllocatorCfg *cfg);
MPP_RET (*close)(void *ctx);
OsAllocatorFunc alloc;
OsAllocatorFunc free;
OsAllocatorFunc import;
OsAllocatorFunc release;
OsAllocatorFunc mmap;
} os_allocator;
#ifdef __cplusplus
extern "C" {
#endif
MPP_RET os_allocator_get(os_allocator *api, MppBufferType type);
#ifdef __cplusplus
}
#endif
#endif /*__OS_ALLOCATOR_H__*/

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2015 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.
*/
#if defined(_WIN32)
#include "os_allocator.h"
#include "allocator_std.h"
/*
* window only support MPP_BUFFER_TYPE_NORMAL
*/
MPP_RET os_allocator_get(os_allocator *api, MppBufferType type)
{
MPP_RET ret = MPP_OK;
switch (type) {
case MPP_BUFFER_TYPE_NORMAL :
case MPP_BUFFER_TYPE_ION :
case MPP_BUFFER_TYPE_V4L2 : {
*api = allocator_std;
} break;
default : {
ret = MPP_NOK;
} break;
}
return ret;
}
#endif