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
This commit is contained in:
Dan Stoza 2015-03-05 11:05:59 -08:00
parent abf952c1b1
commit b90cf07f8b
2 changed files with 65 additions and 2 deletions

View File

@ -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
*/

View File

@ -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