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);
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()
RenderEngine* mRenderEngine;
nsecs_t mBootTime;
bool mGpuToCpuSupported;
+ bool mDropMissedFrames;
sp<EventThread> mEventThread;
sp<EventThread> mSFEventThread;
sp<EventControlThread> mEventControlThread;