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

Commit af15fabf authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Pass an apply token to BBQ

Allow BBQ to use a passed in apply token for applying transactions. This
allows us to order transactions when a BBQ is recreated by sharing
the same apply token between the BBQs.

Flag: EXEMPT bugfix
Test: presubmit
Fixes: 353332587
Change-Id: Icbadce96e9f72f13a26c4430cdfadf6ea315ce84
parent 18285555
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1266,6 +1266,11 @@ void BLASTBufferQueue::setTransactionHangCallback(
    mTransactionHangCallback = std::move(callback);
}

void BLASTBufferQueue::setApplyToken(sp<IBinder> applyToken) {
    std::lock_guard _lock{mMutex};
    mApplyToken = std::move(applyToken);
}

#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)

BLASTBufferQueue::BufferReleaseReader::BufferReleaseReader(
+2 −2
Original line number Diff line number Diff line
@@ -143,7 +143,7 @@ public:
     * indicates the reason for the hang.
     */
    void setTransactionHangCallback(std::function<void(const std::string&)> callback);

    void setApplyToken(sp<IBinder>);
    virtual ~BLASTBufferQueue();

    void onFirstRef() override;
@@ -272,7 +272,7 @@ private:

    // Queues up transactions using this token in SurfaceFlinger. This prevents queued up
    // transactions from other parts of the client from blocking this transaction.
    const sp<IBinder> mApplyToken GUARDED_BY(mMutex) = sp<BBinder>::make();
    sp<IBinder> mApplyToken GUARDED_BY(mMutex) = sp<BBinder>::make();

    // Guards access to mDequeueTimestamps since we cannot hold to mMutex in onFrameDequeued or
    // we will deadlock.
+67 −0
Original line number Diff line number Diff line
@@ -186,6 +186,10 @@ public:
        mBlastBufferQueueAdapter->mergeWithNextTransaction(merge, frameNumber);
    }

    void setApplyToken(sp<IBinder> applyToken) {
        mBlastBufferQueueAdapter->setApplyToken(std::move(applyToken));
    }

private:
    sp<TestBLASTBufferQueue> mBlastBufferQueueAdapter;
};
@@ -511,6 +515,69 @@ TEST_F(BLASTBufferQueueTest, TripleBuffering) {
    adapter.waitForCallbacks();
}

class WaitForCommittedCallback {
public:
    WaitForCommittedCallback() = default;
    ~WaitForCommittedCallback() = default;

    void wait() {
        std::unique_lock lock(mMutex);
        cv.wait(lock, [this] { return mCallbackReceived; });
    }

    void notify() {
        std::unique_lock lock(mMutex);
        mCallbackReceived = true;
        cv.notify_one();
        mCallbackReceivedTimeStamp = std::chrono::system_clock::now();
    }
    auto getCallback() {
        return [this](void* /* unused context */, nsecs_t /* latchTime */,
                      const sp<Fence>& /* presentFence */,
                      const std::vector<SurfaceControlStats>& /* stats */) { notify(); };
    }
    std::chrono::time_point<std::chrono::system_clock> mCallbackReceivedTimeStamp;

private:
    std::mutex mMutex;
    std::condition_variable cv;
    bool mCallbackReceived = false;
};

TEST_F(BLASTBufferQueueTest, setApplyToken) {
    sp<IBinder> applyToken = sp<BBinder>::make();
    WaitForCommittedCallback firstTransaction;
    WaitForCommittedCallback secondTransaction;
    {
        BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
        adapter.setApplyToken(applyToken);
        sp<IGraphicBufferProducer> igbProducer;
        setUpProducer(adapter, igbProducer);

        Transaction t;
        t.addTransactionCommittedCallback(firstTransaction.getCallback(), nullptr);
        adapter.mergeWithNextTransaction(&t, 1);
        queueBuffer(igbProducer, 127, 127, 127,
                    /*presentTimeDelay*/ std::chrono::nanoseconds(500ms).count());
    }
    {
        BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
        adapter.setApplyToken(applyToken);
        sp<IGraphicBufferProducer> igbProducer;
        setUpProducer(adapter, igbProducer);

        Transaction t;
        t.addTransactionCommittedCallback(secondTransaction.getCallback(), nullptr);
        adapter.mergeWithNextTransaction(&t, 1);
        queueBuffer(igbProducer, 127, 127, 127, /*presentTimeDelay*/ 0);
    }

    firstTransaction.wait();
    secondTransaction.wait();
    EXPECT_GT(secondTransaction.mCallbackReceivedTimeStamp,
              firstTransaction.mCallbackReceivedTimeStamp);
}

TEST_F(BLASTBufferQueueTest, SetCrop_Item) {
    uint8_t r = 255;
    uint8_t g = 0;