summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2018-05-31 15:14:23 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2018-05-31 15:14:23 +0000
commit664ff4f0169970479fda925a032e1d9538409a12 (patch)
tree9040890a3d3afefa5856fcac25a84c377d60b117
parent88fbd425a85fbba6365976ca9b056c719f7685a5 (diff)
parent9053521815dc4cbe3d2ab21096e05d33386dd5da (diff)
downloadnative-664ff4f0169970479fda925a032e1d9538409a12.tar.gz
Merge "Keep early vsync-offsets for at least two frames after transaction" into pi-dev
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp2
-rw-r--r--services/surfaceflinger/VSyncModulator.h36
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