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

Commit 28eebbfc authored by Yin-Chia Yeh's avatar Yin-Chia Yeh
Browse files

Camera: add interface to evict obsolete buffer caches

Test: fix CTS ReprocessCaptureTest
Bug: 34461678
Change-Id: Icde654b0c8423c31d7d39d180913ffa374e7de3c
parent 3368520b
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -183,6 +183,11 @@ interface ICameraDeviceSession {
     * client, the HAL must process the requests in order of lowest index to
     * highest index.
     *
     * The cachesToRemove argument contains a list of buffer caches (see
     * StreamBuffer document for more information on buffer cache) to be removed
     * by camera HAL. Camera HAL must remove these cache entries whether or not
     * this method returns OK.
     *
     * The actual request processing is asynchronous, with the results of
     * capture being returned by the HAL through the processCaptureResult()
     * call. This call requires the result metadata to be available, but output
@@ -238,7 +243,8 @@ interface ICameraDeviceSession {
     *     that HAL processed successfully before HAL runs into an error.
     *
     */
    processCaptureRequest(vec<CaptureRequest> requests)
    processCaptureRequest(vec<CaptureRequest> requests,
            vec<BufferCache> cachesToRemove)
            generates (Status status, uint32_t numRequestProcessed);

    /**
+25 −1
Original line number Diff line number Diff line
@@ -678,8 +678,32 @@ void CameraDeviceSession::cleanupBuffersLocked(int id) {
    mCirculatingBuffers.erase(id);
}

void CameraDeviceSession::updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove) {
    Mutex::Autolock _l(mInflightLock);
    for (auto& cache : cachesToRemove) {
        auto cbsIt = mCirculatingBuffers.find(cache.streamId);
        if (cbsIt == mCirculatingBuffers.end()) {
            // The stream could have been removed
            continue;
        }
        CirculatingBuffers& cbs = cbsIt->second;
        auto it = cbs.find(cache.bufferId);
        if (it != cbs.end()) {
            sHandleImporter.freeBuffer(it->second);
            cbs.erase(it);
        } else {
            ALOGE("%s: stream %d buffer %" PRIu64 " is not cached",
                    __FUNCTION__, cache.streamId, cache.bufferId);
        }
    }
}

Return<void> CameraDeviceSession::processCaptureRequest(
        const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb)  {
        const hidl_vec<CaptureRequest>& requests,
        const hidl_vec<BufferCache>& cachesToRemove,
        processCaptureRequest_cb _hidl_cb)  {
    updateBufferCaches(cachesToRemove);

    uint32_t numRequestProcessed = 0;
    Status s = Status::OK;
    for (size_t i = 0; i < requests.size(); i++, numRequestProcessed++) {
+5 −1
Original line number Diff line number Diff line
@@ -85,7 +85,9 @@ struct CameraDeviceSession : public ICameraDeviceSession, private camera3_callba
    Return<void> configureStreams(
            const StreamConfiguration& requestedConfiguration, configureStreams_cb _hidl_cb) override;
    Return<void> processCaptureRequest(
            const hidl_vec<CaptureRequest>& requests, processCaptureRequest_cb _hidl_cb) override;
            const hidl_vec<CaptureRequest>& requests,
            const hidl_vec<BufferCache>& cachesToRemove,
            processCaptureRequest_cb _hidl_cb) override;
    Return<Status> flush() override;
    Return<void> close() override;

@@ -234,6 +236,8 @@ private:

    void cleanupBuffersLocked(int id);

    void updateBufferCaches(const hidl_vec<BufferCache>& cachesToRemove);

    Status processOneCaptureRequest(const CaptureRequest& request);
    /**
     * Static callback forwarding methods from HAL to instance
+22 −0
Original line number Diff line number Diff line
@@ -958,3 +958,25 @@ struct CaptureResult {
    uint32_t partialResult;

};

/**
 * BufferCache:
 *
 * A list of cached bufferIds associated with a certain stream.
 * Buffers are passed between camera service and camera HAL via bufferId except
 * the first time a new buffer is being passed to HAL in CaptureRequest. Camera
 * service and camera HAL therefore need to maintain a cached map of bufferId
 * and corresponing native handle.
 *
 */
struct BufferCache {
    /**
     * The ID of the stream this list is associated with.
     */
    int32_t streamId;

    /**
     * A cached buffer ID associated with streamId.
     */
    uint64_t bufferId;
};
+10 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ using ::android::hardware::camera::common::V1_0::TorchModeStatus;
using ::android::hardware::camera::provider::V2_4::ICameraProvider;
using ::android::hardware::camera::provider::V2_4::ICameraProviderCallback;
using ::android::hardware::camera::device::V3_2::ICameraDevice;
using ::android::hardware::camera::device::V3_2::BufferCache;
using ::android::hardware::camera::device::V3_2::CaptureRequest;
using ::android::hardware::camera::device::V3_2::CaptureResult;
using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
@@ -2481,8 +2482,10 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) {

            Status status = Status::INTERNAL_ERROR;
            uint32_t numRequestProcessed = 0;
            hidl_vec<BufferCache> cachesToRemove;
            Return<void> returnStatus = session->processCaptureRequest(
                    {request},
                    cachesToRemove,
                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
                        status = s;
                        numRequestProcessed = n;
@@ -2513,6 +2516,7 @@ TEST_F(CameraHidlTest, processCaptureRequestPreview) {

            returnStatus = session->processCaptureRequest(
                    {request},
                    cachesToRemove,
                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
                        status = s;
                        numRequestProcessed = n;
@@ -2579,8 +2583,10 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidSinglePreview) {
            //Settings were not correctly initialized, we should fail here
            Status status = Status::OK;
            uint32_t numRequestProcessed = 0;
            hidl_vec<BufferCache> cachesToRemove;
            Return<void> ret = session->processCaptureRequest(
                    {request},
                    cachesToRemove,
                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
                        status = s;
                        numRequestProcessed = n;
@@ -2632,8 +2638,10 @@ TEST_F(CameraHidlTest, processCaptureRequestInvalidBuffer) {
            //Output buffers are missing, we should fail here
            Status status = Status::OK;
            uint32_t numRequestProcessed = 0;
            hidl_vec<BufferCache> cachesToRemove;
            ret = session->processCaptureRequest(
                    {request},
                    cachesToRemove,
                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
                        status = s;
                        numRequestProcessed = n;
@@ -2701,8 +2709,10 @@ TEST_F(CameraHidlTest, flushPreviewRequest) {

            Status status = Status::INTERNAL_ERROR;
            uint32_t numRequestProcessed = 0;
            hidl_vec<BufferCache> cachesToRemove;
            ret = session->processCaptureRequest(
                    {request},
                    cachesToRemove,
                    [&status, &numRequestProcessed] (auto s, uint32_t n) {
                        status = s;
                        numRequestProcessed = n;