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