OSDN Git Service

SurfaceFlinger: give SF its own vsync phase
authorJamie Gennis <jgennis@google.com>
Tue, 15 Oct 2013 03:52:46 +0000 (20:52 -0700)
committerJamie Gennis <jgennis@google.com>
Tue, 15 Oct 2013 21:31:41 +0000 (14:31 -0700)
This change allows SurfaceFlinger to run at a different vsync phase offset from
that used by external listeners.

Bug: 11175503
Change-Id: I561c53a5659fa6dc1e3e4ae30340f3c1a6adceb4

services/surfaceflinger/Android.mk
services/surfaceflinger/SurfaceFlinger.cpp
services/surfaceflinger/SurfaceFlinger.h

index 36ad741..c3daa64 100644 (file)
@@ -66,6 +66,13 @@ else
     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
index 8ef4d6f..9d94c87 100644 (file)
@@ -117,6 +117,9 @@ static const bool runningWithoutSyncFramework = false;
 // 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 @@ status_t SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisual
 
 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 @@ public:
         // 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 @@ private:
             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 @@ private:
 
     int mValue;
 
+    const nsecs_t mPhaseOffset;
+    const bool mTraceVsync;
+
     DispSync* mDispSync;
     sp<VSyncSource::Callback> mCallback;
     Mutex mMutex;
@@ -589,9 +601,13 @@ void SurfaceFlinger::init() {
     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);
index 03c4ba3..f08e66a 100644 (file)
@@ -428,6 +428,7 @@ private:
     nsecs_t mBootTime;
     bool mGpuToCpuSupported;
     sp<EventThread> mEventThread;
+    sp<EventThread> mSFEventThread;
     sp<EventControlThread> mEventControlThread;
     EGLContext mEGLContext;
     EGLConfig mEGLConfig;