From 3e2a2991783a4d0067b532ad6d0e607a756ac194 Mon Sep 17 00:00:00 2001 From: Robert Carr Date: Fri, 11 Jun 2021 13:42:55 -0700 Subject: Avoid traversal in tunnel mode reporter We can just track whether we have a sideband stream or not using a counter. Test: Existing tests pass. simpleperf Bug: 186200583 Change-Id: I40b0217c186517fc67fe55d8aecf26198561bc39 --- services/surfaceflinger/BufferStateLayer.cpp | 8 +++++++- services/surfaceflinger/Layer.cpp | 5 +++++ services/surfaceflinger/SurfaceFlinger.cpp | 2 +- services/surfaceflinger/SurfaceFlinger.h | 1 + services/surfaceflinger/TunnelModeEnabledReporter.cpp | 11 ++--------- services/surfaceflinger/TunnelModeEnabledReporter.h | 7 +++++-- .../tests/unittests/TunnelModeEnabledReporterTest.cpp | 17 +++++++++++++---- 7 files changed, 34 insertions(+), 17 deletions(-) diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index a3b7b13d4c..6b5cf04536 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -540,10 +540,16 @@ bool BufferStateLayer::setApi(int32_t api) { bool BufferStateLayer::setSidebandStream(const sp& sidebandStream) { if (mDrawingState.sidebandStream == sidebandStream) return false; + + if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) { + mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount(); + } else if (sidebandStream != nullptr) { + mFlinger->mTunnelModeEnabledReporter->incrementTunnelModeCount(); + } + mDrawingState.sidebandStream = sidebandStream; mDrawingState.modified = true; setTransactionFlags(eTransactionNeeded); - if (!mSidebandStreamChanged.exchange(true)) { // mSidebandStreamChanged was false mFlinger->signalLayerUpdate(); diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6c9905e7da..4af950631d 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -70,6 +70,7 @@ #include "MonitoredProducer.h" #include "SurfaceFlinger.h" #include "TimeStats/TimeStats.h" +#include "TunnelModeEnabledReporter.h" #include "input/InputWindow.h" #define DEBUG_RESIZE 0 @@ -172,6 +173,10 @@ Layer::~Layer() { mFrameTracker.logAndResetStats(mName); mFlinger->onLayerDestroyed(this); + + if (mDrawingState.sidebandStream != nullptr) { + mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount(); + } } LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp client, std::string name, diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 26581a07ea..10ec10d2a4 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -342,6 +342,7 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory, SkipInitializationTag) mEventQueue(mFactory.createMessageQueue()), mCompositionEngine(mFactory.createCompositionEngine()), mHwcServiceName(base::GetProperty("debug.sf.hwc_service_name"s, "default"s)), + mTunnelModeEnabledReporter(new TunnelModeEnabledReporter()), mInternalDisplayDensity(getDensityFromProperty("ro.sf.lcd_density", true)), mEmulatedDisplayDensity(getDensityFromProperty("qemu.sf.lcd_density", false)) { ALOGI("Using HWComposer service: %s", mHwcServiceName.c_str()); @@ -3169,7 +3170,6 @@ void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) { mRegionSamplingThread = new RegionSamplingThread(*this, RegionSamplingThread::EnvironmentTimingTunables()); mFpsReporter = new FpsReporter(*mFrameTimeline, *this); - mTunnelModeEnabledReporter = new TunnelModeEnabledReporter(*this); // Dispatch a mode change request for the primary display on scheduler // initialization, so that the EventThreads always contain a reference to a // prior configuration. diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 81f569ae9b..7a9c30f930 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -364,6 +364,7 @@ private: // For unit tests friend class TestableSurfaceFlinger; friend class TransactionApplicationTest; + friend class TunnelModeEnabledReporterTest; using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate; using VsyncModulator = scheduler::VsyncModulator; diff --git a/services/surfaceflinger/TunnelModeEnabledReporter.cpp b/services/surfaceflinger/TunnelModeEnabledReporter.cpp index 48e321635b..4497cafa58 100644 --- a/services/surfaceflinger/TunnelModeEnabledReporter.cpp +++ b/services/surfaceflinger/TunnelModeEnabledReporter.cpp @@ -26,17 +26,10 @@ namespace android { -TunnelModeEnabledReporter::TunnelModeEnabledReporter(SurfaceFlinger& flinger) : mFlinger(flinger) {} +TunnelModeEnabledReporter::TunnelModeEnabledReporter() {} void TunnelModeEnabledReporter::updateTunnelModeStatus() { - bool tunnelModeEnabled = false; - mFlinger.mCurrentState.traverse([&](Layer* layer) { - auto& state = layer->getDrawingState(); - if (state.sidebandStream != nullptr) { - tunnelModeEnabled = true; - return; - } - }); + bool tunnelModeEnabled = mTunnelModeCount > 0; dispatchTunnelModeEnabled(tunnelModeEnabled); } diff --git a/services/surfaceflinger/TunnelModeEnabledReporter.h b/services/surfaceflinger/TunnelModeEnabledReporter.h index d55507a8e9..935502a6e1 100644 --- a/services/surfaceflinger/TunnelModeEnabledReporter.h +++ b/services/surfaceflinger/TunnelModeEnabledReporter.h @@ -29,7 +29,7 @@ class SurfaceFlinger; class TunnelModeEnabledReporter : public IBinder::DeathRecipient { public: - TunnelModeEnabledReporter(SurfaceFlinger& flinger); + TunnelModeEnabledReporter(); // Checks if there is a tunnel mode enabled state change and if so, dispatches the updated // tunnel mode enabled/disabled state to the registered listeners @@ -49,6 +49,9 @@ public: // Deregisters a TunnelModeEnabled listener void removeListener(const sp& listener); + inline void incrementTunnelModeCount() { mTunnelModeCount++; } + inline void decrementTunnelModeCount() { mTunnelModeCount--; } + private: mutable std::mutex mMutex; struct WpHash { @@ -57,10 +60,10 @@ private: } }; - SurfaceFlinger& mFlinger; std::unordered_map, sp, WpHash> mListeners GUARDED_BY(mMutex); bool mTunnelModeEnabled GUARDED_BY(mMutex) = false; + uint32_t mTunnelModeCount = 0; }; } // namespace android diff --git a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp index d7d7ea77d6..e4f74694f7 100644 --- a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp +++ b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp @@ -27,6 +27,7 @@ #include "TunnelModeEnabledReporter.h" #include "mock/DisplayHardware/MockComposer.h" #include "mock/MockEventThread.h" +#include "mock/MockMessageQueue.h" namespace android { @@ -71,15 +72,20 @@ protected: sp mTunnelModeEnabledListener = new TestableTunnelModeEnabledListener(); sp mTunnelModeEnabledReporter = - new TunnelModeEnabledReporter(*(mFlinger.flinger())); + new TunnelModeEnabledReporter(); + + mock::MessageQueue* mMessageQueue = new mock::MessageQueue(); }; TunnelModeEnabledReporterTest::TunnelModeEnabledReporterTest() { const ::testing::TestInfo* const test_info = ::testing::UnitTest::GetInstance()->current_test_info(); ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name()); + + mFlinger.mutableEventQueue().reset(mMessageQueue); setupScheduler(); mFlinger.setupComposer(std::make_unique()); + mFlinger.flinger()->mTunnelModeEnabledReporter = mTunnelModeEnabledReporter; mTunnelModeEnabledReporter->dispatchTunnelModeEnabled(false); } @@ -156,16 +162,18 @@ TEST_F(TunnelModeEnabledReporterTest, callsNewListenerWithFreshInformation) { sp stream = NativeHandle::create(reinterpret_cast(DEFAULT_SIDEBAND_STREAM), false); - mFlinger.setLayerSidebandStream(layer, stream); + layer->setSidebandStream(stream); mFlinger.mutableCurrentState().layersSortedByZ.add(layer); mTunnelModeEnabledReporter->updateTunnelModeStatus(); mTunnelModeEnabledReporter->addListener(mTunnelModeEnabledListener); EXPECT_EQ(true, mTunnelModeEnabledListener->mTunnelModeEnabled); mTunnelModeEnabledReporter->removeListener(mTunnelModeEnabledListener); - mFlinger.mutableCurrentState().layersSortedByZ.remove(layer); + layer = nullptr; + mTunnelModeEnabledReporter->updateTunnelModeStatus(); mTunnelModeEnabledReporter->addListener(mTunnelModeEnabledListener); + EXPECT_EQ(false, mTunnelModeEnabledListener->mTunnelModeEnabled); } @@ -178,7 +186,7 @@ TEST_F(TunnelModeEnabledReporterTest, layerWithSidebandStreamTriggersUpdate) { sp stream = NativeHandle::create(reinterpret_cast(DEFAULT_SIDEBAND_STREAM), false); - mFlinger.setLayerSidebandStream(layerWithSidebandStream, stream); + layerWithSidebandStream->setSidebandStream(stream); mFlinger.mutableCurrentState().layersSortedByZ.add(simpleLayer); mFlinger.mutableCurrentState().layersSortedByZ.add(layerWithSidebandStream); @@ -186,6 +194,7 @@ TEST_F(TunnelModeEnabledReporterTest, layerWithSidebandStreamTriggersUpdate) { EXPECT_EQ(true, mTunnelModeEnabledListener->mTunnelModeEnabled); mFlinger.mutableCurrentState().layersSortedByZ.remove(layerWithSidebandStream); + layerWithSidebandStream = nullptr; mTunnelModeEnabledReporter->updateTunnelModeStatus(); EXPECT_EQ(false, mTunnelModeEnabledListener->mTunnelModeEnabled); } -- cgit v1.2.3-59-g8ed1b