diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 36ad741ea..c3daa64d9 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -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 diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 8ef4d6f27..9d94c874f 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -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(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 mCallback; Mutex mMutex; @@ -589,9 +601,13 @@ void SurfaceFlinger::init() { getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext); // start the EventThread - sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync); + sp vsyncSrc = new DispSyncSource(&mPrimaryDispSync, + vsyncPhaseOffsetNs, true); mEventThread = new EventThread(vsyncSrc); - mEventQueue.setEventThread(mEventThread); + sp 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 03c4ba36c..f08e66abc 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -428,6 +428,7 @@ private: nsecs_t mBootTime; bool mGpuToCpuSupported; sp mEventThread; + sp mSFEventThread; sp mEventControlThread; EGLContext mEGLContext; EGLConfig mEGLConfig;