SurfaceFlinger: correctly pass desired present time for BLAST
Pass whether a desired present time is automatically
populated or not to match BufferStateLayer behavior to the one
we have for BufferQueueLayer.
Bug: 169901895
Test: expand notification shade and observe systrace
Change-Id: Ia02c5633d46dde67d2c3be33b084d63c40c2afb0
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 0b9caba..df1472d 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -341,7 +341,7 @@
}
bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence,
- nsecs_t postTime, nsecs_t desiredPresentTime,
+ nsecs_t postTime, nsecs_t desiredPresentTime, bool isAutoTimestamp,
const client_cache_t& clientCacheId, uint64_t frameNumber) {
ATRACE_CALL();
@@ -365,13 +365,13 @@
const int32_t layerId = getSequence();
mFlinger->mTimeStats->setPostTime(layerId, mCurrentState.frameNumber, getName().c_str(),
mOwnerUid, postTime);
- desiredPresentTime = desiredPresentTime <= 0 ? 0 : desiredPresentTime;
mCurrentState.desiredPresentTime = desiredPresentTime;
+ mCurrentState.isAutoTimestamp = isAutoTimestamp;
- mFlinger->mScheduler->recordLayerHistory(this, desiredPresentTime,
+ mFlinger->mScheduler->recordLayerHistory(this, isAutoTimestamp ? 0 : desiredPresentTime,
LayerHistory::LayerUpdateType::Buffer);
- addFrameEvent(acquireFence, postTime, desiredPresentTime);
+ addFrameEvent(acquireFence, postTime, isAutoTimestamp ? 0 : desiredPresentTime);
return true;
}
@@ -533,7 +533,7 @@
return true;
}
- return mCurrentState.desiredPresentTime <= expectedPresentTime;
+ return mCurrentState.isAutoTimestamp || mCurrentState.desiredPresentTime <= expectedPresentTime;
}
bool BufferStateLayer::onPreComposition(nsecs_t refreshStartTime) {
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index ad00c65..734f647 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -70,8 +70,8 @@
bool setCrop(const Rect& crop) override;
bool setFrame(const Rect& frame) override;
bool setBuffer(const sp<GraphicBuffer>& buffer, const sp<Fence>& acquireFence, nsecs_t postTime,
- nsecs_t desiredPresentTime, const client_cache_t& clientCacheId,
- uint64_t frameNumber) override;
+ nsecs_t desiredPresentTime, bool isAutoTimestamp,
+ const client_cache_t& clientCacheId, uint64_t frameNumber) override;
bool setAcquireFence(const sp<Fence>& fence) override;
bool setDataspace(ui::Dataspace dataspace) override;
bool setHdrMetadata(const HdrMetadata& hdrMetadata) override;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c9e97da..d6023b6 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -275,7 +275,8 @@
// recent callback handle.
std::deque<sp<CallbackHandle>> callbackHandles;
bool colorSpaceAgnostic;
- nsecs_t desiredPresentTime = -1;
+ nsecs_t desiredPresentTime = 0;
+ bool isAutoTimestamp = true;
// Length of the cast shadow. If the radius is > 0, a shadow of length shadowRadius will
// be rendered around the layer.
@@ -444,7 +445,8 @@
virtual bool setFrame(const Rect& /*frame*/) { return false; };
virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/, const sp<Fence>& /*acquireFence*/,
nsecs_t /*postTime*/, nsecs_t /*desiredPresentTime*/,
- const client_cache_t& /*clientCacheId*/, uint64_t /* frameNumber */) {
+ bool /*isAutoTimestamp*/, const client_cache_t& /*clientCacheId*/,
+ uint64_t /* frameNumber */) {
return false;
};
virtual bool setAcquireFence(const sp<Fence>& /*fence*/) { return false; };
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index a959b9a..c291b7f 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -235,7 +235,7 @@
void RefreshRateOverlay::changeRefreshRate(const RefreshRate& refreshRate) {
mCurrentFps = refreshRate.getFps().getIntValue();
auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame];
- mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {},
+ mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {},
mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */));
mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
@@ -247,7 +247,7 @@
const auto& buffers = getOrCreateBuffers(*mCurrentFps);
mFrame = (mFrame + 1) % buffers.size();
auto buffer = buffers[mFrame];
- mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {},
+ mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {},
mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */));
mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 14536b3..68d2a68 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3262,8 +3262,9 @@
applyTransactionState(transaction.frameTimelineVsyncId, transaction.states,
transaction.displays, transaction.flags,
mPendingInputWindowCommands, transaction.desiredPresentTime,
- transaction.buffer, transaction.postTime,
- transaction.privileged, transaction.hasListenerCallbacks,
+ transaction.isAutoTimestamp, transaction.buffer,
+ transaction.postTime, transaction.privileged,
+ transaction.hasListenerCallbacks,
transaction.listenerCallbacks, transaction.originPid,
transaction.originUid, transaction.id, /*isMainThread*/ true);
transactionQueue.pop();
@@ -3294,7 +3295,7 @@
bool ready = true;
// Do not present if the desiredPresentTime has not passed unless it is more than one second
// in the future. We ignore timestamps more than 1 second in the future for stability reasons.
- if (desiredPresentTime >= 0 && desiredPresentTime >= expectedPresentTime &&
+ if (desiredPresentTime > 0 && desiredPresentTime >= expectedPresentTime &&
desiredPresentTime < expectedPresentTime + s2ns(1)) {
ready = false;
}
@@ -3331,7 +3332,7 @@
int64_t frameTimelineVsyncId, const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
- const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
+ bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {
ATRACE_CALL();
@@ -3372,17 +3373,19 @@
const int originPid = ipc->getCallingPid();
const int originUid = ipc->getCallingUid();
- if (pendingTransactions || !transactionIsReadyToBeApplied(desiredPresentTime, states, true)) {
+ if (pendingTransactions ||
+ !transactionIsReadyToBeApplied(isAutoTimestamp ? 0 : desiredPresentTime, states, true)) {
mTransactionQueues[applyToken].emplace(frameTimelineVsyncId, states, displays, flags,
- desiredPresentTime, uncacheBuffer, postTime,
- privileged, hasListenerCallbacks, listenerCallbacks,
- originPid, originUid, transactionId);
+ desiredPresentTime, isAutoTimestamp, uncacheBuffer,
+ postTime, privileged, hasListenerCallbacks,
+ listenerCallbacks, originPid, originUid,
+ transactionId);
setTransactionFlags(eTransactionFlushNeeded);
return NO_ERROR;
}
applyTransactionState(frameTimelineVsyncId, states, displays, flags, inputWindowCommands,
- desiredPresentTime, uncacheBuffer, postTime, privileged,
+ desiredPresentTime, isAutoTimestamp, uncacheBuffer, postTime, privileged,
hasListenerCallbacks, listenerCallbacks, originPid, originUid,
transactionId, /*isMainThread*/ false);
return NO_ERROR;
@@ -3392,9 +3395,10 @@
int64_t frameTimelineVsyncId, const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands, const int64_t desiredPresentTime,
- const client_cache_t& uncacheBuffer, const int64_t postTime, bool privileged,
- bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
- int originPid, int originUid, uint64_t transactionId, bool isMainThread) {
+ bool isAutoTimestamp, const client_cache_t& uncacheBuffer, const int64_t postTime,
+ bool privileged, bool hasListenerCallbacks,
+ const std::vector<ListenerCallbacks>& listenerCallbacks, int originPid, int originUid,
+ uint64_t transactionId, bool isMainThread) {
uint32_t transactionFlags = 0;
if (flags & eAnimation) {
@@ -3428,12 +3432,13 @@
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash> listenerCallbacksWithSurfaces;
uint32_t clientStateFlags = 0;
for (const ComposerState& state : states) {
- clientStateFlags |=
- setClientStateLocked(frameTimelineVsyncId, state, desiredPresentTime, postTime,
- privileged, listenerCallbacksWithSurfaces);
+ clientStateFlags |= setClientStateLocked(frameTimelineVsyncId, state, desiredPresentTime,
+ isAutoTimestamp, postTime, privileged,
+ listenerCallbacksWithSurfaces);
if ((flags & eAnimation) && state.state.surface) {
if (const auto layer = fromHandleLocked(state.state.surface).promote(); layer) {
- mScheduler->recordLayerHistory(layer.get(), desiredPresentTime,
+ mScheduler->recordLayerHistory(layer.get(),
+ isAutoTimestamp ? 0 : desiredPresentTime,
LayerHistory::LayerUpdateType::AnimationTX);
}
}
@@ -3608,7 +3613,7 @@
uint32_t SurfaceFlinger::setClientStateLocked(
int64_t frameTimelineVsyncId, const ComposerState& composerState,
- int64_t desiredPresentTime, int64_t postTime, bool privileged,
+ int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, bool privileged,
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks) {
const layer_state_t& s = composerState.state;
@@ -3919,8 +3924,8 @@
? s.frameNumber
: layer->getHeadFrameNumber(-1 /* expectedPresentTime */) + 1;
- if (layer->setBuffer(buffer, s.acquireFence, postTime, desiredPresentTime, s.cachedBuffer,
- frameNumber)) {
+ if (layer->setBuffer(buffer, s.acquireFence, postTime, desiredPresentTime, isAutoTimestamp,
+ s.cachedBuffer, frameNumber)) {
flags |= eTraversalNeeded;
}
}
@@ -4198,7 +4203,7 @@
d.height = 0;
displays.add(d);
setTransactionState(ISurfaceComposer::INVALID_VSYNC_ID, state, displays, 0, nullptr,
- mPendingInputWindowCommands, -1, {}, false, {},
+ mPendingInputWindowCommands, systemTime(), true, {}, false, {},
0 /* Undefined transactionId */);
setPowerModeInternal(display, hal::PowerMode::ON);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index e3e9c4f..db75312 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -341,7 +341,7 @@
virtual uint32_t setClientStateLocked(
int64_t frameTimelineVsyncId, const ComposerState& composerState,
- int64_t desiredPresentTime, int64_t postTime, bool privileged,
+ int64_t desiredPresentTime, bool isAutoTimestamp, int64_t postTime, bool privileged,
std::unordered_set<ListenerCallbacks, ListenerCallbacksHash>& listenerCallbacks)
REQUIRES(mStateLock);
virtual void commitTransactionLocked();
@@ -434,8 +434,9 @@
struct TransactionState {
TransactionState(int64_t frameTimelineVsyncId, const Vector<ComposerState>& composerStates,
const Vector<DisplayState>& displayStates, uint32_t transactionFlags,
- int64_t desiredPresentTime, const client_cache_t& uncacheBuffer,
- int64_t postTime, bool privileged, bool hasListenerCallbacks,
+ int64_t desiredPresentTime, bool isAutoTimestamp,
+ const client_cache_t& uncacheBuffer, int64_t postTime, bool privileged,
+ bool hasListenerCallbacks,
std::vector<ListenerCallbacks> listenerCallbacks, int originPid,
int originUid, uint64_t transactionId)
: frameTimelineVsyncId(frameTimelineVsyncId),
@@ -443,6 +444,7 @@
displays(displayStates),
flags(transactionFlags),
desiredPresentTime(desiredPresentTime),
+ isAutoTimestamp(isAutoTimestamp),
buffer(uncacheBuffer),
postTime(postTime),
privileged(privileged),
@@ -457,6 +459,7 @@
Vector<DisplayState> displays;
uint32_t flags;
const int64_t desiredPresentTime;
+ const bool isAutoTimestamp;
client_cache_t buffer;
const int64_t postTime;
bool privileged;
@@ -520,8 +523,8 @@
const Vector<DisplayState>& displays, uint32_t flags,
const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands,
- int64_t desiredPresentTime, const client_cache_t& uncacheBuffer,
- bool hasListenerCallbacks,
+ int64_t desiredPresentTime, bool isAutoTimestamp,
+ const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks,
uint64_t transactionId) override;
void bootFinished() override;
@@ -723,7 +726,7 @@
void applyTransactionState(int64_t frameTimelineVsyncId, const Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags,
const InputWindowCommands& inputWindowCommands,
- const int64_t desiredPresentTime,
+ const int64_t desiredPresentTime, bool isAutoTimestamp,
const client_cache_t& uncacheBuffer, const int64_t postTime,
bool privileged, bool hasListenerCallbacks,
const std::vector<ListenerCallbacks>& listenerCallbacks,
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index c98004a..25aaa14 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -371,14 +371,14 @@
const Vector<DisplayState>& displays, uint32_t flags,
const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands,
- int64_t desiredPresentTime, const client_cache_t& uncacheBuffer,
- bool hasListenerCallbacks,
+ int64_t desiredPresentTime, bool isAutoTimestamp,
+ const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
std::vector<ListenerCallbacks>& listenerCallbacks,
uint64_t transactionId) {
return mFlinger->setTransactionState(frameTimelineVsyncId, states, displays, flags,
applyToken, inputWindowCommands, desiredPresentTime,
- uncacheBuffer, hasListenerCallbacks, listenerCallbacks,
- transactionId);
+ isAutoTimestamp, uncacheBuffer, hasListenerCallbacks,
+ listenerCallbacks, transactionId);
}
auto flushTransactionQueues() { return mFlinger->flushTransactionQueues(); };
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index c36d994..fa6ff30 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -97,7 +97,8 @@
uint32_t flags = 0;
sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
InputWindowCommands inputWindowCommands;
- int64_t desiredPresentTime = -1;
+ int64_t desiredPresentTime = 0;
+ bool isAutoTimestamp = true;
int64_t frameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID;
client_cache_t uncacheBuffer;
int64_t id = -1;
@@ -114,11 +115,13 @@
}
void setupSingle(TransactionInfo& transaction, uint32_t flags, bool syncInputWindows,
- int64_t desiredPresentTime, int64_t frameTimelineVsyncId) {
+ int64_t desiredPresentTime, bool isAutoTimestamp,
+ int64_t frameTimelineVsyncId) {
mTransactionNumber++;
transaction.flags |= flags; // ISurfaceComposer::eSynchronous;
transaction.inputWindowCommands.syncInputWindows = syncInputWindows;
transaction.desiredPresentTime = desiredPresentTime;
+ transaction.isAutoTimestamp = isAutoTimestamp;
transaction.frameTimelineVsyncId = frameTimelineVsyncId;
}
@@ -129,13 +132,15 @@
EXPECT_CALL(*mVSyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillOnce(Return(systemTime()));
TransactionInfo transaction;
setupSingle(transaction, flags, syncInputWindows,
- /*desiredPresentTime*/ -1, ISurfaceComposer::INVALID_VSYNC_ID);
+ /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
+ ISurfaceComposer::INVALID_VSYNC_ID);
nsecs_t applicationTime = systemTime();
mFlinger.setTransactionState(transaction.frameTimelineVsyncId, transaction.states,
transaction.displays, transaction.flags,
transaction.applyToken, transaction.inputWindowCommands,
- transaction.desiredPresentTime, transaction.uncacheBuffer,
- mHasListenerCallbacks, mCallbacks, transaction.id);
+ transaction.desiredPresentTime, transaction.isAutoTimestamp,
+ transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
+ transaction.id);
// This transaction should not have been placed on the transaction queue.
// If transaction is synchronous or syncs input windows, SF
@@ -164,13 +169,15 @@
.WillOnce(Return(time + nsecs_t(5 * 1e8)));
TransactionInfo transaction;
setupSingle(transaction, flags, syncInputWindows,
- /*desiredPresentTime*/ time + s2ns(1), ISurfaceComposer::INVALID_VSYNC_ID);
+ /*desiredPresentTime*/ time + s2ns(1), false,
+ ISurfaceComposer::INVALID_VSYNC_ID);
nsecs_t applicationSentTime = systemTime();
mFlinger.setTransactionState(transaction.frameTimelineVsyncId, transaction.states,
transaction.displays, transaction.flags,
transaction.applyToken, transaction.inputWindowCommands,
- transaction.desiredPresentTime, transaction.uncacheBuffer,
- mHasListenerCallbacks, mCallbacks, transaction.id);
+ transaction.desiredPresentTime, transaction.isAutoTimestamp,
+ transaction.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
+ transaction.id);
nsecs_t returnedTime = systemTime();
EXPECT_LE(returnedTime, applicationSentTime + s2ns(5));
@@ -189,20 +196,23 @@
// transaction that should go on the pending thread
TransactionInfo transactionA;
setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
- /*desiredPresentTime*/ time + s2ns(1), ISurfaceComposer::INVALID_VSYNC_ID);
+ /*desiredPresentTime*/ time + s2ns(1), false,
+ ISurfaceComposer::INVALID_VSYNC_ID);
// transaction that would not have gone on the pending thread if not
// blocked
TransactionInfo transactionB;
setupSingle(transactionB, flags, syncInputWindows,
- /*desiredPresentTime*/ -1, ISurfaceComposer::INVALID_VSYNC_ID);
+ /*desiredPresentTime*/ systemTime(), /*isAutoTimestamp*/ true,
+ ISurfaceComposer::INVALID_VSYNC_ID);
nsecs_t applicationSentTime = systemTime();
mFlinger.setTransactionState(transactionA.frameTimelineVsyncId, transactionA.states,
transactionA.displays, transactionA.flags,
transactionA.applyToken, transactionA.inputWindowCommands,
- transactionA.desiredPresentTime, transactionA.uncacheBuffer,
- mHasListenerCallbacks, mCallbacks, transactionA.id);
+ transactionA.desiredPresentTime, transactionA.isAutoTimestamp,
+ transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
+ transactionA.id);
// This thread should not have been blocked by the above transaction
// (5s is the timeout period that applyTransactionState waits for SF to
@@ -213,8 +223,9 @@
mFlinger.setTransactionState(transactionB.frameTimelineVsyncId, transactionB.states,
transactionB.displays, transactionB.flags,
transactionB.applyToken, transactionB.inputWindowCommands,
- transactionB.desiredPresentTime, transactionB.uncacheBuffer,
- mHasListenerCallbacks, mCallbacks, transactionB.id);
+ transactionB.desiredPresentTime, transactionB.isAutoTimestamp,
+ transactionB.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
+ transactionB.id);
// this thread should have been blocked by the above transaction
// if this is an animation, this thread should be blocked for 5s
@@ -256,12 +267,12 @@
.WillOnce(Return(s2ns(2)));
TransactionInfo transactionA; // transaction to go on pending queue
setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
- /*desiredPresentTime*/ s2ns(1), ISurfaceComposer::INVALID_VSYNC_ID);
+ /*desiredPresentTime*/ s2ns(1), false, ISurfaceComposer::INVALID_VSYNC_ID);
mFlinger.setTransactionState(transactionA.frameTimelineVsyncId, transactionA.states,
transactionA.displays, transactionA.flags, transactionA.applyToken,
transactionA.inputWindowCommands, transactionA.desiredPresentTime,
- transactionA.uncacheBuffer, mHasListenerCallbacks, mCallbacks,
- transactionA.id);
+ transactionA.isAutoTimestamp, transactionA.uncacheBuffer,
+ mHasListenerCallbacks, mCallbacks, transactionA.id);
auto& transactionQueue = mFlinger.getTransactionQueue();
ASSERT_EQ(1, transactionQueue.size());
@@ -279,8 +290,8 @@
empty.applyToken = sp<IBinder>();
mFlinger.setTransactionState(empty.frameTimelineVsyncId, empty.states, empty.displays,
empty.flags, empty.applyToken, empty.inputWindowCommands,
- empty.desiredPresentTime, empty.uncacheBuffer,
- mHasListenerCallbacks, mCallbacks, empty.id);
+ empty.desiredPresentTime, empty.isAutoTimestamp,
+ empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks, empty.id);
// flush transaction queue should flush as desiredPresentTime has
// passed