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