diff options
author | Ady Abraham <adyabr@google.com> | 2019-04-29 15:40:03 -0700 |
---|---|---|
committer | Ady Abraham <adyabr@google.com> | 2019-04-30 13:09:06 -0700 |
commit | cd1580cb3fe40e225000a56c9b4ee43c0ce0a45d (patch) | |
tree | d222bdfd4de314246784a6f02908bbd3e658ab16 /services/surfaceflinger/BufferQueueLayer.cpp | |
parent | dde87c4a326d0480aef0420f04c160b9d5d5096e (diff) | |
download | android_frameworks_native-cd1580cb3fe40e225000a56c9b4ee43c0ce0a45d.tar.gz android_frameworks_native-cd1580cb3fe40e225000a56c9b4ee43c0ce0a45d.tar.bz2 android_frameworks_native-cd1580cb3fe40e225000a56c9b4ee43c0ce0a45d.zip |
SurfaceFlinger: fix deferred transactions for buffers with timestamps
A deferred transaction needs to wait until the buffer is ready
to be latched. This means that the buffer needs to be:
1. Done with rendering (fence has signaled)
2. Present timestamp is within the boundary of the next vsync
Test: Screen rotation with Chrome
Bug: 130785247
Change-Id: I8def1f10ea3d5c253ab14fa3aa4445588fc2ba8b
Diffstat (limited to 'services/surfaceflinger/BufferQueueLayer.cpp')
-rw-r--r-- | services/surfaceflinger/BufferQueueLayer.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index ff5f27196..5d729f5b4 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -19,6 +19,7 @@ #include <compositionengine/OutputLayer.h> #include <compositionengine/impl/LayerCompositionState.h> #include <compositionengine/impl/OutputLayerCompositionState.h> +#include <gui/BufferQueueConsumer.h> #include <system/window.h> #include "BufferQueueLayer.h" @@ -133,6 +134,15 @@ bool BufferQueueLayer::fenceHasSignaled() const { return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; } +bool BufferQueueLayer::framePresentTimeIsCurrent() const { + if (!hasFrameUpdate() || isRemovedFromCurrentState()) { + return true; + } + + Mutex::Autolock lock(mQueueItemLock); + return mQueueItems[0].mTimestamp <= mFlinger->mScheduler->expectedPresentTime(); +} + nsecs_t BufferQueueLayer::getDesiredPresentTime() { return mConsumer->getTimestamp(); } @@ -185,7 +195,37 @@ PixelFormat BufferQueueLayer::getPixelFormat() const { uint64_t BufferQueueLayer::getFrameNumber() const { Mutex::Autolock lock(mQueueItemLock); - return mQueueItems[0].mFrameNumber; + uint64_t frameNumber = mQueueItems[0].mFrameNumber; + + // The head of the queue will be dropped if there are signaled and timely frames behind it + nsecs_t expectedPresentTime = mFlinger->mScheduler->expectedPresentTime(); + + if (isRemovedFromCurrentState()) { + expectedPresentTime = 0; + } + + for (int i = 1; i < mQueueItems.size(); i++) { + const bool fenceSignaled = + mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; + if (!fenceSignaled) { + break; + } + + // We don't drop frames without explicit timestamps + if (mQueueItems[i].mIsAutoTimestamp) { + break; + } + + const nsecs_t desiredPresent = mQueueItems[i].mTimestamp; + if (desiredPresent < expectedPresentTime - BufferQueueConsumer::MAX_REASONABLE_NSEC || + desiredPresent > expectedPresentTime) { + break; + } + + frameNumber = mQueueItems[i].mFrameNumber; + } + + return frameNumber; } bool BufferQueueLayer::getAutoRefresh() const { |