SurfaceFlinger: add transactions to FrameTimeline
Allow transaction clients to specify the vsyncId that started the
transaction and plumb this data to FrameTimeline to be able
to track jank associated with transactions
Bug: 166302754
Test: manually see transactions in frame timeline
Change-Id: Id05e0d0a73039204943d93b666cb67e3e7515a69
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
index 409f90d..2c8178e 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
@@ -118,7 +118,11 @@
}
void RefreshRateSelectionTest::commitTransaction(Layer* layer) {
- layer->commitTransaction(layer->getCurrentState());
+ layer->pushPendingState();
+ auto c = layer->getCurrentState();
+ if (layer->applyPendingStates(&c)) {
+ layer->commitTransaction(c);
+ }
}
void RefreshRateSelectionTest::setupScheduler() {
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index d4591fc..efee826 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -157,7 +157,11 @@
void SetFrameRateTest::commitTransaction() {
for (auto layer : mLayers) {
- layer.get()->commitTransaction(layer.get()->getCurrentState());
+ layer->pushPendingState();
+ auto c = layer->getCurrentState();
+ if (layer->applyPendingStates(&c)) {
+ layer->commitTransaction(c);
+ }
}
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 37f159c..8c12e94 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -348,7 +348,7 @@
auto& getTransactionQueue() { return mFlinger->mTransactionQueues; }
- auto setTransactionState(const Vector<ComposerState>& states,
+ auto setTransactionState(int64_t frameTimelineVsyncId, const Vector<ComposerState>& states,
const Vector<DisplayState>& displays, uint32_t flags,
const sp<IBinder>& applyToken,
const InputWindowCommands& inputWindowCommands,
@@ -356,9 +356,9 @@
bool hasListenerCallbacks,
std::vector<ListenerCallbacks>& listenerCallbacks,
uint64_t transactionId) {
- return mFlinger->setTransactionState(states, displays, flags, applyToken,
- inputWindowCommands, desiredPresentTime, uncacheBuffer,
- hasListenerCallbacks, listenerCallbacks,
+ return mFlinger->setTransactionState(frameTimelineVsyncId, states, displays, flags,
+ applyToken, inputWindowCommands, desiredPresentTime,
+ uncacheBuffer, hasListenerCallbacks, listenerCallbacks,
transactionId);
}
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 7151a52..760bf65 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -100,6 +100,7 @@
sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
InputWindowCommands inputWindowCommands;
int64_t desiredPresentTime = -1;
+ int64_t frameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID;
client_cache_t uncacheBuffer;
int64_t id = -1;
};
@@ -115,11 +116,12 @@
}
void setupSingle(TransactionInfo& transaction, uint32_t flags, bool syncInputWindows,
- int64_t desiredPresentTime) {
+ int64_t desiredPresentTime, int64_t frameTimelineVsyncId) {
mTransactionNumber++;
transaction.flags |= flags; // ISurfaceComposer::eSynchronous;
transaction.inputWindowCommands.syncInputWindows = syncInputWindows;
transaction.desiredPresentTime = desiredPresentTime;
+ transaction.frameTimelineVsyncId = frameTimelineVsyncId;
}
void NotPlacedOnTransactionQueue(uint32_t flags, bool syncInputWindows) {
@@ -129,9 +131,10 @@
EXPECT_CALL(*mVSyncTracker, nextAnticipatedVSyncTimeFrom(_)).WillOnce(Return(systemTime()));
TransactionInfo transaction;
setupSingle(transaction, flags, syncInputWindows,
- /*desiredPresentTime*/ -1);
+ /*desiredPresentTime*/ -1, ISurfaceComposer::INVALID_VSYNC_ID);
nsecs_t applicationTime = systemTime();
- mFlinger.setTransactionState(transaction.states, transaction.displays, transaction.flags,
+ mFlinger.setTransactionState(transaction.frameTimelineVsyncId, transaction.states,
+ transaction.displays, transaction.flags,
transaction.applyToken, transaction.inputWindowCommands,
transaction.desiredPresentTime, transaction.uncacheBuffer,
mHasListenerCallbacks, mCallbacks, transaction.id);
@@ -163,9 +166,10 @@
.WillOnce(Return(time + nsecs_t(5 * 1e8)));
TransactionInfo transaction;
setupSingle(transaction, flags, syncInputWindows,
- /*desiredPresentTime*/ time + s2ns(1));
+ /*desiredPresentTime*/ time + s2ns(1), ISurfaceComposer::INVALID_VSYNC_ID);
nsecs_t applicationSentTime = systemTime();
- mFlinger.setTransactionState(transaction.states, transaction.displays, transaction.flags,
+ mFlinger.setTransactionState(transaction.frameTimelineVsyncId, transaction.states,
+ transaction.displays, transaction.flags,
transaction.applyToken, transaction.inputWindowCommands,
transaction.desiredPresentTime, transaction.uncacheBuffer,
mHasListenerCallbacks, mCallbacks, transaction.id);
@@ -187,16 +191,17 @@
// transaction that should go on the pending thread
TransactionInfo transactionA;
setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
- /*desiredPresentTime*/ time + s2ns(1));
+ /*desiredPresentTime*/ time + s2ns(1), 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);
+ /*desiredPresentTime*/ -1, ISurfaceComposer::INVALID_VSYNC_ID);
nsecs_t applicationSentTime = systemTime();
- mFlinger.setTransactionState(transactionA.states, transactionA.displays, transactionA.flags,
+ mFlinger.setTransactionState(transactionA.frameTimelineVsyncId, transactionA.states,
+ transactionA.displays, transactionA.flags,
transactionA.applyToken, transactionA.inputWindowCommands,
transactionA.desiredPresentTime, transactionA.uncacheBuffer,
mHasListenerCallbacks, mCallbacks, transactionA.id);
@@ -207,7 +212,8 @@
EXPECT_LE(systemTime(), applicationSentTime + s2ns(5));
applicationSentTime = systemTime();
- mFlinger.setTransactionState(transactionB.states, transactionB.displays, transactionB.flags,
+ mFlinger.setTransactionState(transactionB.frameTimelineVsyncId, transactionB.states,
+ transactionB.displays, transactionB.flags,
transactionB.applyToken, transactionB.inputWindowCommands,
transactionB.desiredPresentTime, transactionB.uncacheBuffer,
mHasListenerCallbacks, mCallbacks, transactionB.id);
@@ -252,11 +258,12 @@
.WillOnce(Return(s2ns(2)));
TransactionInfo transactionA; // transaction to go on pending queue
setupSingle(transactionA, /*flags*/ 0, /*syncInputWindows*/ false,
- /*desiredPresentTime*/ s2ns(1));
- mFlinger.setTransactionState(transactionA.states, transactionA.displays, transactionA.flags,
- transactionA.applyToken, transactionA.inputWindowCommands,
- transactionA.desiredPresentTime, transactionA.uncacheBuffer,
- mHasListenerCallbacks, mCallbacks, transactionA.id);
+ /*desiredPresentTime*/ s2ns(1), 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);
auto& transactionQueue = mFlinger.getTransactionQueue();
ASSERT_EQ(1, transactionQueue.size());
@@ -272,9 +279,10 @@
// different process) to re-query and reset the cached expected present time
TransactionInfo empty;
empty.applyToken = sp<IBinder>();
- mFlinger.setTransactionState(empty.states, empty.displays, empty.flags, empty.applyToken,
- empty.inputWindowCommands, empty.desiredPresentTime,
- empty.uncacheBuffer, mHasListenerCallbacks, mCallbacks, empty.id);
+ mFlinger.setTransactionState(empty.frameTimelineVsyncId, empty.states, empty.displays,
+ empty.flags, empty.applyToken, empty.inputWindowCommands,
+ empty.desiredPresentTime, empty.uncacheBuffer,
+ mHasListenerCallbacks, mCallbacks, empty.id);
// flush transaction queue should flush as desiredPresentTime has
// passed