1 /*
2 * Copyright 2015 - 2017 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #define MODULE_TAG "hal_bufs"
17
18 #include <string.h>
19
20 #include "mpp_env.h"
21 #include "mpp_mem.h"
22 #include "mpp_debug.h"
23 #include "mpp_common.h"
24
25 #include "hal_bufs.h"
26
27 #define HAL_BUFS_DBG_FUNCTION (0x00000001)
28
29 #define hal_bufs_dbg(flag, fmt, ...) _mpp_dbg(hal_bufs_debug, flag, fmt, ## __VA_ARGS__)
30 #define hal_bufs_dbg_f(flag, fmt, ...) _mpp_dbg_f(hal_bufs_debug, flag, fmt, ## __VA_ARGS__)
31
32 #define hal_bufs_dbg_func(fmt, ...) hal_bufs_dbg_f(HAL_BUFS_DBG_FUNCTION, fmt, ## __VA_ARGS__)
33
34 #define hal_bufs_enter() hal_bufs_dbg_func("enter\n");
35 #define hal_bufs_leave() hal_bufs_dbg_func("leave\n");
36
37 #define MAX_HAL_BUFS_CNT 40
38 #define MAX_HAL_BUFS_SIZE_CNT 8
39
40 typedef struct HalBufsImpl_t {
41 MppBufferGroup group;
42
43 RK_S32 max_cnt;
44 RK_S32 size_cnt;
45 RK_S32 size_sum;
46 RK_S32 slot_sum;
47 RK_S32 elem_size;
48
49 RK_U32 valid;
50 size_t sizes[MAX_HAL_BUFS_SIZE_CNT];
51 RK_U8 *bufs;
52 } HalBufsImpl;
53
54 static RK_U32 hal_bufs_debug = 0;
55
hal_bufs_pos(HalBufsImpl * impl,RK_S32 idx)56 static HalBuf *hal_bufs_pos(HalBufsImpl *impl, RK_S32 idx)
57 {
58 RK_S32 elem_size = impl->elem_size;
59
60 return (HalBuf *)(impl->bufs + idx * elem_size);
61 }
62
hal_bufs_clear(HalBufsImpl * impl)63 static MPP_RET hal_bufs_clear(HalBufsImpl *impl)
64 {
65 MPP_RET ret = MPP_OK;
66
67 if (impl->valid && impl->size_sum) {
68 RK_S32 i;
69
70 for (i = 0; i < impl->max_cnt; i++) {
71 RK_U32 mask = 1 << i;
72
73 if (impl->valid & mask) {
74 HalBuf *buf = hal_bufs_pos(impl, i);
75 RK_S32 j = 0;
76
77 for (j = 0; j < impl->size_cnt; j++) {
78 if (buf->buf[j]) {
79 impl->size_sum -= impl->sizes[j];
80 ret |= mpp_buffer_put(buf->buf[j]);
81 buf->buf[j] = NULL;
82 }
83 }
84 impl->valid &= ~mask;
85 }
86 }
87
88 mpp_assert(impl->valid == 0);
89 mpp_assert(impl->size_sum == 0);
90 }
91
92 impl->max_cnt = 0;
93 impl->size_cnt = 0;
94 impl->size_sum = 0;
95 impl->slot_sum = 0;
96 impl->valid = 0;
97 memset(impl->sizes, 0, sizeof(impl->sizes));
98 MPP_FREE(impl->bufs);
99
100 return ret;
101 }
102
hal_bufs_init(HalBufs * bufs)103 MPP_RET hal_bufs_init(HalBufs *bufs)
104 {
105 MPP_RET ret = MPP_OK;
106
107 if (NULL == bufs) {
108 mpp_err_f("invalid NULL input\n");
109 return MPP_ERR_NULL_PTR;
110 }
111
112 mpp_env_get_u32("hal_bufs_debug", &hal_bufs_debug, 0);
113
114 hal_bufs_enter();
115
116 HalBufsImpl *impl = mpp_calloc(HalBufsImpl, 1);
117 if (impl) {
118 ret = mpp_buffer_group_get_internal(&impl->group, MPP_BUFFER_TYPE_ION);
119 } else {
120 mpp_err_f("failed to malloc HalBufs\n");
121 ret = MPP_ERR_MALLOC;
122 }
123
124 *bufs = impl;
125
126 hal_bufs_leave();
127
128 return ret;
129 }
130
hal_bufs_deinit(HalBufs bufs)131 MPP_RET hal_bufs_deinit(HalBufs bufs)
132 {
133 HalBufsImpl *impl = (HalBufsImpl *)bufs;
134 MPP_RET ret = MPP_OK;
135
136 if (NULL == bufs) {
137 mpp_err_f("invalid NULL input\n");
138 return MPP_ERR_NULL_PTR;
139 }
140
141 hal_bufs_enter();
142
143 ret = hal_bufs_clear(impl);
144
145 if (impl->group) {
146 ret |= mpp_buffer_group_put(impl->group);
147 impl->group = NULL;
148 }
149
150 memset(impl, 0, sizeof(*impl));
151 MPP_FREE(impl);
152
153 hal_bufs_leave();
154
155 return ret;
156 }
157
hal_bufs_setup(HalBufs bufs,RK_S32 max_cnt,RK_S32 size_cnt,size_t sizes[])158 MPP_RET hal_bufs_setup(HalBufs bufs, RK_S32 max_cnt, RK_S32 size_cnt, size_t sizes[])
159 {
160 HalBufsImpl *impl = (HalBufsImpl *)bufs;
161 MPP_RET ret = MPP_OK;
162 RK_S32 elem_size = 0;
163 RK_S32 impl_size = 0;
164
165 if (NULL == bufs || NULL == sizes) {
166 mpp_err_f("invalid NULL input bufs %p sizes %p\n", bufs, sizes);
167 return MPP_ERR_NULL_PTR;
168 }
169
170 if (max_cnt <= 0 || max_cnt > MAX_HAL_BUFS_CNT ||
171 size_cnt <= 0 || size_cnt > MAX_HAL_BUFS_SIZE_CNT) {
172 mpp_err_f("invalid max cnt %d size cnt %d\n", max_cnt, size_cnt);
173 return MPP_ERR_VALUE;
174 }
175
176 hal_bufs_enter();
177
178 hal_bufs_clear(impl);
179
180 if (impl->group)
181 ret = mpp_buffer_group_clear(impl->group);
182 else
183 ret = mpp_buffer_group_get_internal(&impl->group, MPP_BUFFER_TYPE_ION);
184
185 mpp_assert(impl->group);
186
187 elem_size = sizeof(HalBuf) + sizeof(MppBuffer) * size_cnt;
188 impl_size = elem_size * max_cnt;
189
190 impl->elem_size = elem_size;
191 impl->bufs = mpp_calloc_size(void, impl_size);
192 if (impl->bufs) {
193 RK_S32 slot_sum = 0;
194 RK_S32 i;
195
196 for (i = 0; i < size_cnt; i++) {
197 slot_sum += sizes[i];
198 impl->sizes[i] = sizes[i];
199 }
200
201 impl->slot_sum = slot_sum;
202
203 for (i = 0; i < max_cnt; i++) {
204 HalBuf *buf = hal_bufs_pos(impl, i);
205
206 buf->cnt = size_cnt;
207 buf->buf = (MppBuffer)(buf + 1);
208 }
209
210 impl->max_cnt = max_cnt;
211 impl->size_cnt = size_cnt;
212 } else {
213 mpp_err_f("failed to malloc size %d for impl\n", impl_size);
214 ret = MPP_ERR_MALLOC;
215 }
216
217 hal_bufs_leave();
218
219 return ret;
220 }
221
hal_bufs_get_buf(HalBufs bufs,RK_S32 buf_idx)222 HalBuf *hal_bufs_get_buf(HalBufs bufs, RK_S32 buf_idx)
223 {
224 HalBufsImpl *impl = (HalBufsImpl *)bufs;
225
226 if (NULL == impl || buf_idx < 0 || buf_idx >= impl->max_cnt) {
227 mpp_err_f("invalid input impl %p buf_idx %d\n", impl, buf_idx);
228 return NULL;
229 }
230
231 hal_bufs_enter();
232
233 HalBuf *hal_buf = hal_bufs_pos(impl, buf_idx);
234 RK_U32 mask = 1 << buf_idx;
235
236 if (!(impl->valid & mask)) {
237 MppBufferGroup group = impl->group;
238 RK_S32 i;
239
240 for (i = 0; i < impl->size_cnt; i++) {
241 size_t size = impl->sizes[i];
242 MppBuffer buf = hal_buf->buf[i];
243
244 if (size && NULL == buf) {
245 mpp_buffer_get(group, &buf, size);
246 impl->size_sum += size;
247 }
248
249 mpp_assert(buf);
250 hal_buf->buf[i] = buf;
251 }
252
253 impl->valid |= mask;
254 }
255
256 hal_bufs_leave();
257
258 return hal_buf;
259 }
260