summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/SurfaceFlinger.cpp
diff options
context:
space:
mode:
author Ady Abraham <adyabr@google.com> 2019-04-24 15:41:53 -0700
committer Ady Abraham <adyabr@google.com> 2019-04-29 18:01:19 -0700
commitbe0f948bd3b780e1a70e57eb01113ec897f99264 (patch)
tree7670d86fdea1997faae5a87921e7b241cca65b9e /services/surfaceflinger/SurfaceFlinger.cpp
parentdde87c4a326d0480aef0420f04c160b9d5d5096e (diff)
SurfaceFlinger: support negative phase offset
Store the last 2 present frames to accommodate negative phase offsets. Test: systrace Bug: 130191039 Change-Id: Ie4460d4a1b14a2a12f5d2f3c1542e0b837cb761c
Diffstat (limited to 'services/surfaceflinger/SurfaceFlinger.cpp')
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp28
1 files changed, 20 insertions, 8 deletions
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1d54cb275b..5e0ba13faa 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -977,8 +977,7 @@ void SurfaceFlinger::setActiveConfigInternal() {
bool SurfaceFlinger::performSetActiveConfig() {
ATRACE_CALL();
if (mCheckPendingFence) {
- if (mPreviousPresentFence != Fence::NO_FENCE &&
- (mPreviousPresentFence->getStatus() == Fence::Status::Unsignaled)) {
+ if (previousFrameMissed()) {
// fence has not signaled yet. wait for the next invalidate
repaintEverythingForHWC();
return true;
@@ -1591,12 +1590,23 @@ void SurfaceFlinger::updateVrFlinger() {
setTransactionFlags(eDisplayTransactionNeeded);
}
+bool SurfaceFlinger::previousFrameMissed() NO_THREAD_SAFETY_ANALYSIS {
+ // We are storing the last 2 present fences. If sf's phase offset is to be
+ // woken up before the actual vsync but targeting the next vsync, we need to check
+ // fence N-2
+ const sp<Fence>& fence =
+ mVsyncModulator.getOffsets().sf < mPhaseOffsets->getOffsetThresholdForNextVsync()
+ ? mPreviousPresentFences[0]
+ : mPreviousPresentFences[1];
+
+ return fence != Fence::NO_FENCE && (fence->getStatus() == Fence::Status::Unsignaled);
+}
+
void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
- bool frameMissed = mPreviousPresentFence != Fence::NO_FENCE &&
- (mPreviousPresentFence->getStatus() == Fence::Status::Unsignaled);
+ bool frameMissed = previousFrameMissed();
bool hwcFrameMissed = mHadDeviceComposition && frameMissed;
bool gpuFrameMissed = mHadClientComposition && frameMissed;
ATRACE_INT("FrameMissed", static_cast<int>(frameMissed));
@@ -1986,9 +1996,11 @@ void SurfaceFlinger::postComposition()
}
getBE().mDisplayTimeline.updateSignalTimes();
- mPreviousPresentFence = displayDevice ? getHwComposer().getPresentFence(*displayDevice->getId())
- : Fence::NO_FENCE;
- auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFence);
+ mPreviousPresentFences[1] = mPreviousPresentFences[0];
+ mPreviousPresentFences[0] = displayDevice
+ ? getHwComposer().getPresentFence(*displayDevice->getId())
+ : Fence::NO_FENCE;
+ auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]);
getBE().mDisplayTimeline.push(presentFenceTime);
DisplayStatInfo stats;
@@ -2079,7 +2091,7 @@ void SurfaceFlinger::postComposition()
}
}
- mTransactionCompletedThread.addPresentFence(mPreviousPresentFence);
+ mTransactionCompletedThread.addPresentFence(mPreviousPresentFences[0]);
mTransactionCompletedThread.sendCallbacks();
if (mLumaSampling && mRegionSamplingThread) {