summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/TransactionCallbackInvoker.cpp
diff options
context:
space:
mode:
author Robert Carr <racarr@google.com> 2021-09-28 17:46:57 -0700
committer Rob Carr <racarr@google.com> 2021-10-11 18:25:56 +0000
commit3ec2b85e6b682ba5426a48144b7a0fc2ee507e84 (patch)
tree52fa5fa4de727d55190ebee3755251d285e1c11c /services/surfaceflinger/TransactionCallbackInvoker.cpp
parent6cb6100dd6c1f4a2d50a74905df46b84382236cc (diff)
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
Diffstat (limited to 'services/surfaceflinger/TransactionCallbackInvoker.cpp')
-rw-r--r--services/surfaceflinger/TransactionCallbackInvoker.cpp36
1 files changed, 34 insertions, 2 deletions
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.cpp b/services/surfaceflinger/TransactionCallbackInvoker.cpp
index 4b12a2640b..c1eb8966d1 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.cpp
+++ b/services/surfaceflinger/TransactionCallbackInvoker.cpp
@@ -49,6 +49,31 @@ static bool containsOnCommitCallbacks(const std::vector<CallbackId>& callbacks)
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 @@ void TransactionCallbackInvoker::sendCallbacks() {
// 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++;