Merge "TransactionCallbackInvoker: Send callbacks on thread"
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++;
diff --git a/services/surfaceflinger/TransactionCallbackInvoker.h b/services/surfaceflinger/TransactionCallbackInvoker.h
index 71ca6e5..7e879e1 100644
--- a/services/surfaceflinger/TransactionCallbackInvoker.h
+++ b/services/surfaceflinger/TransactionCallbackInvoker.h
@@ -18,6 +18,7 @@
#include <condition_variable>
#include <deque>
+#include <queue>
#include <mutex>
#include <thread>
#include <unordered_map>
@@ -56,8 +57,11 @@
class TransactionCallbackInvoker {
public:
+ TransactionCallbackInvoker();
+ ~TransactionCallbackInvoker();
+
status_t addCallbackHandles(const std::deque<sp<CallbackHandle>>& handles,
- const std::vector<JankData>& jankData);
+ const std::vector<JankData>& jankData);
status_t addOnCommitCallbackHandles(const std::deque<sp<CallbackHandle>>& handles,
std::deque<sp<CallbackHandle>>& outRemainingHandles);
@@ -88,6 +92,12 @@
mCompletedTransactions;
sp<Fence> mPresentFence;
+
+ std::mutex mCallbackThreadMutex;
+ std::condition_variable mCallbackConditionVariable;
+ std::thread mThread;
+ bool mKeepRunning = true;
+ std::queue<std::function<void()>> mCallbackThreadWork;
};
} // namespace android