SurfaceFlinger: fix frame rate override on BLAST
Apply BLAST transactions only is the vsync is considered valid
for that layer (i.e. the vsync aligns to the overriden vsync policy).
Bug: 170502573
Test: atest FrameRateOverrideHostTest
Change-Id: I379f76556922391df370b551f3034d2c01c94859
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d54cac2..b420939 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3288,14 +3288,18 @@
if (s.acquireFence && s.acquireFence->getStatus() == Fence::Status::Unsignaled) {
ready = false;
}
+ sp<Layer> layer = nullptr;
+ if (s.surface) {
+ layer = fromHandleLocked(s.surface).promote();
+ } else {
+ ALOGW("Transaction with buffer, but no Layer?");
+ continue;
+ }
+ if (layer && !mScheduler->isVsyncValid(expectedPresentTime, layer->getOwnerUid())) {
+ ATRACE_NAME("!isVsyncValidForUid");
+ ready = false;
+ }
if (updateTransactionCounters) {
- sp<Layer> layer = nullptr;
- if (s.surface) {
- layer = fromHandleLocked(s.surface).promote();
- } else {
- ALOGW("Transaction with buffer, but no Layer?");
- continue;
- }
// See BufferStateLayer::mPendingBufferTransactions
if (layer) layer->incrementPendingBufferCount();
@@ -3338,7 +3342,11 @@
const bool pendingTransactions = itr != mTransactionQueues.end();
// Expected present time is computed and cached on invalidate, so it may be stale.
if (!pendingTransactions) {
- mExpectedPresentTime = calculateExpectedPresentTime(systemTime());
+ // The transaction might arrive just before the next vsync but after
+ // invalidate was called. In that case we need to get the next vsync
+ // afterwards.
+ const auto referenceTime = std::max(mExpectedPresentTime.load(), systemTime());
+ mExpectedPresentTime = calculateExpectedPresentTime(referenceTime);
}
IPCThreadState* ipc = IPCThreadState::self();