Loading services/surfaceflinger/TransactionCallbackInvoker.cpp +34 −2 Original line number Diff line number Diff line Loading @@ -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]; Loading Loading @@ -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++; Loading services/surfaceflinger/TransactionCallbackInvoker.h +11 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <condition_variable> #include <deque> #include <queue> #include <mutex> #include <thread> #include <unordered_map> Loading Loading @@ -56,6 +57,9 @@ public: class TransactionCallbackInvoker { public: TransactionCallbackInvoker(); ~TransactionCallbackInvoker(); status_t addCallbackHandles(const std::deque<sp<CallbackHandle>>& handles, const std::vector<JankData>& jankData); status_t addOnCommitCallbackHandles(const std::deque<sp<CallbackHandle>>& handles, Loading Loading @@ -88,6 +92,12 @@ private: 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 Loading
services/surfaceflinger/TransactionCallbackInvoker.cpp +34 −2 Original line number Diff line number Diff line Loading @@ -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]; Loading Loading @@ -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++; Loading
services/surfaceflinger/TransactionCallbackInvoker.h +11 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ #include <condition_variable> #include <deque> #include <queue> #include <mutex> #include <thread> #include <unordered_map> Loading Loading @@ -56,6 +57,9 @@ public: class TransactionCallbackInvoker { public: TransactionCallbackInvoker(); ~TransactionCallbackInvoker(); status_t addCallbackHandles(const std::deque<sp<CallbackHandle>>& handles, const std::vector<JankData>& jankData); status_t addOnCommitCallbackHandles(const std::deque<sp<CallbackHandle>>& handles, Loading Loading @@ -88,6 +92,12 @@ private: 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