Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7447f0fc authored by Yin-Chia Yeh's avatar Yin-Chia Yeh
Browse files

Camera: implement signalPipelineDrain API

SignalPipelineDrain will be sent after the request
thread has stopped sending capture requests so
HAL can expect no more capture requests are sent
after they receive this call.

Test: CTS
Bug: 109829698
Change-Id: I6f75c28ff0998a8edc80f9af9ebe727c585ea6e9
parent 4ee35438
Loading
Loading
Loading
Loading
+92 −14
Original line number Diff line number Diff line
@@ -1619,6 +1619,15 @@ void Camera3Device::StreamSet::clear() {
    return mData.clear();
}

std::vector<int> Camera3Device::StreamSet::getStreamIds() {
    std::lock_guard<std::mutex> lock(mLock);
    std::vector<int> streamIds(mData.size());
    for (size_t i = 0; i < mData.size(); i++) {
        streamIds[i] = mData.keyAt(i);
    }
    return streamIds;
}

status_t Camera3Device::createStream(sp<Surface> 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,19 +3917,17 @@ 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;
            });
            };

    auto postprocConfigStream34 = [&finalConfiguration, &finalConfiguration3_4]
            (hardware::Return<void>& err) -> status_t {
                if (!err.isOk()) {
                    ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
                    return DEAD_OBJECT;
@@ -3923,6 +3936,31 @@ status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *
                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;
        }
    } 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
        ALOGV("%s: v3.3 device found", __FUNCTION__);
@@ -4292,6 +4330,20 @@ status_t Camera3Device::HalInterface::close() {
    return res;
}

void Camera3Device::HalInterface::signalPipelineDrain(const std::vector<int>& 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<std::pair<int32_t, int32_t>>* out) {
    std::lock_guard<std::mutex> lock(mInflightLock);
@@ -4418,6 +4470,7 @@ Camera3Device::RequestThread::RequestThread(wp<Camera3Device> 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<int>& 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<Camera3Device::CaptureRequest>
                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);
+10 −2
Original line number Diff line number Diff line
@@ -285,6 +285,8 @@ class Camera3Device :
        status_t dump(int fd);
        status_t close();

        void signalPipelineDrain(const std::vector<int>& streamIds);

        // method to extract buffer's unique ID
        // return pair of (newlySeenBuffer?, bufferId)
        std::pair<bool, uint64_t> 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<uint64_t, buffer_handle_t*> mRequestedBuffers;

        uint32_t mNextStreamConfigCounter = 1;
    };

    sp<HalInterface> mInterface;
@@ -415,6 +419,7 @@ class Camera3Device :
        // get by (underlying) vector index
        sp<camera3::Camera3OutputStreamInterface> operator[] (size_t index);
        size_t size() const;
        std::vector<int> getStreamIds();
        void clear();

      private:
@@ -808,6 +813,8 @@ class Camera3Device :
            mRequestLatency.dump(fd, name);
        }

        void signalPipelineDrain(const std::vector<int>& 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<int>   mStreamIdsToBeDrained;

        sp<CaptureRequest> mPrevRequest;
        int32_t            mPrevTriggers;