diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 3409b32cec..82672e5fbc 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -2267,8 +2267,8 @@ sp Camera3Device::createCaptureRequest( return NULL; } } - // Check if stream is being prepared - if (mInputStream->isPreparing()) { + // Check if stream prepare is blocking requests. + if (mInputStream->isBlockedByPrepare()) { CLOGE("Request references an input stream that's being prepared!"); return NULL; } @@ -2318,8 +2318,8 @@ sp Camera3Device::createCaptureRequest( return NULL; } } - // Check if stream is being prepared - if (stream->isPreparing()) { + // Check if stream prepare is blocking requests. + if (stream->isBlockedByPrepare()) { CLOGE("Request references an output stream that's being prepared!"); return NULL; } @@ -4890,7 +4890,8 @@ status_t Camera3Device::RequestThread::prepareHalRequests() { // Only try to prepare video stream on the first video request. mPrepareVideoStream = false; - res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX); + res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX, + false /*blockRequest*/); while (res == NOT_ENOUGH_DATA) { res = outputStream->prepareNextBuffer(); } @@ -5555,7 +5556,7 @@ status_t Camera3Device::PreparerThread::prepare(int maxCount, sp listener = mListener.promote(); - res = stream->startPrepare(maxCount); + res = stream->startPrepare(maxCount, true /*blockRequest*/); if (res == OK) { // No preparation needed, fire listener right off ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId()); @@ -5643,7 +5644,7 @@ status_t Camera3Device::PreparerThread::resume() { auto it = mPendingStreams.begin(); for (; it != mPendingStreams.end();) { - res = it->second->startPrepare(it->first); + res = it->second->startPrepare(it->first, true /*blockRequest*/); if (res == OK) { if (listener != NULL) { listener->notifyPrepared(it->second->getId()); diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp index 6154301b71..7ebc299a76 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.cpp +++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp @@ -61,6 +61,7 @@ Camera3Stream::Camera3Stream(int id, mOldUsage(0), mOldMaxBuffers(0), mPrepared(false), + mPrepareBlockRequest(true), mPreparedBufferIdx(0), mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX), mBufferLimitLatency(kBufferLimitLatencyBinSize), @@ -327,6 +328,7 @@ status_t Camera3Stream::finishConfiguration() { // Reset prepared state, since buffer config has changed, and existing // allocations are no longer valid mPrepared = false; + mPrepareBlockRequest = true; mStreamUnpreparable = false; status_t res; @@ -388,7 +390,7 @@ bool Camera3Stream::isUnpreparable() { return mStreamUnpreparable; } -status_t Camera3Stream::startPrepare(int maxCount) { +status_t Camera3Stream::startPrepare(int maxCount, bool blockRequest) { ATRACE_CALL(); Mutex::Autolock l(mLock); @@ -420,8 +422,6 @@ status_t Camera3Stream::startPrepare(int maxCount) { return INVALID_OPERATION; } - - size_t pipelineMax = getBufferCountLocked(); size_t clampedCount = (pipelineMax < static_cast(maxCount)) ? pipelineMax : static_cast(maxCount); @@ -429,6 +429,7 @@ status_t Camera3Stream::startPrepare(int maxCount) { pipelineMax : clampedCount; mPrepared = bufferCount <= mLastMaxCount; + mPrepareBlockRequest = blockRequest; if (mPrepared) return OK; @@ -442,9 +443,9 @@ status_t Camera3Stream::startPrepare(int maxCount) { return NOT_ENOUGH_DATA; } -bool Camera3Stream::isPreparing() const { +bool Camera3Stream::isBlockedByPrepare() const { Mutex::Autolock l(mLock); - return mState == STATE_PREPARING; + return mState == STATE_PREPARING && mPrepareBlockRequest; } bool Camera3Stream::isAbandoned() const { diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h index 1af939c0a0..03559782c1 100644 --- a/services/camera/libcameraservice/device3/Camera3Stream.h +++ b/services/camera/libcameraservice/device3/Camera3Stream.h @@ -232,6 +232,11 @@ class Camera3Stream : * * This call performs no allocation, so is quick to call. * + * blockRequest specifies whether prepare will block upcoming capture + * request. This flag should only be set to false if the caller guarantees + * the whole buffer preparation process is done before capture request + * comes in. + * * Returns: * OK if no more buffers need to be preallocated * NOT_ENOUGH_DATA if calls to prepareNextBuffer are needed to finish @@ -240,12 +245,12 @@ class Camera3Stream : * INVALID_OPERATION if called when not in CONFIGURED state, or a * valid buffer has already been returned to this stream. */ - status_t startPrepare(int maxCount); + status_t startPrepare(int maxCount, bool blockRequest); /** - * Check if the stream is mid-preparing. + * Check if the request on a stream is blocked by prepare. */ - bool isPreparing() const; + bool isBlockedByPrepare() const; /** * Continue stream buffer preparation by allocating the next @@ -535,6 +540,7 @@ class Camera3Stream : // has been called sufficient number of times, or stream configuration // had to register buffers with the HAL bool mPrepared; + bool mPrepareBlockRequest; Vector mPreparedBuffers; size_t mPreparedBufferIdx; diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h index 2dde1c3258..3d45c8943a 100644 --- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h +++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h @@ -160,6 +160,11 @@ class Camera3StreamInterface : public virtual RefBase { * PREPARING state. Otherwise, returns NOT_ENOUGH_DATA and transitions * to PREPARING. * + * blockRequest specifies whether prepare will block upcoming capture + * request. This flag should only be set to false if the caller guarantees + * the whole buffer preparation process is done before capture request + * comes in. + * * Returns: * OK if no more buffers need to be preallocated * NOT_ENOUGH_DATA if calls to prepareNextBuffer are needed to finish @@ -168,12 +173,12 @@ class Camera3StreamInterface : public virtual RefBase { * INVALID_OPERATION if called when not in CONFIGURED state, or a * valid buffer has already been returned to this stream. */ - virtual status_t startPrepare(int maxCount) = 0; + virtual status_t startPrepare(int maxCount, bool blockRequest) = 0; /** - * Check if the stream is mid-preparing. + * Check if the request on a stream is blocked by prepare. */ - virtual bool isPreparing() const = 0; + virtual bool isBlockedByPrepare() const = 0; /** * Continue stream buffer preparation by allocating the next