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

Commit ff1b1d26 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Automerger Merge Worker
Browse files

Merge "Invoke sync transaction callback if overwritten" into tm-dev am: 00b449e7

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/native/+/17239278

Change-Id: I58d44674e127580c102eb433046f6f816c67bf9d
parents 8c473376 00b449e7
Loading
Loading
Loading
Loading
+28 −7
Original line number Diff line number Diff line
@@ -184,6 +184,10 @@ BLASTBufferQueue::~BLASTBufferQueue() {
    mergePendingTransactions(&t, std::numeric_limits<uint64_t>::max() /* frameNumber */);
    // All transactions on our apply token are one-way. See comment on mAppliedLastTransaction
    t.setApplyToken(mApplyToken).apply(false, true);

    if (mTransactionReadyCallback) {
        mTransactionReadyCallback(mSyncTransaction);
    }
}

void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width, uint32_t height,
@@ -702,7 +706,19 @@ void BLASTBufferQueue::syncNextTransaction(
        std::function<void(SurfaceComposerClient::Transaction*)> callback,
        bool acquireSingleBuffer) {
    BBQ_TRACE();

    std::function<void(SurfaceComposerClient::Transaction*)> prevCallback = nullptr;
    SurfaceComposerClient::Transaction* prevTransaction = nullptr;

    {
        std::lock_guard _lock{mMutex};
        // We're about to overwrite the previous call so we should invoke that callback
        // immediately.
        if (mTransactionReadyCallback) {
            prevCallback = mTransactionReadyCallback;
            prevTransaction = mSyncTransaction;
        }

        mTransactionReadyCallback = callback;
        if (callback) {
            mSyncTransaction = new SurfaceComposerClient::Transaction();
@@ -712,6 +728,11 @@ void BLASTBufferQueue::syncNextTransaction(
        mAcquireSingleBuffer = mTransactionReadyCallback ? acquireSingleBuffer : true;
    }

    if (prevCallback) {
        prevCallback(prevTransaction);
    }
}

void BLASTBufferQueue::stopContinuousSyncTransaction() {
    std::function<void(SurfaceComposerClient::Transaction*)> prevCallback = nullptr;
    SurfaceComposerClient::Transaction* prevTransaction = nullptr;
+28 −0
Original line number Diff line number Diff line
@@ -1083,6 +1083,34 @@ TEST_F(BLASTBufferQueueTest, SyncNextTransactionAcquireMultipleBuffers) {
            checkScreenCapture(255, 0, 0, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
}

TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
    std::mutex mutex;
    std::condition_variable callbackReceivedCv;
    bool receivedCallback = false;

    BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
    ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
    auto callback = [&](Transaction*) {
        std::unique_lock<std::mutex> lock(mutex);
        receivedCallback = true;
        callbackReceivedCv.notify_one();
    };
    adapter.syncNextTransaction(callback);
    ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());

    auto callback2 = [](Transaction*) {};
    adapter.syncNextTransaction(callback2);

    std::unique_lock<std::mutex> lock(mutex);
    if (!receivedCallback) {
        ASSERT_NE(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
                  std::cv_status::timeout)
                << "did not receive callback";
    }

    ASSERT_TRUE(receivedCallback);
}

// This test will currently fail because the old surfacecontrol will steal the last presented buffer
// until the old surface control is destroyed. This is not necessarily a bug but to document a
// limitation with the update API and to test any changes to make the api more robust. The current