1 /* SPDX-License-Identifier: Apache-2.0 OR MIT */ 2 /* 3 * Copyright (c) 2015 Rockchip Electronics Co., Ltd. 4 */ 5 6 #ifndef __MPP_BUFFER_IMPL_H__ 7 #define __MPP_BUFFER_IMPL_H__ 8 9 #include "mpp_list.h" 10 #include "mpp_hash.h" 11 #include "mpp_common.h" 12 #include "mpp_allocator.h" 13 #include "mpp_device.h" 14 15 #define MPP_BUF_DBG_FUNCTION (0x00000001) 16 #define MPP_BUF_DBG_OPS_RUNTIME (0x00000002) 17 #define MPP_BUF_DBG_OPS_HISTORY (0x00000004) 18 #define MPP_BUF_DBG_CLR_ON_EXIT (0x00000010) 19 #define MPP_BUF_DBG_DUMP_ON_EXIT (0x00000020) 20 #define MPP_BUF_DBG_CHECK_SIZE (0x00000100) 21 22 #define mpp_buf_dbg(flag, fmt, ...) _mpp_dbg(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) 23 #define mpp_buf_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) 24 25 #define MPP_BUF_FUNCTION_ENTER() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "enter\n") 26 #define MPP_BUF_FUNCTION_LEAVE() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "leave\n") 27 #define MPP_BUF_FUNCTION_LEAVE_OK() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "success\n") 28 #define MPP_BUF_FUNCTION_LEAVE_FAIL() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "failed\n") 29 30 typedef enum MppBufOps_e { 31 GRP_CREATE, 32 GRP_RELEASE, 33 GRP_RESET, 34 GRP_ORPHAN, 35 GRP_DESTROY, 36 37 GRP_OPS_BUTT = GRP_DESTROY, 38 BUF_COMMIT, 39 BUF_CREATE, 40 BUF_MMAP, 41 BUF_REF_INC, 42 BUF_REF_DEC, 43 BUF_DISCARD, 44 BUF_DESTROY, 45 BUF_OPS_BUTT, 46 } MppBufOps; 47 48 typedef struct MppBufLog_t { 49 RK_U32 group_id; 50 RK_S32 buffer_id; 51 MppBufOps ops; 52 RK_S32 ref_count; 53 const char *caller; 54 } MppBufLog; 55 56 typedef struct MppBufLogs_t { 57 pthread_mutex_t lock; 58 RK_U16 max_count; 59 RK_U16 log_count; 60 RK_U16 log_write; 61 RK_U16 log_read; 62 MppBufLog *logs; 63 } MppBufLogs; 64 65 typedef struct MppBufferImpl_t MppBufferImpl; 66 typedef struct MppBufferGroupImpl_t MppBufferGroupImpl; 67 typedef void (*MppBufCallback)(void *, void *); 68 69 // use index instead of pointer to avoid invalid pointer 70 struct MppBufferImpl_t { 71 char tag[MPP_TAG_SIZE]; 72 const char *caller; 73 pthread_mutex_t lock; 74 /* parameter store from MppBufferGroup */ 75 MppAllocator allocator; 76 MppAllocatorApi *alloc_api; 77 RK_U32 log_runtime_en; 78 RK_U32 log_history_en; 79 RK_U32 group_id; 80 RK_S32 buffer_id; 81 MppBufferMode mode; 82 MppBufferType type; 83 MppBufLogs *logs; 84 85 MppBufferInfo info; 86 size_t offset; 87 size_t length; 88 89 /* cacheable flag */ 90 RK_U32 uncached; 91 92 /* 93 * discard: 94 * used for buf on group reset mode 95 * set disard value to 1 when frame refcount no zero , 96 * we will delay relesase buffer after refcount to zero, 97 * not put this buf to unused list 98 */ 99 RK_S32 discard; 100 // used flag is for used/unused list detection 101 RK_U32 used; 102 RK_S32 ref_count; 103 struct list_head list_status; 104 105 /* 106 * mpp_device map for attach / detach operation 107 */ 108 struct list_head list_maps; 109 }; 110 111 struct MppBufferGroupImpl_t { 112 char tag[MPP_TAG_SIZE]; 113 const char *caller; 114 /* parameter store for MppBuffer */ 115 MppAllocator allocator; 116 MppAllocatorApi *alloc_api; 117 MppAllocFlagType flags; 118 RK_U32 log_runtime_en; 119 RK_U32 log_history_en; 120 RK_U32 group_id; 121 MppBufferMode mode; 122 MppBufferType type; 123 124 /* group status flag */ 125 // buffer force clear mode flag 126 RK_U32 clear_on_exit; 127 RK_U32 dump_on_exit; 128 // is_misc: 0 - normal group 1 - misc group 129 RK_U32 is_misc; 130 // is_orphan: 0 - normal group 1 - orphan group 131 RK_U32 is_orphan; 132 RK_U32 is_finalizing; 133 // used in limit mode only 134 size_t limit_size; 135 RK_S32 limit_count; 136 // status record 137 size_t limit; 138 size_t usage; 139 RK_S32 buffer_id; 140 RK_S32 buffer_count; 141 142 // thread that will be signal on buffer return 143 MppBufCallback callback; 144 void *arg; 145 146 // link to list_status in MppBufferImpl 147 pthread_mutex_t buf_lock; 148 struct hlist_node hlist; 149 struct list_head list_used; 150 struct list_head list_unused; 151 RK_S32 count_used; 152 RK_S32 count_unused; 153 154 // buffer log function 155 MppBufLogs *logs; 156 157 // link to the other MppBufferGroupImpl 158 struct list_head list_group; 159 }; 160 161 #ifdef __cplusplus 162 extern "C" { 163 #endif 164 165 extern RK_U32 mpp_buffer_debug; 166 167 /* 168 * mpp_buffer_create : create a unused buffer with parameter tag/size/data 169 * if input buffer is NULL then buffer will be register to unused list 170 * otherwise the buffer will be register to used list and set to paramter buffer 171 * 172 * mpp_buffer_mmap : The created mpp_buffer can not be accessed directly. 173 * It required map to access. This is an optimization 174 * for reducing virtual memory usage. 175 * 176 * mpp_buffer_get_unused : get unused buffer with size. it will first search 177 * the unused list. if failed it will create on from 178 * group allocator. 179 * 180 * mpp_buffer_ref_inc : increase buffer's reference counter. if it is unused 181 * then it will be moved to used list. 182 * 183 * mpp_buffer_ref_dec : decrease buffer's reference counter. if the reference 184 * reduce to zero buffer will be moved to unused list. 185 * 186 * normal call flow will be like this: 187 * 188 * mpp_buffer_create - create a unused buffer 189 * mpp_buffer_get_unused - get the unused buffer 190 * mpp_buffer_ref_inc/dec - use the buffer 191 * mpp_buffer_destory - destroy the buffer 192 */ 193 MPP_RET mpp_buffer_create(const char *tag, const char *caller, MppBufferGroupImpl *group, MppBufferInfo *info, MppBufferImpl **buffer); 194 MPP_RET mpp_buffer_mmap(MppBufferImpl *buffer, const char* caller); 195 MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer, const char* caller); 196 MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller); 197 MPP_RET mpp_buffer_discard(MppBufferImpl *buffer, const char* caller); 198 MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size, const char* caller); 199 RK_U32 mpp_buffer_to_addr(MppBuffer buffer, size_t offset); 200 MPP_RET mpp_buffer_attach_dev_f(const char *caller, MppBuffer buffer, MppDev dev); 201 MPP_RET mpp_buffer_detach_dev_f(const char *caller, MppBuffer buffer, MppDev dev); 202 RK_U32 mpp_buffer_get_iova_f(const char *caller, MppBuffer buffer, MppDev dev); 203 204 #define mpp_buffer_attach_dev(buf, dev) mpp_buffer_attach_dev_f(__FUNCTION__, buf, dev) 205 #define mpp_buffer_detach_dev(buf, dev) mpp_buffer_detach_dev_f(__FUNCTION__, buf, dev) 206 #define mpp_buffer_get_iova(buf, dev) mpp_buffer_get_iova_f(__FUNCTION__, buf, dev) 207 208 MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, MppBufferMode mode, MppBufferType type); 209 MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p); 210 MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p); 211 MPP_RET mpp_buffer_group_set_callback(MppBufferGroupImpl *p, 212 MppBufCallback callback, void *arg); 213 // mpp_buffer_group helper function 214 void mpp_buffer_group_dump(MppBufferGroupImpl *p, const char *caller); 215 MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type); 216 217 #ifdef __cplusplus 218 } 219 #endif 220 221 #endif /*__MPP_BUFFER_IMPL_H__*/ 222