Loading libs/gui/include/gui/BLASTBufferQueue.h +4 −4 Original line number Diff line number Diff line Loading @@ -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); Loading libs/gui/tests/BLASTBufferQueue_test.cpp +9 −10 Original line number Diff line number Diff line Loading @@ -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 { Loading services/surfaceflinger/SurfaceFlinger.cpp +26 −29 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); Loading services/surfaceflinger/SurfaceFlinger.h +0 −3 Original line number Diff line number Diff line Loading @@ -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); Loading services/surfaceflinger/tests/LayerCallback_test.cpp +44 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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; Loading Loading @@ -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 Loading
libs/gui/include/gui/BLASTBufferQueue.h +4 −4 Original line number Diff line number Diff line Loading @@ -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); Loading
libs/gui/tests/BLASTBufferQueue_test.cpp +9 −10 Original line number Diff line number Diff line Loading @@ -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 { Loading
services/surfaceflinger/SurfaceFlinger.cpp +26 −29 Original line number Diff line number Diff line Loading @@ -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) { Loading @@ -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(); Loading
services/surfaceflinger/SurfaceFlinger.h +0 −3 Original line number Diff line number Diff line Loading @@ -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); Loading
services/surfaceflinger/tests/LayerCallback_test.cpp +44 −0 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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; Loading Loading @@ -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