diff options
author | Dan Stoza <stoza@google.com> | 2015-03-05 11:05:59 -0800 |
---|---|---|
committer | Dan Stoza <stoza@google.com> | 2015-03-05 14:43:08 -0800 |
commit | b90cf07f8b3a8fe76e40b997924c2509d04575f4 (patch) | |
tree | e5258b96ffdfe626be8718cf5a10a3cc5537f41d /services/surfaceflinger | |
parent | abf952c1b121405ebb6720a779817b7850fb43b9 (diff) | |
download | frameworks_native-b90cf07f8b3a8fe76e40b997924c2509d04575f4.zip frameworks_native-b90cf07f8b3a8fe76e40b997924c2509d04575f4.tar.gz frameworks_native-b90cf07f8b3a8fe76e40b997924c2509d04575f4.tar.bz2 |
SurfaceFlinger: Add --static-screen stats
Adds a --static-screen option to dumpsys SurfaceFlinger, which
displays screen-on time broken down by the time between the prior
frame and the current frame. An example dump looks like this:
$ adb shell dumpsys SurfaceFlinger --static-screen
Static screen stats:
< 1 frames: 12.235 s (3.5%)
< 2 frames: 29.898 s (8.7%)
< 3 frames: 15.370 s (4.4%)
< 4 frames: 13.103 s (3.8%)
< 5 frames: 15.780 s (4.6%)
< 6 frames: 2.022 s (0.6%)
< 7 frames: 0.201 s (0.1%)
7+ frames: 256.887 s (74.4%)
The buckets are exclusive, so '< 3 frames' covers the interval
[2, 3) frames
Bug: 19543586
Change-Id: I3253a54c23995d25e96016997acedd0775956b60
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 58 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 9 |
2 files changed, 65 insertions, 2 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 3419295..d01b945 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -148,7 +148,11 @@ SurfaceFlinger::SurfaceFlinger() mPrimaryHWVsyncEnabled(false), mHWVsyncAvailable(false), mDaltonize(false), - mHasColorMatrix(false) + mHasColorMatrix(false), + mHasPoweredOff(false), + mFrameBuckets(), + mTotalTime(0), + mLastSwapTime(0) { ALOGI("SurfaceFlinger is starting"); @@ -949,8 +953,8 @@ void SurfaceFlinger::postComposition() } } + const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); if (kIgnorePresentFences) { - const sp<const DisplayDevice> hw(getDefaultDisplayDevice()); if (hw->isDisplayOn()) { enableHardwareVsync(); } @@ -969,6 +973,26 @@ void SurfaceFlinger::postComposition() } mAnimFrameTracker.advanceFrame(); } + + if (hw->getPowerMode() == HWC_POWER_MODE_OFF) { + return; + } + + nsecs_t currentTime = systemTime(); + if (mHasPoweredOff) { + mHasPoweredOff = false; + } else { + nsecs_t period = mPrimaryDispSync.getPeriod(); + nsecs_t elapsedTime = currentTime - mLastSwapTime; + size_t numPeriods = static_cast<size_t>(elapsedTime / period); + if (numPeriods < NUM_BUCKETS - 1) { + mFrameBuckets[numPeriods] += elapsedTime; + } else { + mFrameBuckets[NUM_BUCKETS - 1] += elapsedTime; + } + mTotalTime += elapsedTime; + } + mLastSwapTime = currentTime; } void SurfaceFlinger::rebuildLayerStacks() { @@ -2345,6 +2369,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw, } mVisibleRegionsDirty = true; + mHasPoweredOff = true; repaintEverything(); } else if (mode == HWC_POWER_MODE_OFF) { if (type == DisplayDevice::DISPLAY_PRIMARY) { @@ -2445,6 +2470,13 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) mPrimaryDispSync.dump(result); dumpAll = false; } + + if ((index < numArgs) && + (args[index] == String16("--static-screen"))) { + index++; + dumpStaticScreenStats(result); + dumpAll = false; + } } if (dumpAll) { @@ -2548,6 +2580,23 @@ void SurfaceFlinger::logFrameStats() { result.append(config); } +void SurfaceFlinger::dumpStaticScreenStats(String8& result) const +{ + result.appendFormat("Static screen stats:\n"); + for (size_t b = 0; b < NUM_BUCKETS - 1; ++b) { + float bucketTimeSec = mFrameBuckets[b] / 1e9; + float percent = 100.0f * + static_cast<float>(mFrameBuckets[b]) / mTotalTime; + result.appendFormat(" < %zd frames: %.3f s (%.1f%%)\n", + b + 1, bucketTimeSec, percent); + } + float bucketTimeSec = mFrameBuckets[NUM_BUCKETS - 1] / 1e9; + float percent = 100.0f * + static_cast<float>(mFrameBuckets[NUM_BUCKETS - 1]) / mTotalTime; + result.appendFormat(" %zd+ frames: %.3f s (%.1f%%)\n", + NUM_BUCKETS - 1, bucketTimeSec, percent); +} + void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, String8& result) const { @@ -2594,6 +2643,11 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index, mHwc->getRefreshPeriod(HWC_DISPLAY_PRIMARY)); result.append("\n"); + // Dump static screen stats + result.append("\n"); + dumpStaticScreenStats(result); + result.append("\n"); + /* * Dump the visible layer list */ diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 4deb815..34f0aaa 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -416,6 +416,8 @@ private: void logFrameStats(); + void dumpStaticScreenStats(String8& result) const; + /* ------------------------------------------------------------------------ * Attributes */ @@ -493,6 +495,13 @@ private: mat4 mColorMatrix; bool mHasColorMatrix; + + // Static screen stats + bool mHasPoweredOff; + static const size_t NUM_BUCKETS = 8; // < 1-7, 7+ + nsecs_t mFrameBuckets[NUM_BUCKETS]; + nsecs_t mTotalTime; + nsecs_t mLastSwapTime; }; }; // namespace android |