diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2018-05-31 15:14:23 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2018-05-31 15:14:23 +0000 |
commit | 664ff4f0169970479fda925a032e1d9538409a12 (patch) | |
tree | 9040890a3d3afefa5856fcac25a84c377d60b117 | |
parent | 88fbd425a85fbba6365976ca9b056c719f7685a5 (diff) | |
parent | 9053521815dc4cbe3d2ab21096e05d33386dd5da (diff) | |
download | native-664ff4f0169970479fda925a032e1d9538409a12.tar.gz |
Merge "Keep early vsync-offsets for at least two frames after transaction" into pi-dev
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/VSyncModulator.h | 36 |
2 files changed, 32 insertions, 6 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index a120738713..e66d14e269 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -1549,7 +1549,7 @@ void SurfaceFlinger::handleMessageRefresh() { mHadClientComposition = mHadClientComposition || getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); } - mVsyncModulator.setLastFrameUsedRenderEngine(mHadClientComposition); + mVsyncModulator.onRefreshed(mHadClientComposition); mLayersWithQueuedFrames.clear(); } diff --git a/services/surfaceflinger/VSyncModulator.h b/services/surfaceflinger/VSyncModulator.h index 3e5800e2a2..d526313994 100644 --- a/services/surfaceflinger/VSyncModulator.h +++ b/services/surfaceflinger/VSyncModulator.h @@ -28,6 +28,12 @@ namespace android { * Modulates the vsync-offsets depending on current SurfaceFlinger state. */ class VSyncModulator { +private: + + // Number of frames we'll keep the early phase offsets once they are activated. This acts as a + // low-pass filter in case the client isn't quick enough in sending new transactions. + const int MIN_EARLY_FRAME_COUNT = 2; + public: enum TransactionStart { @@ -55,6 +61,11 @@ public: } void setTransactionStart(TransactionStart transactionStart) { + + if (transactionStart == TransactionStart::EARLY) { + mRemainingEarlyFrameCount = MIN_EARLY_FRAME_COUNT; + } + // An early transaction stays an early transaction. if (transactionStart == mTransactionStart || mTransactionStart == TransactionStart::EARLY) { return; @@ -69,10 +80,19 @@ public: updatePhaseOffsets(); } - void setLastFrameUsedRenderEngine(bool re) { - if (re == mLastFrameUsedRenderEngine) return; - mLastFrameUsedRenderEngine = re; - updatePhaseOffsets(); + void onRefreshed(bool usedRenderEngine) { + bool updatePhaseOffsetsNeeded = false; + if (mRemainingEarlyFrameCount > 0) { + mRemainingEarlyFrameCount--; + updatePhaseOffsetsNeeded = true; + } + if (usedRenderEngine != mLastFrameUsedRenderEngine) { + mLastFrameUsedRenderEngine = usedRenderEngine; + updatePhaseOffsetsNeeded = true; + } + if (updatePhaseOffsetsNeeded) { + updatePhaseOffsets(); + } } private: @@ -82,7 +102,7 @@ private: // Do not change phase offsets if disabled. if (mEarlyPhaseOffset == mLatePhaseOffset) return; - if (mTransactionStart == TransactionStart::EARLY || mLastFrameUsedRenderEngine) { + if (shouldUseEarlyOffset()) { if (mPhaseOffset != mEarlyPhaseOffset) { if (mEventThread) { mEventThread->setPhaseOffset(mEarlyPhaseOffset); @@ -99,12 +119,18 @@ private: } } + bool shouldUseEarlyOffset() { + return mTransactionStart == TransactionStart::EARLY || mLastFrameUsedRenderEngine + || mRemainingEarlyFrameCount > 0; + } + nsecs_t mLatePhaseOffset = 0; nsecs_t mEarlyPhaseOffset = 0; EventThread* mEventThread = nullptr; std::atomic<nsecs_t> mPhaseOffset = 0; std::atomic<TransactionStart> mTransactionStart = TransactionStart::NORMAL; std::atomic<bool> mLastFrameUsedRenderEngine = false; + std::atomic<int> mRemainingEarlyFrameCount = 0; }; } // namespace android |