SF: Clean up dumpsys for Scheduler
Split dump into three flags corresponding to Scheduler, EventThread, and
VsyncReactor. Expand utils::Dumper to automate more types.
Bug: 241285191
Test: dumpsys SurfaceFlinger --scheduler
Test: dumpsys SurfaceFlinger --events
Test: dumpsys SurfaceFlinger --vsync
Change-Id: I17b3b772cd164305e2fe0239638b1a08236c12a2
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index a6cd47b..1acf15a 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -668,6 +668,7 @@
StringAppendF(&result, " %s\n", toString(*connection).c_str());
}
}
+ result += '\n';
}
const char* EventThread::toCString(State state) {
diff --git a/services/surfaceflinger/Scheduler/FrameRateOverrideMappings.cpp b/services/surfaceflinger/Scheduler/FrameRateOverrideMappings.cpp
index c233455..cb9bfe9 100644
--- a/services/surfaceflinger/Scheduler/FrameRateOverrideMappings.cpp
+++ b/services/surfaceflinger/Scheduler/FrameRateOverrideMappings.cpp
@@ -54,10 +54,9 @@
std::vector<FrameRateOverride> FrameRateOverrideMappings::getAllFrameRateOverrides(
bool supportsFrameRateOverrideByContent) {
std::lock_guard lock(mFrameRateOverridesLock);
+
std::vector<FrameRateOverride> overrides;
- overrides.reserve(std::max({mFrameRateOverridesFromGameManager.size(),
- mFrameRateOverridesFromBackdoor.size(),
- mFrameRateOverridesByContent.size()}));
+ overrides.reserve(maxOverridesCount());
for (const auto& [uid, frameRate] : mFrameRateOverridesFromBackdoor) {
overrides.emplace_back(FrameRateOverride{uid, frameRate.getValue()});
@@ -83,28 +82,34 @@
return overrides;
}
-void FrameRateOverrideMappings::dump(std::string& result) const {
- using base::StringAppendF;
+void FrameRateOverrideMappings::dump(utils::Dumper& dumper) const {
+ using namespace std::string_view_literals;
std::lock_guard lock(mFrameRateOverridesLock);
- StringAppendF(&result, "Frame Rate Overrides (backdoor): {");
- for (const auto& [uid, frameRate] : mFrameRateOverridesFromBackdoor) {
- StringAppendF(&result, "[uid: %d frameRate: %s], ", uid, to_string(frameRate).c_str());
- }
- StringAppendF(&result, "}\n");
+ const bool hasOverrides = maxOverridesCount() > 0;
+ dumper.dump("FrameRateOverrides"sv, hasOverrides ? ""sv : "none"sv);
- StringAppendF(&result, "Frame Rate Overrides (GameManager): {");
- for (const auto& [uid, frameRate] : mFrameRateOverridesFromGameManager) {
- StringAppendF(&result, "[uid: %d frameRate: %s], ", uid, to_string(frameRate).c_str());
- }
- StringAppendF(&result, "}\n");
+ if (!hasOverrides) return;
- StringAppendF(&result, "Frame Rate Overrides (setFrameRate): {");
- for (const auto& [uid, frameRate] : mFrameRateOverridesByContent) {
- StringAppendF(&result, "[uid: %d frameRate: %s], ", uid, to_string(frameRate).c_str());
+ dump(dumper, "setFrameRate"sv, mFrameRateOverridesByContent);
+ dump(dumper, "GameManager"sv, mFrameRateOverridesFromGameManager);
+ dump(dumper, "Backdoor"sv, mFrameRateOverridesFromBackdoor);
+}
+
+void FrameRateOverrideMappings::dump(utils::Dumper& dumper, std::string_view name,
+ const UidToFrameRateOverride& overrides) const {
+ if (overrides.empty()) return;
+
+ utils::Dumper::Indent indent(dumper);
+ dumper.dump(name);
+ {
+ utils::Dumper::Indent indent(dumper);
+ for (const auto& [uid, frameRate] : overrides) {
+ using namespace std::string_view_literals;
+ dumper.dump("(uid, frameRate)"sv, uid, frameRate);
+ }
}
- StringAppendF(&result, "}\n");
}
bool FrameRateOverrideMappings::updateFrameRateOverridesByContent(
diff --git a/services/surfaceflinger/Scheduler/FrameRateOverrideMappings.h b/services/surfaceflinger/Scheduler/FrameRateOverrideMappings.h
index 4185a4c..da0f276 100644
--- a/services/surfaceflinger/Scheduler/FrameRateOverrideMappings.h
+++ b/services/surfaceflinger/Scheduler/FrameRateOverrideMappings.h
@@ -23,7 +23,10 @@
#include <map>
#include <optional>
+#include "Utils/Dumper.h"
+
namespace android::scheduler {
+
class FrameRateOverrideMappings {
using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
using UidToFrameRateOverride = std::map<uid_t, Fps>;
@@ -34,7 +37,6 @@
EXCLUDES(mFrameRateOverridesLock);
std::vector<FrameRateOverride> getAllFrameRateOverrides(bool supportsFrameRateOverrideByContent)
EXCLUDES(mFrameRateOverridesLock);
- void dump(std::string& result) const;
bool updateFrameRateOverridesByContent(const UidToFrameRateOverride& frameRateOverrides)
EXCLUDES(mFrameRateOverridesLock);
void setGameModeRefreshRateForUid(FrameRateOverride frameRateOverride)
@@ -42,7 +44,17 @@
void setPreferredRefreshRateForUid(FrameRateOverride frameRateOverride)
EXCLUDES(mFrameRateOverridesLock);
+ void dump(utils::Dumper&) const;
+
private:
+ size_t maxOverridesCount() const REQUIRES(mFrameRateOverridesLock) {
+ return std::max({mFrameRateOverridesByContent.size(),
+ mFrameRateOverridesFromGameManager.size(),
+ mFrameRateOverridesFromBackdoor.size()});
+ }
+
+ void dump(utils::Dumper&, std::string_view name, const UidToFrameRateOverride&) const;
+
// The frame rate override lists need their own mutex as they are being read
// by SurfaceFlinger, Scheduler and EventThread (as a callback) to prevent deadlocks
mutable std::mutex mFrameRateOverridesLock;
@@ -53,4 +65,5 @@
UidToFrameRateOverride mFrameRateOverridesFromBackdoor GUARDED_BY(mFrameRateOverridesLock);
UidToFrameRateOverride mFrameRateOverridesFromGameManager GUARDED_BY(mFrameRateOverridesLock);
};
+
} // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index b884dc8..7c9cedfa 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -275,7 +275,7 @@
std::string LayerHistory::dump() const {
std::lock_guard lock(mLock);
- return base::StringPrintf("LayerHistory{size=%zu, active=%zu}",
+ return base::StringPrintf("{size=%zu, active=%zu}",
mActiveLayerInfos.size() + mInactiveLayerInfos.size(),
mActiveLayerInfos.size());
}
diff --git a/services/surfaceflinger/Scheduler/OneShotTimer.cpp b/services/surfaceflinger/Scheduler/OneShotTimer.cpp
index 3c8dc64..cd45bfd 100644
--- a/services/surfaceflinger/Scheduler/OneShotTimer.cpp
+++ b/services/surfaceflinger/Scheduler/OneShotTimer.cpp
@@ -179,11 +179,5 @@
}
}
-std::string OneShotTimer::dump() const {
- std::ostringstream stream;
- stream << mInterval.count() << " ms";
- return stream.str();
-}
-
} // namespace scheduler
} // namespace android
diff --git a/services/surfaceflinger/Scheduler/OneShotTimer.h b/services/surfaceflinger/Scheduler/OneShotTimer.h
index 2017c31..f95646c 100644
--- a/services/surfaceflinger/Scheduler/OneShotTimer.h
+++ b/services/surfaceflinger/Scheduler/OneShotTimer.h
@@ -23,6 +23,7 @@
#include "../Clock.h"
#include <android-base/thread_annotations.h>
+#include <scheduler/Time.h>
namespace android {
namespace scheduler {
@@ -42,6 +43,8 @@
std::unique_ptr<Clock> clock = std::make_unique<SteadyClock>());
~OneShotTimer();
+ Duration interval() const { return mInterval; }
+
// Initializes and turns on the idle timer.
void start();
// Stops the idle timer and any held resources.
@@ -49,8 +52,6 @@
// Resets the wakeup time and fires the reset callback.
void reset();
- std::string dump() const;
-
private:
// Enum to track in what state is the timer.
enum class TimerState {
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 40af6ee..263ebab 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -1129,20 +1129,15 @@
dumper.dump("supportsFrameRateOverrideByContent"sv, mSupportsFrameRateOverrideByContent);
- std::string idleTimer;
- if (mIdleTimer) {
- idleTimer = mIdleTimer->dump();
- } else {
- idleTimer = "off"sv;
+ dumper.dump("idleTimer"sv);
+ {
+ utils::Dumper::Indent indent(dumper);
+ dumper.dump("interval"sv, mIdleTimer.transform(&OneShotTimer::interval));
+ dumper.dump("controller"sv,
+ mConfig.kernelIdleTimerController
+ .and_then(&ftl::enum_name<KernelIdleTimerController>)
+ .value_or("Platform"sv));
}
-
- if (const auto controller = mConfig.kernelIdleTimerController) {
- base::StringAppendF(&idleTimer, " (kernel via %s)", ftl::enum_string(*controller).c_str());
- } else {
- idleTimer += " (platform)"sv;
- }
-
- dumper.dump("idleTimer"sv, idleTimer);
}
std::chrono::milliseconds RefreshRateSelector::getIdleTimerTimeout() {
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.h b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
index bff16d3..688d43d 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
@@ -18,12 +18,12 @@
#include <algorithm>
#include <numeric>
-#include <optional>
#include <type_traits>
#include <utility>
#include <variant>
#include <ftl/concat.h>
+#include <ftl/optional.h>
#include <gui/DisplayEventReceiver.h>
#include <scheduler/Fps.h>
@@ -272,7 +272,7 @@
// The controller representing how the kernel idle timer will be configured
// either on the HWC api or sysprop.
- std::optional<KernelIdleTimerController> kernelIdleTimerController;
+ ftl::Optional<KernelIdleTimerController> kernelIdleTimerController;
};
RefreshRateSelector(DisplayModes, DisplayModeId activeModeId,
@@ -467,7 +467,7 @@
std::mutex mIdleTimerCallbacksMutex;
std::optional<IdleTimerCallbacks> mIdleTimerCallbacks GUARDED_BY(mIdleTimerCallbacksMutex);
// Used to detect (lack of) frame activity.
- std::optional<scheduler::OneShotTimer> mIdleTimer;
+ ftl::Optional<scheduler::OneShotTimer> mIdleTimer;
};
} // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 6e34a68..6108d92 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -25,6 +25,7 @@
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>
+#include <ftl/enum.h>
#include <ftl/fake_guard.h>
#include <ftl/small_map.h>
#include <gui/WindowInfo.h>
@@ -599,22 +600,36 @@
ATRACE_INT("ExpiredDisplayPowerTimer", static_cast<int>(state));
}
-void Scheduler::dump(std::string& result) const {
- using base::StringAppendF;
-
- StringAppendF(&result, "+ Touch timer: %s\n",
- mTouchTimer ? mTouchTimer->dump().c_str() : "off");
- StringAppendF(&result, "+ Content detection: %s %s\n\n",
- mFeatures.test(Feature::kContentDetection) ? "on" : "off",
- mLayerHistory.dump().c_str());
-
- mFrameRateOverrideMappings.dump(result);
+void Scheduler::dump(utils::Dumper& dumper) const {
+ using namespace std::string_view_literals;
{
+ utils::Dumper::Section section(dumper, "Features"sv);
+
+ for (Feature feature : ftl::enum_range<Feature>()) {
+ if (const auto flagOpt = ftl::flag_name(feature)) {
+ dumper.dump(flagOpt->substr(1), mFeatures.test(feature));
+ }
+ }
+ }
+ {
+ utils::Dumper::Section section(dumper, "Policy"sv);
+
+ dumper.dump("layerHistory"sv, mLayerHistory.dump());
+ dumper.dump("touchTimer"sv, mTouchTimer.transform(&OneShotTimer::interval));
+ dumper.dump("displayPowerTimer"sv, mDisplayPowerTimer.transform(&OneShotTimer::interval));
+ }
+
+ mFrameRateOverrideMappings.dump(dumper);
+ dumper.eol();
+
+ {
+ utils::Dumper::Section section(dumper, "Hardware VSYNC"sv);
+
std::lock_guard lock(mHWVsyncLock);
- StringAppendF(&result,
- "mScreenAcquired=%d mPrimaryHWVsyncEnabled=%d mHWVsyncAvailable=%d\n",
- mScreenAcquired.load(), mPrimaryHWVsyncEnabled, mHWVsyncAvailable);
+ dumper.dump("screenAcquired"sv, mScreenAcquired.load());
+ dumper.dump("hwVsyncAvailable"sv, mHWVsyncAvailable);
+ dumper.dump("hwVsyncEnabled"sv, mPrimaryHWVsyncEnabled);
}
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 797ec96..04f3b69 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -45,6 +45,7 @@
#include "MessageQueue.h"
#include "OneShotTimer.h"
#include "RefreshRateSelector.h"
+#include "Utils/Dumper.h"
#include "VsyncSchedule.h"
namespace android::scheduler {
@@ -197,7 +198,7 @@
// for a given uid
bool isVsyncValid(TimePoint expectedVsyncTimestamp, uid_t uid) const;
- void dump(std::string&) const;
+ void dump(utils::Dumper&) const;
void dump(ConnectionHandle, std::string&) const;
void dumpVsync(std::string&) const;
@@ -335,9 +336,9 @@
LayerHistory mLayerHistory;
// Timer used to monitor touch events.
- std::optional<OneShotTimer> mTouchTimer;
+ ftl::Optional<OneShotTimer> mTouchTimer;
// Timer used to monitor display power mode.
- std::optional<OneShotTimer> mDisplayPowerTimer;
+ ftl::Optional<OneShotTimer> mDisplayPowerTimer;
ISchedulerCallback& mSchedulerCallback;
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/Time.h b/services/surfaceflinger/Scheduler/include/scheduler/Time.h
index 2ca55d4..bd4e3c2 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/Time.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/Time.h
@@ -17,7 +17,9 @@
#pragma once
#include <chrono>
+#include <string>
+#include <android-base/stringprintf.h>
#include <utils/Timers.h>
namespace android {
@@ -79,4 +81,8 @@
return std::chrono::duration_cast<D>(d).count();
}
+inline std::string to_string(Duration d) {
+ return base::StringPrintf("%.3f ms", ticks<std::milli, float>(d));
+}
+
} // namespace android