1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include <securec.h>
10 #include <hdf_log.h>
11 #include <osal_mem.h>
12 #include "osal_uaccess.h"
13 #include "camera_buffer_manager.h"
14 #include "camera_buffer.h"
15 #include "camera_device_manager.h"
16 #include "buffer_queue.h"
17
18 #define HDF_LOG_TAG HDF_CAMERA_QUEUE
19
BufferQueueStop(struct BufferQueue * queue)20 void BufferQueueStop(struct BufferQueue *queue)
21 {
22 uint32_t i;
23
24 if (OsalAtomicRead(&queue->driverOwnCount) != 0) {
25 for (i = 0; i < queue->numBuffers; ++i) {
26 if (queue->buffers[i]->state == BUFFER_STATE_ACTIVE) {
27 CameraBufferDone(queue->buffers[i], BUFFER_STATE_ERROR);
28 }
29 }
30 HDF_LOGI("%s: Expect zero, driverOwnCount = %{public}d", __func__, OsalAtomicRead(&queue->driverOwnCount));
31 }
32
33 queue->flags &= ~QUEUE_STATE_STREAMING;
34 queue->flags &= ~QUEUE_STATE_STREAMING_CALLED;
35 queue->queuedCount = 0;
36 queue->flags &= ~QUEUE_STATE_ERROR;
37
38 DListHeadInit(&queue->queuedList);
39 DListHeadInit(&queue->doneList);
40 OsalAtomicSet(&queue->driverOwnCount, 0);
41 wake_up_interruptible(&queue->doneWait);
42
43 for (i = 0; i < queue->numBuffers; ++i) {
44 struct CameraBuffer *buffer = queue->buffers[i];
45 CameraBufferSyncForUser(buffer);
46 buffer->flags &= ~BUFFER_PREPARED;
47 buffer->state = BUFFER_STATE_DEQUEUED;
48 }
49 }
50
BufferQueueCheckMmapOps(struct BufferQueue * queue)51 static int32_t BufferQueueCheckMmapOps(struct BufferQueue *queue)
52 {
53 if (((queue->ioModes & MEMTYPE_MMAP) == 0) || (queue->memOps->mmapAlloc == NULL) ||
54 (queue->memOps->mmapFree == NULL) || (queue->memOps->mmap == NULL)) {
55 return HDF_FAILURE;
56 }
57 return HDF_SUCCESS;
58 }
59
BufferQueueCheckUserPtrOps(struct BufferQueue * queue)60 static int32_t BufferQueueCheckUserPtrOps(struct BufferQueue *queue)
61 {
62 if (((queue->ioModes & MEMTYPE_USERPTR) == 0) || (queue->memOps->allocUserPtr == NULL) ||
63 (queue->memOps->freeUserPtr == NULL)) {
64 return HDF_FAILURE;
65 }
66 return HDF_SUCCESS;
67 }
68
BufferQueueCheckDmaBufOps(struct BufferQueue * queue)69 static int32_t BufferQueueCheckDmaBufOps(struct BufferQueue *queue)
70 {
71 if (((queue->ioModes & MEMTYPE_DMABUF) == 0) || (queue->memOps->attachDmaBuf == NULL) ||
72 (queue->memOps->detachDmaBuf == NULL) || (queue->memOps->mapDmaBuf == NULL) ||
73 (queue->memOps->unmapDmaBuf == NULL)) {
74 return HDF_FAILURE;
75 }
76 return HDF_SUCCESS;
77 }
78
BufferQueueCheckMemOps(struct BufferQueue * queue,enum CameraMemType memType)79 int32_t BufferQueueCheckMemOps(struct BufferQueue *queue, enum CameraMemType memType)
80 {
81 if (memType != MEMTYPE_MMAP && memType != MEMTYPE_USERPTR && memType != MEMTYPE_DMABUF) {
82 HDF_LOGE("%s: memType is fault!", __func__);
83 return HDF_ERR_INVALID_PARAM;
84 }
85 if (memType == MEMTYPE_MMAP && BufferQueueCheckMmapOps(queue) != HDF_SUCCESS) {
86 HDF_LOGE("%s: MMAP for current setup unsupported!", __func__);
87 return HDF_ERR_NOT_SUPPORT;
88 }
89 if (memType == MEMTYPE_USERPTR && BufferQueueCheckUserPtrOps(queue) != HDF_SUCCESS) {
90 HDF_LOGE("%s: USERPTR for current setup unsupported!", __func__);
91 return HDF_ERR_NOT_SUPPORT;
92 }
93 if (memType == MEMTYPE_DMABUF && BufferQueueCheckDmaBufOps(queue) != HDF_SUCCESS) {
94 HDF_LOGE("%s: DMABUF for current setup unsupported!", __func__);
95 return HDF_ERR_NOT_SUPPORT;
96 }
97 return HDF_SUCCESS;
98 }
99
BufferQueueFree(struct BufferQueue * queue,uint32_t count)100 static int32_t BufferQueueFree(struct BufferQueue *queue, uint32_t count)
101 {
102 uint32_t i;
103 struct CameraBuffer *buffer = NULL;
104
105 if (queue->numBuffers < count) {
106 HDF_LOGE("%s: count out of range!", __func__);
107 return HDF_ERR_INVALID_PARAM;
108 }
109
110 for (i = queue->numBuffers - count; i < queue->numBuffers; ++i) {
111 buffer = queue->buffers[i];
112 if (buffer == NULL) {
113 continue;
114 }
115 if (buffer->state == BUFFER_STATE_PREPARING) {
116 HDF_LOGE("%s: Can free buffer. Buffer is preparing!", __func__);
117 return HDF_FAILURE;
118 }
119 CameraBufferFree(buffer);
120 OsalMemFree(buffer);
121 queue->buffers[i] = NULL;
122 }
123
124 queue->numBuffers -= count;
125 if (queue->numBuffers == 0) {
126 queue->memType = MEMTYPE_UNKNOWN;
127 DListHeadInit(&queue->queuedList);
128 }
129 return HDF_SUCCESS;
130 }
131
BufferQueueReleaseBuffers(struct BufferQueue * queue,struct UserCameraReq * userRequest)132 int32_t BufferQueueReleaseBuffers(struct BufferQueue *queue, struct UserCameraReq *userRequest)
133 {
134 int32_t ret = 0;
135
136 userRequest->capabilities = queue->ioModes;
137 if ((queue->flags & QUEUE_STATE_STREAMING) != 0) {
138 HDF_LOGE("%s: Queue is streaming", __func__);
139 return HDF_FAILURE;
140 }
141 if (((queue->flags & QUEUE_STATE_WAITING_DEQUEUE) != 0) && userRequest->count != 0) {
142 HDF_LOGE("%s: Queue is waiting dequeue", __func__);
143 return HDF_FAILURE;
144 }
145
146 if (userRequest->count == 0 || queue->numBuffers != 0 ||
147 (queue->memType != MEMTYPE_UNKNOWN && queue->memType != userRequest->memType)) {
148 OsalMutexLock(&queue->mmapLock);
149 BufferQueueStop(queue);
150 ret = BufferQueueFree(queue, queue->numBuffers);
151 OsalMutexUnlock(&queue->mmapLock);
152 }
153 return ret;
154 }
155
BufferQueueAllocBuffers(struct BufferQueue * queue,uint32_t memType,uint32_t numBuffers,uint32_t numPlanes,const uint32_t planeSizes[])156 static int32_t BufferQueueAllocBuffers(struct BufferQueue *queue, uint32_t memType,
157 uint32_t numBuffers, uint32_t numPlanes, const uint32_t planeSizes[])
158 {
159 uint32_t bufferId;
160 uint32_t planeId;
161 struct CameraBuffer *buffer = NULL;
162 int32_t ret;
163
164 numBuffers = numBuffers < (MAX_FRAME - queue->numBuffers) ? numBuffers : (MAX_FRAME - queue->numBuffers);
165 for (bufferId = 0; bufferId < numBuffers; ++bufferId) {
166 buffer = OsalMemCalloc(queue->bufferSize);
167 if (buffer == NULL) {
168 HDF_LOGE("%s: Memory alloc failed", __func__);
169 break;
170 }
171 buffer->state = BUFFER_STATE_DEQUEUED;
172 buffer->bufferQueue = queue;
173 buffer->numPlanes = numPlanes;
174 buffer->id = queue->numBuffers + bufferId;
175 buffer->memType = memType;
176 if (queue->memType != MEMTYPE_DMABUF) {
177 buffer->flags |= BUFFER_NEED_USER_SYNC;
178 buffer->flags |= BUFFER_NEED_DEVICE_SYNC;
179 }
180 for (planeId = 0; planeId < numPlanes; ++planeId) {
181 buffer->planes[planeId].length = planeSizes[planeId];
182 buffer->planes[planeId].minLength = planeSizes[planeId];
183 }
184 queue->buffers[buffer->id] = buffer;
185 if (memType == MEMTYPE_MMAP) {
186 ret = CameraBufferAllocMmapPlanes(buffer);
187 if (ret != HDF_SUCCESS) {
188 HDF_LOGE("%s: Mmap alloc failed", __func__);
189 queue->buffers[buffer->id] = NULL;
190 OsalMemFree(buffer);
191 break;
192 }
193 CameraBufferSetupOffsets(buffer);
194 }
195 }
196 HDF_LOGI("%s: allocated %{public}d buffers and %{public}d planes", __func__, bufferId, planeId);
197
198 return bufferId;
199 }
200
BufferQueueRequestBuffers(struct BufferQueue * queue,struct UserCameraReq * userRequest,uint32_t numBuffers,uint32_t numPlanes,uint32_t planeSizes[])201 int32_t BufferQueueRequestBuffers(struct BufferQueue *queue, struct UserCameraReq *userRequest,
202 uint32_t numBuffers, uint32_t numPlanes, uint32_t planeSizes[])
203 {
204 int32_t ret;
205 uint32_t allocatedBuffers;
206
207 allocatedBuffers = BufferQueueAllocBuffers(queue, userRequest->memType, numBuffers, numPlanes, planeSizes);
208 ret = allocatedBuffers < queue->minBuffersNeeded ? HDF_FAILURE : HDF_SUCCESS;
209 if (allocatedBuffers == 0) {
210 HDF_LOGE("%s: allocatedBuffers wrong", __func__);
211 return HDF_FAILURE;
212 }
213 if (ret == HDF_SUCCESS && allocatedBuffers < numBuffers) {
214 numBuffers = allocatedBuffers;
215 numPlanes = 0;
216 ret = queue->queueOps->queueSetup != NULL ? queue->queueOps->queueSetup(queue, &numBuffers,
217 &numPlanes, planeSizes) : HDF_SUCCESS;
218 if (ret == HDF_SUCCESS && allocatedBuffers < numBuffers) {
219 ret = HDF_FAILURE;
220 }
221 }
222
223 OsalMutexLock(&queue->mmapLock);
224 queue->numBuffers = allocatedBuffers;
225 if (ret != HDF_SUCCESS) {
226 BufferQueueFree(queue, queue->numBuffers);
227 OsalMutexUnlock(&queue->mmapLock);
228 return ret;
229 }
230 OsalMutexUnlock(&queue->mmapLock);
231 userRequest->count = allocatedBuffers;
232 queue->flags |= QUEUE_STATE_WAITING_BUFFERS;
233 return HDF_SUCCESS;
234 }
235
BufferQueueStart(struct BufferQueue * queue)236 int32_t BufferQueueStart(struct BufferQueue *queue)
237 {
238 struct CameraBuffer *buffer = NULL;
239 int32_t ret;
240
241 struct BufferQueueImp *queueImp = container_of(queue, struct BufferQueueImp, queue);
242 struct StreamDevice *streamDev = container_of(queueImp, struct StreamDevice, queueImp);
243
244 DLIST_FOR_EACH_ENTRY(buffer, &queue->queuedList, struct CameraBuffer, queueEntry) {
245 CameraBufferEnqueue(buffer);
246 }
247 queue->flags |= QUEUE_STATE_STREAMING_CALLED;
248 if (streamDev->streamOps->startStreaming == NULL) {
249 return HDF_FAILURE;
250 }
251
252 ret = streamDev->streamOps->startStreaming(streamDev);
253 if (ret == HDF_SUCCESS) {
254 return ret;
255 }
256 queue->flags &= ~QUEUE_STATE_STREAMING_CALLED;
257
258 if (OsalAtomicRead(&queue->driverOwnCount) != 0) {
259 for (uint32_t i = 0; i < queue->numBuffers; ++i) {
260 buffer = queue->buffers[i];
261 if (buffer->state == BUFFER_STATE_ACTIVE) {
262 CameraBufferDone(buffer, BUFFER_STATE_QUEUED);
263 }
264 }
265 HDF_LOGW("%s: driver count must be zero: %{public}d", __func__, OsalAtomicRead(&queue->driverOwnCount));
266 }
267 if (!DListIsEmpty(&queue->doneList)) {
268 HDF_LOGW("%s: doneList is not empty", __func__);
269 }
270 return ret;
271 }
272
BufferQueuePrepare(struct BufferQueue * queue,struct UserCameraBuffer * userBuffer)273 int32_t BufferQueuePrepare(struct BufferQueue *queue, struct UserCameraBuffer *userBuffer)
274 {
275 struct CameraBuffer *buffer = NULL;
276 int32_t ret;
277
278 if (userBuffer->id >= queue->numBuffers) {
279 HDF_LOGE("%s: buffer index out of range", __func__);
280 return HDF_ERR_INVALID_PARAM;
281 }
282 if (queue->buffers[userBuffer->id] == NULL) {
283 HDF_LOGE("%s: buffer is NULL", __func__);
284 return HDF_FAILURE;
285 }
286 if (userBuffer->memType != queue->memType) {
287 HDF_LOGE("%s: invalid memory type: userBuffer memType = %{public}u, queue memType = %{public}u",
288 __func__, userBuffer->memType, queue->memType);
289 return HDF_FAILURE;
290 }
291
292 buffer = queue->buffers[userBuffer->id];
293 ret = CameraBufferCheckPlanes(buffer, userBuffer);
294 if (ret != HDF_SUCCESS) {
295 return ret;
296 }
297 if (buffer->state != BUFFER_STATE_DEQUEUED) {
298 HDF_LOGE("%s: buffer is not in dequeued state", __func__);
299 return HDF_FAILURE;
300 }
301
302 if ((buffer->flags & BUFFER_PREPARED) == 0) {
303 CameraBufferSetCacheSync(queue, buffer);
304 ret = CameraBufferCheckPlaneLength(buffer, userBuffer);
305 if (ret != HDF_SUCCESS) {
306 return ret;
307 }
308 }
309 return ret;
310 }
311