summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger
diff options
context:
space:
mode:
authorDan Stoza <stoza@google.com>2015-07-09 12:43:33 -0700
committerDan Stoza <stoza@google.com>2015-07-23 11:15:32 -0700
commit14cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578 (patch)
treec748b48b6b9984358a7137d0775ea09a70934eee /services/surfaceflinger
parent177a4166252afddbe03a5ed7b2e56b0f9173ef81 (diff)
downloadframeworks_native-14cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578.zip
frameworks_native-14cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578.tar.gz
frameworks_native-14cd37cf3d7d783eaeb4cfb5f1f9e712d3b49578.tar.bz2
SF: Track missed frames and optionally drop them
Adds code to track whether SurfaceFlinger has sent two frames to HWC in the same vsync window. This can occur if one frame is delayed so far it slips into the next window or just if one frame takes an abnormal amount of time. If this occurs, it shows up as FrameMissed in systrace. Also adds a property debug.sf.drop_missed_frames which, if set, tells SurfaceFlinger to skip sending a frame to HWC (i.e., calling prepare/set) when we detect this condition, which can help prevent backpressure from the HWC implementation. Bug: 22513558 Change-Id: I2df0d44cec5fd6edba419388d8c90b5710d1a5b6
Diffstat (limited to 'services/surfaceflinger')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp34
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h1
2 files changed, 29 insertions, 6 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9b9867d..01ffac2 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -163,6 +163,9 @@ SurfaceFlinger::SurfaceFlinger()
property_get("ro.bq.gpu_to_cpu_unsupported", value, "0");
mGpuToCpuSupported = !atoi(value);
+ property_get("debug.sf.drop_missed_frames", value, "0");
+ mDropMissedFrames = atoi(value);
+
property_get("debug.sf.showupdates", value, "0");
mDebugRegion = atoi(value);
@@ -919,12 +922,31 @@ bool SurfaceFlinger::handleMessageInvalidate() {
void SurfaceFlinger::handleMessageRefresh() {
ATRACE_CALL();
- preComposition();
- rebuildLayerStacks();
- setUpHWComposer();
- doDebugFlashRegions();
- doComposition();
- postComposition();
+
+ static nsecs_t previousExpectedPresent = 0;
+ nsecs_t expectedPresent = mPrimaryDispSync.computeNextRefresh(0);
+ static bool previousFrameMissed = false;
+ bool frameMissed = (expectedPresent == previousExpectedPresent);
+ if (frameMissed != previousFrameMissed) {
+ ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
+ }
+ previousFrameMissed = frameMissed;
+
+ if (CC_UNLIKELY(mDropMissedFrames && frameMissed)) {
+ // Latch buffers, but don't send anything to HWC, then signal another
+ // wakeup for the next vsync
+ preComposition();
+ repaintEverything();
+ } else {
+ preComposition();
+ rebuildLayerStacks();
+ setUpHWComposer();
+ doDebugFlashRegions();
+ doComposition();
+ postComposition();
+ }
+
+ previousExpectedPresent = mPrimaryDispSync.computeNextRefresh(0);
}
void SurfaceFlinger::doDebugFlashRegions()
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3759a92..b3baadd 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -445,6 +445,7 @@ private:
RenderEngine* mRenderEngine;
nsecs_t mBootTime;
bool mGpuToCpuSupported;
+ bool mDropMissedFrames;
sp<EventThread> mEventThread;
sp<EventThread> mSFEventThread;
sp<EventControlThread> mEventControlThread;