SurfaceFlinger: LocklessQueue for transaction queue
Test: presubmit
Test: go/wm-smoke
Bug: 238781169
Change-Id: If23f4eae1c4bb652abbe8109f728bde20f7f66e5
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index 84f1170..b2da34e 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -117,7 +117,7 @@
}
void NotPlacedOnTransactionQueue(uint32_t flags) {
- ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
+ ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
TransactionInfo transaction;
setupSingle(transaction, flags,
@@ -140,12 +140,12 @@
EXPECT_LE(returnedTime, applicationTime + mFlinger.getAnimationTransactionTimeout());
}
// Each transaction should have been placed on the transaction queue
- auto transactionQueue = mFlinger.getTransactionQueue();
- EXPECT_EQ(1u, transactionQueue.size());
+ auto& transactionQueue = mFlinger.getTransactionQueue();
+ EXPECT_FALSE(transactionQueue.isEmpty());
}
void PlaceOnTransactionQueue(uint32_t flags) {
- ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
+ ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
// first check will see desired present time has not passed,
@@ -171,12 +171,12 @@
applicationSentTime + mFlinger.getAnimationTransactionTimeout());
}
// This transaction should have been placed on the transaction queue
- auto transactionQueue = mFlinger.getTransactionQueue();
- EXPECT_EQ(1u, transactionQueue.size());
+ auto& transactionQueue = mFlinger.getTransactionQueue();
+ EXPECT_FALSE(transactionQueue.isEmpty());
}
void BlockedByPriorTransaction(uint32_t flags) {
- ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
+ ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
nsecs_t time = systemTime();
EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(2);
@@ -239,8 +239,8 @@
int mTransactionNumber = 0;
};
-TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
- ASSERT_EQ(0u, mFlinger.getTransactionQueue().size());
+TEST_F(TransactionApplicationTest, AddToPendingQueue) {
+ ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
TransactionInfo transactionA; // transaction to go on pending queue
@@ -253,10 +253,27 @@
mHasListenerCallbacks, mCallbacks, transactionA.id);
auto& transactionQueue = mFlinger.getTransactionQueue();
- ASSERT_EQ(1u, transactionQueue.size());
+ ASSERT_FALSE(transactionQueue.isEmpty());
- auto& transactionState = transactionQueue.front();
+ auto transactionState = transactionQueue.pop().value();
checkEqual(transactionA, transactionState);
+}
+
+TEST_F(TransactionApplicationTest, Flush_RemovesFromQueue) {
+ ASSERT_TRUE(mFlinger.getTransactionQueue().isEmpty());
+ EXPECT_CALL(*mFlinger.scheduler(), scheduleFrame()).Times(1);
+
+ TransactionInfo transactionA; // transaction to go on pending queue
+ setupSingle(transactionA, /*flags*/ 0, /*desiredPresentTime*/ s2ns(1), false,
+ FrameTimelineInfo{});
+ mFlinger.setTransactionState(transactionA.frameTimelineInfo, transactionA.states,
+ transactionA.displays, transactionA.flags, transactionA.applyToken,
+ transactionA.inputWindowCommands, transactionA.desiredPresentTime,
+ transactionA.isAutoTimestamp, transactionA.uncacheBuffer,
+ mHasListenerCallbacks, mCallbacks, transactionA.id);
+
+ auto& transactionQueue = mFlinger.getTransactionQueue();
+ ASSERT_FALSE(transactionQueue.isEmpty());
// because flushing uses the cached expected present time, we send an empty
// transaction here (sending a null applyToken to fake it as from a
@@ -272,7 +289,7 @@
// passed
mFlinger.flushTransactionQueues();
- EXPECT_EQ(0u, transactionQueue.size());
+ EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
}
TEST_F(TransactionApplicationTest, NotPlacedOnTransactionQueue_Synchronous) {
@@ -306,7 +323,9 @@
void TearDown() override {
// Clear all transaction queues to release all transactions we sent
// in the tests. Otherwise, gmock complains about memory leaks.
- mFlinger.getTransactionQueue().clear();
+ while (!mFlinger.getTransactionQueue().isEmpty()) {
+ mFlinger.getTransactionQueue().pop();
+ }
mFlinger.getPendingTransactionQueue().clear();
mFlinger.getTransactionCommittedSignals().clear();
mFlinger.commitTransactionsLocked(eTransactionMask);
@@ -358,7 +377,7 @@
void setTransactionStates(const std::vector<TransactionInfo>& transactions,
size_t expectedTransactionsApplied,
size_t expectedTransactionsPending) {
- EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
+ EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
EXPECT_EQ(0u, mFlinger.getPendingTransactionQueue().size());
for (const auto& transaction : transactions) {
@@ -370,7 +389,7 @@
mHasListenerCallbacks, mCallbacks, transaction.id);
}
mFlinger.flushTransactionQueues();
- EXPECT_EQ(0u, mFlinger.getTransactionQueue().size());
+ EXPECT_TRUE(mFlinger.getTransactionQueue().isEmpty());
EXPECT_EQ(expectedTransactionsPending, mFlinger.getPendingTransactionQueue().size());
EXPECT_EQ(expectedTransactionsApplied, mFlinger.getTransactionCommittedSignals().size());
}