summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Alec Mouri <alecmouri@google.com> 2019-06-06 13:28:34 -0700
committer Alec Mouri <alecmouri@google.com> 2019-06-06 14:19:57 -0700
commitaa61419b69daed4794c593f0718b3330ee2ec8dc (patch)
treec953d23d4c13a0eac88f0f1e5520ff0762c38f9e
parent0fafdb81ae408c155607151f27ca51622cdeb089 (diff)
[SurfaceFlinger] correct present time for negative phase offsets
DispSync::expectedPresentTime returns the expected presentation time for the current frame, but when we're in negative offsets we are targetting the following frame instead. Bug: 133241520 Bug: 134589085 Test: systrace when flinging through news Change-Id: I7cc05a0b9e8e9b5c3e8d0c4b1d59b0a7dabd43d4
-rw-r--r--services/surfaceflinger/BufferQueueLayer.cpp2
-rw-r--r--services/surfaceflinger/BufferStateLayer.cpp2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp15
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h5
4 files changed, 20 insertions, 4 deletions
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index bd0b55f688..57f1008e85 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -143,7 +143,7 @@ bool BufferQueueLayer::framePresentTimeIsCurrent() const {
}
Mutex::Autolock lock(mQueueItemLock);
- return mQueueItems[0].mTimestamp <= mFlinger->mScheduler->expectedPresentTime();
+ return mQueueItems[0].mTimestamp <= mFlinger->getExpectedPresentTime();
}
nsecs_t BufferQueueLayer::getDesiredPresentTime() {
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 05c721f141..203bd72e6f 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -380,7 +380,7 @@ bool BufferStateLayer::framePresentTimeIsCurrent() const {
return true;
}
- return mDesiredPresentTime <= mFlinger->mScheduler->expectedPresentTime();
+ return mDesiredPresentTime <= mFlinger->getExpectedPresentTime();
}
nsecs_t BufferStateLayer::getDesiredPresentTime() {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 50fabe3c43..dadb3fed05 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1643,6 +1643,18 @@ bool SurfaceFlinger::previousFrameMissed() NO_THREAD_SAFETY_ANALYSIS {
return fence != Fence::NO_FENCE && (fence->getStatus() == Fence::Status::Unsignaled);
}
+nsecs_t SurfaceFlinger::getExpectedPresentTime() NO_THREAD_SAFETY_ANALYSIS {
+ DisplayStatInfo stats;
+ mScheduler->getDisplayStatInfo(&stats);
+ const nsecs_t presentTime = mScheduler->expectedPresentTime();
+ // Inflate the expected present time if we're targetting the next vsync.
+ const nsecs_t correctedTime =
+ mVsyncModulator.getOffsets().sf < mPhaseOffsets->getOffsetThresholdForNextVsync()
+ ? presentTime
+ : presentTime + stats.vsyncPeriod;
+ return correctedTime;
+}
+
void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
ATRACE_CALL();
switch (what) {
@@ -3244,8 +3256,7 @@ bool SurfaceFlinger::handlePageFlip()
mDrawingState.traverseInZOrder([&](Layer* layer) {
if (layer->hasReadyFrame()) {
frameQueued = true;
- nsecs_t expectedPresentTime;
- expectedPresentTime = mScheduler->expectedPresentTime();
+ const nsecs_t expectedPresentTime = getExpectedPresentTime();
if (layer->shouldPresentNow(expectedPresentTime)) {
mLayersWithQueuedFrames.push_back(layer);
} else {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 74fefa7a3f..3d98ec19a5 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -298,6 +298,11 @@ public:
// TODO: this should be made accessible only to MessageQueue
void onMessageReceived(int32_t what);
+ // Returns the expected present time for this frame.
+ // When we are in negative offsets, we perform a correction so that the
+ // predicted vsync for the *next* frame is used instead.
+ nsecs_t getExpectedPresentTime();
+
// for debugging only
// TODO: this should be made accessible only to HWComposer
const Vector<sp<Layer>>& getLayerSortedByZForHwcDisplay(DisplayId displayId);