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

Commit 695f28e4 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Invoke commit callback after latch buffers"

parents 3678058c 6b9ffea5
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -88,9 +88,9 @@ public:
    void onFrameDequeued(const uint64_t) override;
    void onFrameCancelled(const uint64_t) override;

    virtual void transactionCommittedCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
    void transactionCommittedCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
                                      const std::vector<SurfaceControlStats>& stats);
    void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
    virtual void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
                                     const std::vector<SurfaceControlStats>& stats);
    void releaseBufferCallback(const ReleaseCallbackId& id, const sp<Fence>& releaseFence,
                               std::optional<uint32_t> currentMaxAcquiredBufferCount);
+9 −10
Original line number Diff line number Diff line
@@ -72,31 +72,30 @@ public:
                         int height, int32_t format)
          : BLASTBufferQueue(name, surface, width, height, format) {}

    void transactionCommittedCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
    void transactionCallback(nsecs_t latchTime, const sp<Fence>& presentFence,
                             const std::vector<SurfaceControlStats>& stats) override {
        BLASTBufferQueue::transactionCommittedCallback(latchTime, presentFence, stats);

        BLASTBufferQueue::transactionCallback(latchTime, presentFence, stats);
        uint64_t frameNumber = stats[0].frameEventStats.frameNumber;

        {
            std::unique_lock lock{frameNumberMutex};
            mLastTransactionCommittedFrameNumber = frameNumber;
            mCommittedCV.notify_all();
            mLastTransactionFrameNumber = frameNumber;
            mWaitForCallbackCV.notify_all();
        }
    }

    void waitForCallback(int64_t frameNumber) {
        std::unique_lock lock{frameNumberMutex};
        // Wait until all but one of the submitted buffers have been released.
        while (mLastTransactionCommittedFrameNumber < frameNumber) {
            mCommittedCV.wait(lock);
        while (mLastTransactionFrameNumber < frameNumber) {
            mWaitForCallbackCV.wait(lock);
        }
    }

private:
    std::mutex frameNumberMutex;
    std::condition_variable mCommittedCV;
    int64_t mLastTransactionCommittedFrameNumber = -1;
    std::condition_variable mWaitForCallbackCV;
    int64_t mLastTransactionFrameNumber = -1;
};

class BLASTBufferQueueHelper {
+26 −29
Original line number Diff line number Diff line
@@ -1970,9 +1970,34 @@ bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expected

        mFrameTimeline->setSfWakeUp(vsyncId, frameTime, Fps::fromPeriodNsecs(stats.vsyncPeriod));

        mustComposite |= flushAndCommitTransactions();
        bool needsTraversal = false;
        if (clearTransactionFlags(eTransactionFlushNeeded)) {
            needsTraversal = flushTransactionQueues();
        }

        const bool shouldCommit =
                (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
        if (shouldCommit) {
            commitTransactions();
        }

        if (transactionFlushNeeded()) {
            setTransactionFlags(eTransactionFlushNeeded);
        }

        mustComposite |= shouldCommit;
        mustComposite |= latchBuffers();

        // This has to be called after latchBuffers because we want to include the layers that have
        // been latched in the commit callback
        if (!needsTraversal) {
            // Invoke empty transaction callbacks early.
            mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
        } else {
            // Invoke OnCommit callbacks.
            mTransactionCallbackInvoker.sendCallbacks(true /* onCommitOnly */);
        }

        updateLayerGeometry();

        if (tracePreComposition) {
@@ -1999,34 +2024,6 @@ bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expected
    return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
}

bool SurfaceFlinger::flushAndCommitTransactions() {
    ATRACE_CALL();

    bool needsTraversal = false;
    if (clearTransactionFlags(eTransactionFlushNeeded)) {
        needsTraversal = flushTransactionQueues();
    }

    const bool shouldCommit = (getTransactionFlags() & ~eTransactionFlushNeeded) || needsTraversal;
    if (shouldCommit) {
        commitTransactions();
    }

    if (!needsTraversal) {
        // Invoke empty transaction callbacks early.
        mTransactionCallbackInvoker.sendCallbacks(false /* onCommitOnly */);
    } else {
        // Invoke OnCommit callbacks.
        mTransactionCallbackInvoker.sendCallbacks(true /* onCommitOnly */);
    }

    if (transactionFlushNeeded()) {
        setTransactionFlags(eTransactionFlushNeeded);
    }

    return shouldCommit;
}

void SurfaceFlinger::composite(nsecs_t frameTime) {
    ATRACE_CALL();

+0 −3
Original line number Diff line number Diff line
@@ -684,9 +684,6 @@ private:
            const std::optional<scheduler::RefreshRateConfigs::Policy>& policy, bool overridePolicy)
            EXCLUDES(mStateLock);

    // Returns whether transactions were committed.
    bool flushAndCommitTransactions() EXCLUDES(mStateLock);

    void commitTransactions() EXCLUDES(mStateLock);
    void commitTransactionsLocked(uint32_t transactionFlags) REQUIRES(mStateLock);
    void doCommitTransactions() REQUIRES(mStateLock);
+44 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ using namespace std::chrono_literals;
namespace android {

using android::hardware::graphics::common::V1_1::BufferUsage;
using SCHash = SurfaceComposerClient::SCHash;

::testing::Environment* const binderEnv =
        ::testing::AddGlobalTestEnvironment(new BinderEnvironment());
@@ -102,6 +103,24 @@ public:
        }
    }

    static void waitForCommitCallback(
            CallbackHelper& helper,
            const std::unordered_set<sp<SurfaceControl>, SCHash>& committedSc) {
        CallbackData callbackData;
        ASSERT_NO_FATAL_FAILURE(helper.getCallbackData(&callbackData));

        const auto& surfaceControlStats = callbackData.surfaceControlStats;

        ASSERT_EQ(surfaceControlStats.size(), committedSc.size()) << "wrong number of surfaces";

        for (const auto& stats : surfaceControlStats) {
            ASSERT_NE(stats.surfaceControl, nullptr) << "returned null surface control";

            const auto& expectedSc = committedSc.find(stats.surfaceControl);
            ASSERT_NE(expectedSc, committedSc.end()) << "unexpected surface control";
        }
    }

    DisplayEventReceiver mDisplayEventReceiver;
    int mEpollFd;

@@ -1085,4 +1104,29 @@ TEST_F(LayerCallbackTest, DISABLED_NonBufferLayerStateChanges) {
    EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
}

TEST_F(LayerCallbackTest, CommitCallbackOffscreenLayer) {
    sp<SurfaceControl> layer;
    ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
    sp<SurfaceControl> offscreenLayer =
            createSurface(mClient, "Offscreen Layer", 0, 0, PIXEL_FORMAT_RGBA_8888,
                          ISurfaceComposerClient::eFXSurfaceBufferState, layer.get());

    Transaction transaction;
    CallbackHelper callback;
    int err = fillTransaction(transaction, &callback, layer, true);
    err |= fillTransaction(transaction, &callback, offscreenLayer, true);
    if (err) {
        GTEST_SUCCEED() << "test not supported";
        return;
    }

    transaction.reparent(offscreenLayer, nullptr)
            .addTransactionCommittedCallback(callback.function, callback.getContext());
    transaction.apply();

    std::unordered_set<sp<SurfaceControl>, SCHash> committedSc;
    committedSc.insert(layer);
    committedSc.insert(offscreenLayer);
    EXPECT_NO_FATAL_FAILURE(waitForCommitCallback(callback, committedSc));
}
} // namespace android