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
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index a3b7b13..6b5cf04 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -540,10 +540,16 @@
 
 bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& 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 6c9905e..4af9506 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 @@
 
     mFrameTracker.logAndResetStats(mName);
     mFlinger->onLayerDestroyed(this);
+
+    if (mDrawingState.sidebandStream != nullptr) {
+        mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
+    }
 }
 
 LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, sp<Client> client, std::string name,
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 26581a0..10ec10d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -342,6 +342,7 @@
         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 @@
     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 81f569a..7a9c30f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -364,6 +364,7 @@
     // 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 48e3216..4497caf 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 d55507a..935502a 100644
--- a/services/surfaceflinger/TunnelModeEnabledReporter.h
+++ b/services/surfaceflinger/TunnelModeEnabledReporter.h
@@ -29,7 +29,7 @@
 
 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 @@
     // Deregisters a TunnelModeEnabled listener
     void removeListener(const sp<gui::ITunnelModeEnabledListener>& listener);
 
+    inline void incrementTunnelModeCount() { mTunnelModeCount++; }
+    inline void decrementTunnelModeCount() { mTunnelModeCount--; }
+
 private:
     mutable std::mutex mMutex;
     struct WpHash {
@@ -57,10 +60,10 @@
         }
     };
 
-    SurfaceFlinger& mFlinger;
     std::unordered_map<wp<IBinder>, sp<gui::ITunnelModeEnabledListener>, 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 d7d7ea7..e4f7469 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 @@
     sp<TestableTunnelModeEnabledListener> mTunnelModeEnabledListener =
             new TestableTunnelModeEnabledListener();
     sp<TunnelModeEnabledReporter> 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<Hwc2::mock::Composer>());
+    mFlinger.flinger()->mTunnelModeEnabledReporter = mTunnelModeEnabledReporter;
     mTunnelModeEnabledReporter->dispatchTunnelModeEnabled(false);
 }
 
@@ -156,16 +162,18 @@
     sp<NativeHandle> stream =
             NativeHandle::create(reinterpret_cast<native_handle_t*>(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 @@
     sp<NativeHandle> stream =
             NativeHandle::create(reinterpret_cast<native_handle_t*>(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 @@
     EXPECT_EQ(true, mTunnelModeEnabledListener->mTunnelModeEnabled);
 
     mFlinger.mutableCurrentState().layersSortedByZ.remove(layerWithSidebandStream);
+    layerWithSidebandStream = nullptr;
     mTunnelModeEnabledReporter->updateTunnelModeStatus();
     EXPECT_EQ(false, mTunnelModeEnabledListener->mTunnelModeEnabled);
 }