TransactionCallbackInvoker: Send callbacks on thread
The binder serialization cost and one way method cost can add up
when we have multiple layers. We invoked these callbacks directly
from the main thread in order to reduce latency. Latency requirements
are now loosened by two changes:
1. Most of the time we have a queue on the server side
and won't be trying to make the next frame from the callback
2. In GL comp where frames are back to back, we now have
release at latch.
Bug: 201436596
Test: Existing tests pass
Change-Id: I1372022b5130e041d6b2429a2e87e2c622086d7a
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index 4b12a26..c1eb896 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -49,6 +49,31 @@
return !callbacks.empty() && callbacks.front().type == CallbackId::Type::ON_COMMIT;
}
+TransactionCallbackInvoker::TransactionCallbackInvoker() {
+ mThread = std::thread([&]() {
+ std::unique_lock lock(mCallbackThreadMutex);
+
+ while (mKeepRunning) {
+ while (mCallbackThreadWork.size() > 0) {
+ mCallbackThreadWork.front()();
+ mCallbackThreadWork.pop();
+ }
+ mCallbackConditionVariable.wait(lock);
+ }
+ });
+}
+
+TransactionCallbackInvoker::~TransactionCallbackInvoker() {
+ {
+ std::unique_lock lock(mCallbackThreadMutex);
+ mKeepRunning = false;
+ mCallbackConditionVariable.notify_all();
+ }
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+}
+
void TransactionCallbackInvoker::addEmptyTransaction(const ListenerCallbacks& listenerCallbacks) {
auto& [listener, callbackIds] = listenerCallbacks;
auto& transactionStatsDeque = mCompletedTransactions[listener];
@@ -180,8 +205,15 @@
// keep it as an IBinder due to consistency reasons: if we
// interface_cast at the IPC boundary when reading a Parcel,
// we get pointers that compare unequal in the SF process.
- interface_cast<ITransactionCompletedListener>(listenerStats.listener)
- ->onTransactionCompleted(listenerStats);
+ {
+ std::unique_lock lock(mCallbackThreadMutex);
+ mCallbackThreadWork.push(
+ [stats = std::move(listenerStats)]() {
+ interface_cast<ITransactionCompletedListener>(stats.listener)
+ ->onTransactionCompleted(stats);
+ });
+ mCallbackConditionVariable.notify_all();
+ }
}
}
completedTransactionsItr++;