summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/BufferQueueLayer.cpp
diff options
context:
space:
mode:
authorAdy Abraham <adyabr@google.com>2019-04-29 15:40:03 -0700
committerAdy Abraham <adyabr@google.com>2019-04-30 13:09:06 -0700
commitcd1580cb3fe40e225000a56c9b4ee43c0ce0a45d (patch)
treed222bdfd4de314246784a6f02908bbd3e658ab16 /services/surfaceflinger/BufferQueueLayer.cpp
parentdde87c4a326d0480aef0420f04c160b9d5d5096e (diff)
downloadandroid_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.cpp42
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 {