Loading services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1549,7 +1549,7 @@ void SurfaceFlinger::handleMessageRefresh() { mHadClientComposition = mHadClientComposition || mHadClientComposition = mHadClientComposition || getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); } } mVsyncModulator.setLastFrameUsedRenderEngine(mHadClientComposition); mVsyncModulator.onRefreshed(mHadClientComposition); mLayersWithQueuedFrames.clear(); mLayersWithQueuedFrames.clear(); } } Loading services/surfaceflinger/VSyncModulator.h +31 −5 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,12 @@ namespace android { * Modulates the vsync-offsets depending on current SurfaceFlinger state. * Modulates the vsync-offsets depending on current SurfaceFlinger state. */ */ class VSyncModulator { 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: public: enum TransactionStart { enum TransactionStart { Loading Loading @@ -55,6 +61,11 @@ public: } } void setTransactionStart(TransactionStart transactionStart) { void setTransactionStart(TransactionStart transactionStart) { if (transactionStart == TransactionStart::EARLY) { mRemainingEarlyFrameCount = MIN_EARLY_FRAME_COUNT; } // An early transaction stays an early transaction. // An early transaction stays an early transaction. if (transactionStart == mTransactionStart || mTransactionStart == TransactionStart::EARLY) { if (transactionStart == mTransactionStart || mTransactionStart == TransactionStart::EARLY) { return; return; Loading @@ -69,11 +80,20 @@ public: updatePhaseOffsets(); updatePhaseOffsets(); } } void setLastFrameUsedRenderEngine(bool re) { void onRefreshed(bool usedRenderEngine) { if (re == mLastFrameUsedRenderEngine) return; bool updatePhaseOffsetsNeeded = false; mLastFrameUsedRenderEngine = re; if (mRemainingEarlyFrameCount > 0) { mRemainingEarlyFrameCount--; updatePhaseOffsetsNeeded = true; } if (usedRenderEngine != mLastFrameUsedRenderEngine) { mLastFrameUsedRenderEngine = usedRenderEngine; updatePhaseOffsetsNeeded = true; } if (updatePhaseOffsetsNeeded) { updatePhaseOffsets(); updatePhaseOffsets(); } } } private: private: Loading @@ -82,7 +102,7 @@ private: // Do not change phase offsets if disabled. // Do not change phase offsets if disabled. if (mEarlyPhaseOffset == mLatePhaseOffset) return; if (mEarlyPhaseOffset == mLatePhaseOffset) return; if (mTransactionStart == TransactionStart::EARLY || mLastFrameUsedRenderEngine) { if (shouldUseEarlyOffset()) { if (mPhaseOffset != mEarlyPhaseOffset) { if (mPhaseOffset != mEarlyPhaseOffset) { if (mEventThread) { if (mEventThread) { mEventThread->setPhaseOffset(mEarlyPhaseOffset); mEventThread->setPhaseOffset(mEarlyPhaseOffset); Loading @@ -99,12 +119,18 @@ private: } } } } bool shouldUseEarlyOffset() { return mTransactionStart == TransactionStart::EARLY || mLastFrameUsedRenderEngine || mRemainingEarlyFrameCount > 0; } nsecs_t mLatePhaseOffset = 0; nsecs_t mLatePhaseOffset = 0; nsecs_t mEarlyPhaseOffset = 0; nsecs_t mEarlyPhaseOffset = 0; EventThread* mEventThread = nullptr; EventThread* mEventThread = nullptr; std::atomic<nsecs_t> mPhaseOffset = 0; std::atomic<nsecs_t> mPhaseOffset = 0; std::atomic<TransactionStart> mTransactionStart = TransactionStart::NORMAL; std::atomic<TransactionStart> mTransactionStart = TransactionStart::NORMAL; std::atomic<bool> mLastFrameUsedRenderEngine = false; std::atomic<bool> mLastFrameUsedRenderEngine = false; std::atomic<int> mRemainingEarlyFrameCount = 0; }; }; } // namespace android } // namespace android Loading
services/surfaceflinger/SurfaceFlinger.cpp +1 −1 Original line number Original line Diff line number Diff line Loading @@ -1549,7 +1549,7 @@ void SurfaceFlinger::handleMessageRefresh() { mHadClientComposition = mHadClientComposition || mHadClientComposition = mHadClientComposition || getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); getBE().mHwc->hasClientComposition(displayDevice->getHwcDisplayId()); } } mVsyncModulator.setLastFrameUsedRenderEngine(mHadClientComposition); mVsyncModulator.onRefreshed(mHadClientComposition); mLayersWithQueuedFrames.clear(); mLayersWithQueuedFrames.clear(); } } Loading
services/surfaceflinger/VSyncModulator.h +31 −5 Original line number Original line Diff line number Diff line Loading @@ -28,6 +28,12 @@ namespace android { * Modulates the vsync-offsets depending on current SurfaceFlinger state. * Modulates the vsync-offsets depending on current SurfaceFlinger state. */ */ class VSyncModulator { 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: public: enum TransactionStart { enum TransactionStart { Loading Loading @@ -55,6 +61,11 @@ public: } } void setTransactionStart(TransactionStart transactionStart) { void setTransactionStart(TransactionStart transactionStart) { if (transactionStart == TransactionStart::EARLY) { mRemainingEarlyFrameCount = MIN_EARLY_FRAME_COUNT; } // An early transaction stays an early transaction. // An early transaction stays an early transaction. if (transactionStart == mTransactionStart || mTransactionStart == TransactionStart::EARLY) { if (transactionStart == mTransactionStart || mTransactionStart == TransactionStart::EARLY) { return; return; Loading @@ -69,11 +80,20 @@ public: updatePhaseOffsets(); updatePhaseOffsets(); } } void setLastFrameUsedRenderEngine(bool re) { void onRefreshed(bool usedRenderEngine) { if (re == mLastFrameUsedRenderEngine) return; bool updatePhaseOffsetsNeeded = false; mLastFrameUsedRenderEngine = re; if (mRemainingEarlyFrameCount > 0) { mRemainingEarlyFrameCount--; updatePhaseOffsetsNeeded = true; } if (usedRenderEngine != mLastFrameUsedRenderEngine) { mLastFrameUsedRenderEngine = usedRenderEngine; updatePhaseOffsetsNeeded = true; } if (updatePhaseOffsetsNeeded) { updatePhaseOffsets(); updatePhaseOffsets(); } } } private: private: Loading @@ -82,7 +102,7 @@ private: // Do not change phase offsets if disabled. // Do not change phase offsets if disabled. if (mEarlyPhaseOffset == mLatePhaseOffset) return; if (mEarlyPhaseOffset == mLatePhaseOffset) return; if (mTransactionStart == TransactionStart::EARLY || mLastFrameUsedRenderEngine) { if (shouldUseEarlyOffset()) { if (mPhaseOffset != mEarlyPhaseOffset) { if (mPhaseOffset != mEarlyPhaseOffset) { if (mEventThread) { if (mEventThread) { mEventThread->setPhaseOffset(mEarlyPhaseOffset); mEventThread->setPhaseOffset(mEarlyPhaseOffset); Loading @@ -99,12 +119,18 @@ private: } } } } bool shouldUseEarlyOffset() { return mTransactionStart == TransactionStart::EARLY || mLastFrameUsedRenderEngine || mRemainingEarlyFrameCount > 0; } nsecs_t mLatePhaseOffset = 0; nsecs_t mLatePhaseOffset = 0; nsecs_t mEarlyPhaseOffset = 0; nsecs_t mEarlyPhaseOffset = 0; EventThread* mEventThread = nullptr; EventThread* mEventThread = nullptr; std::atomic<nsecs_t> mPhaseOffset = 0; std::atomic<nsecs_t> mPhaseOffset = 0; std::atomic<TransactionStart> mTransactionStart = TransactionStart::NORMAL; std::atomic<TransactionStart> mTransactionStart = TransactionStart::NORMAL; std::atomic<bool> mLastFrameUsedRenderEngine = false; std::atomic<bool> mLastFrameUsedRenderEngine = false; std::atomic<int> mRemainingEarlyFrameCount = 0; }; }; } // namespace android } // namespace android