OSDN Git Service

SurfaceFlinger: Add --static-screen stats
authorDan Stoza <stoza@google.com>
Thu, 5 Mar 2015 19:05:59 +0000 (11:05 -0800)
committerDan Stoza <stoza@google.com>
Thu, 5 Mar 2015 22:43:08 +0000 (14:43 -0800)
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

services/surfaceflinger/SurfaceFlinger.cpp
services/surfaceflinger/SurfaceFlinger.h

index 3419295..d01b945 100644 (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
      */
index 4deb815..34f0aaa 100644 (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