diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp index 04d3639283..f829b65eea 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.cpp +++ b/services/camera/libcameraservice/device3/Camera3Device.cpp @@ -1619,6 +1619,15 @@ void Camera3Device::StreamSet::clear() { return mData.clear(); } +std::vector Camera3Device::StreamSet::getStreamIds() { + std::lock_guard lock(mLock); + std::vector streamIds(mData.size()); + for (size_t i = 0; i < mData.size(); i++) { + streamIds[i] = mData.keyAt(i); + } + return streamIds; +} + status_t Camera3Device::createStream(sp consumer, uint32_t width, uint32_t height, int format, android_dataspace dataSpace, camera3_stream_rotation_t rotation, int *id, @@ -2130,6 +2139,12 @@ status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) { break; } + // Notify HAL to start draining + if (!active && mUseHalBufManager) { + auto streamIds = mOutputStreams.getStreamIds(); + mRequestThread->signalPipelineDrain(streamIds); + } + res = mStatusChanged.waitRelative(mLock, timeout); if (res != OK) break; @@ -3902,26 +3917,49 @@ status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t * // Invoke configureStreams device::V3_3::HalStreamConfiguration finalConfiguration; + device::V3_4::HalStreamConfiguration finalConfiguration3_4; common::V1_0::Status status; - // See if we have v3.4 or v3.3 HAL - if (mHidlSession_3_4 != nullptr) { - // We do; use v3.4 for the call - ALOGV("%s: v3.4 device found", __FUNCTION__); - device::V3_4::HalStreamConfiguration finalConfiguration3_4; - auto err = mHidlSession_3_4->configureStreams_3_4(requestedConfiguration3_4, - [&status, &finalConfiguration3_4] + auto configStream34Cb = [&status, &finalConfiguration3_4] (common::V1_0::Status s, const device::V3_4::HalStreamConfiguration& halConfiguration) { finalConfiguration3_4 = halConfiguration; status = s; - }); - if (!err.isOk()) { - ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str()); - return DEAD_OBJECT; + }; + + auto postprocConfigStream34 = [&finalConfiguration, &finalConfiguration3_4] + (hardware::Return& err) -> status_t { + if (!err.isOk()) { + ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str()); + return DEAD_OBJECT; + } + finalConfiguration.streams.resize(finalConfiguration3_4.streams.size()); + for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) { + finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3; + } + return OK; + }; + + // See if we have v3.4 or v3.3 HAL + if (mHidlSession_3_5 != nullptr) { + ALOGV("%s: v3.5 device found", __FUNCTION__); + device::V3_5::StreamConfiguration requestedConfiguration3_5; + requestedConfiguration3_5.v3_4 = requestedConfiguration3_4; + requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++; + auto err = mHidlSession_3_5->configureStreams_3_5( + requestedConfiguration3_5, configStream34Cb); + res = postprocConfigStream34(err); + if (res != OK) { + return res; } - finalConfiguration.streams.resize(finalConfiguration3_4.streams.size()); - for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) { - finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3; + } else if (mHidlSession_3_4 != nullptr) { + // We do; use v3.4 for the call + ALOGV("%s: v3.4 device found", __FUNCTION__); + device::V3_4::HalStreamConfiguration finalConfiguration3_4; + auto err = mHidlSession_3_4->configureStreams_3_4( + requestedConfiguration3_4, configStream34Cb); + res = postprocConfigStream34(err); + if (res != OK) { + return res; } } else if (mHidlSession_3_3 != nullptr) { // We do; use v3.3 for the call @@ -4292,6 +4330,20 @@ status_t Camera3Device::HalInterface::close() { return res; } +void Camera3Device::HalInterface::signalPipelineDrain(const std::vector& streamIds) { + ATRACE_NAME("CameraHal::signalPipelineDrain"); + if (!valid() || mHidlSession_3_5 == nullptr) { + ALOGE("%s called on invalid camera!", __FUNCTION__); + return; + } + + auto err = mHidlSession_3_5->signalStreamFlush(streamIds, mNextStreamConfigCounter); + if (!err.isOk()) { + ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str()); + return; + } +} + void Camera3Device::HalInterface::getInflightBufferKeys( std::vector>* out) { std::lock_guard lock(mInflightLock); @@ -4418,6 +4470,7 @@ Camera3Device::RequestThread::RequestThread(wp parent, mReconfigured(false), mDoPause(false), mPaused(true), + mNotifyPipelineDrain(false), mFrameNumber(0), mLatestRequestId(NAME_NOT_FOUND), mCurrentAfTriggerId(0), @@ -5369,6 +5422,21 @@ bool Camera3Device::RequestThread::isOutputSurfacePending(int streamId, size_t s return false; } +void Camera3Device::RequestThread::signalPipelineDrain(const std::vector& streamIds) { + if (!mUseHalBufManager) { + ALOGE("%s called for camera device not supporting HAL buffer management", __FUNCTION__); + return; + } + + Mutex::Autolock pl(mPauseLock); + if (mPaused) { + return mInterface->signalPipelineDrain(streamIds); + } + // If request thread is still busy, wait until paused then notify HAL + mNotifyPipelineDrain = true; + mStreamIdsToBeDrained = streamIds; +} + nsecs_t Camera3Device::getExpectedInFlightDuration() { ATRACE_CALL(); Mutex::Autolock al(mInFlightLock); @@ -5546,6 +5614,11 @@ sp if (statusTracker != 0) { statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE); } + if (mNotifyPipelineDrain) { + mInterface->signalPipelineDrain(mStreamIdsToBeDrained); + mNotifyPipelineDrain = false; + mStreamIdsToBeDrained.clear(); + } } // Stop waiting for now and let thread management happen return NULL; @@ -5630,6 +5703,11 @@ bool Camera3Device::RequestThread::waitIfPaused() { if (statusTracker != 0) { statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE); } + if (mNotifyPipelineDrain) { + mInterface->signalPipelineDrain(mStreamIdsToBeDrained); + mNotifyPipelineDrain = false; + mStreamIdsToBeDrained.clear(); + } } res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout); diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h index 4ed6d9dd6b..5c0f570ad8 100644 --- a/services/camera/libcameraservice/device3/Camera3Device.h +++ b/services/camera/libcameraservice/device3/Camera3Device.h @@ -285,6 +285,8 @@ class Camera3Device : status_t dump(int fd); status_t close(); + void signalPipelineDrain(const std::vector& streamIds); + // method to extract buffer's unique ID // return pair of (newlySeenBuffer?, bufferId) std::pair getBufferId(const buffer_handle_t& buf, int streamId); @@ -372,6 +374,8 @@ class Camera3Device : // Buffers given to HAL through requestStreamBuffer API std::mutex mRequestedBuffersLock; std::unordered_map mRequestedBuffers; + + uint32_t mNextStreamConfigCounter = 1; }; sp mInterface; @@ -415,6 +419,7 @@ class Camera3Device : // get by (underlying) vector index sp operator[] (size_t index); size_t size() const; + std::vector getStreamIds(); void clear(); private: @@ -808,6 +813,8 @@ class Camera3Device : mRequestLatency.dump(fd, name); } + void signalPipelineDrain(const std::vector& streamIds); + protected: virtual bool threadLoop(); @@ -917,12 +924,13 @@ class Camera3Device : bool mReconfigured; - // Used by waitIfPaused, waitForNextRequest, and waitUntilPaused + // Used by waitIfPaused, waitForNextRequest, waitUntilPaused, and signalPipelineDrain Mutex mPauseLock; bool mDoPause; Condition mDoPauseSignal; bool mPaused; - Condition mPausedSignal; + bool mNotifyPipelineDrain; + std::vector mStreamIdsToBeDrained; sp mPrevRequest; int32_t mPrevTriggers;