summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h')
-rw-r--r--services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h148
1 files changed, 133 insertions, 15 deletions
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
index 0c75f96e46..2afff8d313 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
+++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
@@ -40,37 +40,155 @@ public:
std::string toString() const;
};
+ struct JankPayload {
+ // note that transactions are counted for these frames.
+ int32_t totalFrames = 0;
+ int32_t totalJankyFrames = 0;
+ int32_t totalSFLongCpu = 0;
+ int32_t totalSFLongGpu = 0;
+ int32_t totalSFUnattributed = 0;
+ int32_t totalAppUnattributed = 0;
+ int32_t totalSFScheduling = 0;
+ int32_t totalSFPredictionError = 0;
+ int32_t totalAppBufferStuffing = 0;
+
+ std::string toString() const;
+ };
+
+ struct SetFrameRateVote {
+ float frameRate = 0;
+
+ // Needs to be in sync with atoms.proto
+ enum class FrameRateCompatibility {
+ Undefined = 0,
+ Default = 1,
+ ExactOrMultiple = 2,
+ } frameRateCompatibility = FrameRateCompatibility::Undefined;
+
+ // Needs to be in sync with atoms.proto
+ enum class Seamlessness {
+ Undefined = 0,
+ ShouldBeSeamless = 1,
+ NotRequired = 2,
+ } seamlessness = Seamlessness::Undefined;
+
+ static std::string toString(FrameRateCompatibility);
+ static std::string toString(Seamlessness);
+ std::string toString() const;
+ };
+
+ /**
+ * GameMode of the layer. GameModes are set by SysUI through WMShell.
+ * Actual game mode definitions are managed by GameManager.java
+ * The values defined here should always be in sync with the ones in GameManager.
+ */
+ enum GameMode {
+ GameModeUnsupported = 0,
+ GameModeStandard = 1,
+ GameModePerformance = 2,
+ GameModeBattery = 3,
+ };
+
class TimeStatsLayer {
public:
+ uid_t uid;
std::string layerName;
std::string packageName;
+ int32_t displayRefreshRateBucket = 0;
+ int32_t renderRateBucket = 0;
+ int32_t gameMode = 0;
int32_t totalFrames = 0;
int32_t droppedFrames = 0;
int32_t lateAcquireFrames = 0;
int32_t badDesiredPresentFrames = 0;
+ JankPayload jankPayload;
+ SetFrameRateVote setFrameRateVote;
std::unordered_map<std::string, Histogram> deltas;
std::string toString() const;
+ std::string toString(int32_t gameMode) const;
SFTimeStatsLayerProto toProto() const;
};
+ // Lifted from SkiaGLRenderEngine's LinearEffect class.
+ // Which in turn was inspired by art/runtime/class_linker.cc
+ // Also this is what boost:hash_combine does so this is a pretty good hash.
+ static size_t HashCombine(size_t seed, size_t val) {
+ return seed ^ (val + 0x9e3779b9 + (seed << 6) + (seed >> 2));
+ }
+
+ struct TimelineStatsKey {
+ int32_t displayRefreshRateBucket = 0;
+ int32_t renderRateBucket = 0;
+
+ struct Hasher {
+ size_t operator()(const TimelineStatsKey& key) const {
+ size_t result = std::hash<int32_t>{}(key.displayRefreshRateBucket);
+ return HashCombine(result, std::hash<int32_t>{}(key.renderRateBucket));
+ }
+ };
+
+ bool operator==(const TimelineStatsKey& o) const {
+ return displayRefreshRateBucket == o.displayRefreshRateBucket &&
+ renderRateBucket == o.renderRateBucket;
+ }
+ };
+
+ struct LayerStatsKey {
+ uid_t uid = 0;
+ std::string layerName;
+ int32_t gameMode = 0;
+
+ struct Hasher {
+ size_t operator()(const LayerStatsKey& key) const {
+ size_t uidHash = std::hash<uid_t>{}(key.uid);
+ size_t layerNameHash = std::hash<std::string>{}(key.layerName);
+ size_t gameModeHash = std::hash<int32_t>{}(key.gameMode);
+ return HashCombine(uidHash, HashCombine(layerNameHash, gameModeHash));
+ }
+ };
+
+ bool operator==(const LayerStatsKey& o) const {
+ return uid == o.uid && layerName == o.layerName && gameMode == o.gameMode;
+ }
+ };
+
+ struct TimelineStats {
+ TimelineStatsKey key;
+ JankPayload jankPayload;
+ Histogram displayDeadlineDeltas;
+ Histogram displayPresentDeltas;
+ std::unordered_map<LayerStatsKey, TimeStatsLayer, LayerStatsKey::Hasher> stats;
+
+ void clearGlobals() {
+ jankPayload = {};
+ displayDeadlineDeltas = {};
+ displayPresentDeltas = {};
+ }
+ };
+
class TimeStatsGlobal {
public:
- int64_t statsStart = 0;
- int64_t statsEnd = 0;
- int32_t totalFrames = 0;
- int32_t missedFrames = 0;
- int32_t clientCompositionFrames = 0;
- int32_t clientCompositionReusedFrames = 0;
- int32_t refreshRateSwitches = 0;
- int32_t compositionStrategyChanges = 0;
- int32_t displayEventConnectionsCount = 0;
- int64_t displayOnTime = 0;
- Histogram presentToPresent;
- Histogram frameDuration;
- Histogram renderEngineTiming;
- std::unordered_map<std::string, TimeStatsLayer> stats;
- std::unordered_map<uint32_t, nsecs_t> refreshRateStats;
+ // Note: these are all legacy statistics, we're keeping these around because a variety of
+ // systems and form-factors find these useful when comparing with older releases. However,
+ // the current recommendation is that the new timeline-based metrics are used, and the old
+ // ones are deprecated.
+ int64_t statsStartLegacy = 0;
+ int64_t statsEndLegacy = 0;
+ int32_t totalFramesLegacy = 0;
+ int32_t missedFramesLegacy = 0;
+ int32_t clientCompositionFramesLegacy = 0;
+ int32_t clientCompositionReusedFramesLegacy = 0;
+ int32_t refreshRateSwitchesLegacy = 0;
+ int32_t compositionStrategyChangesLegacy = 0;
+ int32_t displayEventConnectionsCountLegacy = 0;
+ int64_t displayOnTimeLegacy = 0;
+ Histogram presentToPresentLegacy;
+ Histogram frameDurationLegacy;
+ Histogram renderEngineTimingLegacy;
+ std::unordered_map<uint32_t, nsecs_t> refreshRateStatsLegacy;
+
+ std::unordered_map<TimelineStatsKey, TimelineStats, TimelineStatsKey::Hasher> stats;
std::string toString(std::optional<uint32_t> maxLayers) const;
SFTimeStatsGlobalProto toProto(std::optional<uint32_t> maxLayers) const;