SurfaceFlinger: give SF its own vsync phase

This change allows SurfaceFlinger to run at a different vsync phase offset from
that used by external listeners.

Bug: 11175503
Change-Id: I561c53a5659fa6dc1e3e4ae30340f3c1a6adceb4
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 36ad741..c3daa64 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -66,6 +66,13 @@
     LOCAL_CFLAGS += -DVSYNC_EVENT_PHASE_OFFSET_NS=0
 endif
 
+# See build/target/board/generic/BoardConfig.mk for a description of this setting.
+ifneq ($(SF_VSYNC_EVENT_PHASE_OFFSET_NS),)
+    LOCAL_CFLAGS += -DSF_VSYNC_EVENT_PHASE_OFFSET_NS=$(SF_VSYNC_EVENT_PHASE_OFFSET_NS)
+else
+    LOCAL_CFLAGS += -DSF_VSYNC_EVENT_PHASE_OFFSET_NS=0
+endif
+
 ifneq ($(PRESENT_TIME_OFFSET_FROM_VSYNC_NS),)
     LOCAL_CFLAGS += -DPRESENT_TIME_OFFSET_FROM_VSYNC_NS=$(PRESENT_TIME_OFFSET_FROM_VSYNC_NS)
 else
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 8ef4d6f..9d94c87 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -117,6 +117,9 @@
 // conservatively (or at least with awareness of the trade-off being made).
 static const int64_t vsyncPhaseOffsetNs = VSYNC_EVENT_PHASE_OFFSET_NS;
 
+// This is the phase offset at which SurfaceFlinger's composition runs.
+static const int64_t sfVsyncPhaseOffsetNs = SF_VSYNC_EVENT_PHASE_OFFSET_NS;
+
 // ---------------------------------------------------------------------------
 
 const String16 sHardwareTest("android.permission.HARDWARE_TEST");
@@ -439,7 +442,11 @@
 
 class DispSyncSource : public VSyncSource, private DispSync::Callback {
 public:
-    DispSyncSource(DispSync* dispSync) : mValue(0), mDispSync(dispSync) {}
+    DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync) :
+            mValue(0),
+            mPhaseOffset(phaseOffset),
+            mTraceVsync(traceVsync),
+            mDispSync(dispSync) {}
 
     virtual ~DispSyncSource() {}
 
@@ -447,7 +454,7 @@
         // Do NOT lock the mutex here so as to avoid any mutex ordering issues
         // with locking it in the onDispSyncEvent callback.
         if (enable) {
-            status_t err = mDispSync->addEventListener(vsyncPhaseOffsetNs,
+            status_t err = mDispSync->addEventListener(mPhaseOffset,
                     static_cast<DispSync::Callback*>(this));
             if (err != NO_ERROR) {
                 ALOGE("error registering vsync callback: %s (%d)",
@@ -477,8 +484,10 @@
             Mutex::Autolock lock(mMutex);
             callback = mCallback;
 
-            mValue = (mValue + 1) % 2;
-            ATRACE_INT("VSYNC", mValue);
+            if (mTraceVsync) {
+                mValue = (mValue + 1) % 2;
+                ATRACE_INT("VSYNC", mValue);
+            }
         }
 
         if (callback != NULL) {
@@ -488,6 +497,9 @@
 
     int mValue;
 
+    const nsecs_t mPhaseOffset;
+    const bool mTraceVsync;
+
     DispSync* mDispSync;
     sp<VSyncSource::Callback> mCallback;
     Mutex mMutex;
@@ -589,9 +601,13 @@
     getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
 
     // start the EventThread
-    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync);
+    sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
+            vsyncPhaseOffsetNs, true);
     mEventThread = new EventThread(vsyncSrc);
-    mEventQueue.setEventThread(mEventThread);
+    sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
+            sfVsyncPhaseOffsetNs, false);
+    mSFEventThread = new EventThread(sfVsyncSrc);
+    mEventQueue.setEventThread(mSFEventThread);
 
     mEventControlThread = new EventControlThread(this);
     mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 03c4ba3..f08e66a 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -428,6 +428,7 @@
     nsecs_t mBootTime;
     bool mGpuToCpuSupported;
     sp<EventThread> mEventThread;
+    sp<EventThread> mSFEventThread;
     sp<EventControlThread> mEventControlThread;
     EGLContext mEGLContext;
     EGLConfig mEGLConfig;