blob: 9b9dc57781f42cfd8f7ddd3b333616d77e802b62 [file] [log] [blame]
Marissa Walle2ffb422018-10-12 11:33:52 -07001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#undef LOG_TAG
19#define LOG_TAG "TransactionCompletedThread"
20#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21
22#include "TransactionCompletedThread.h"
23
24#include <cinttypes>
25
26#include <binder/IInterface.h>
27#include <gui/ITransactionCompletedListener.h>
28#include <utils/RefBase.h>
29
30namespace android {
31
32TransactionCompletedThread::~TransactionCompletedThread() {
33 {
34 std::lock_guard lock(mMutex);
35 mKeepRunning = false;
36 mConditionVariable.notify_all();
37 }
38
Marissa Wall05d9dd32018-11-13 10:05:14 -080039 if (mThread.joinable()) {
40 mThread.join();
41 }
Marissa Walle2ffb422018-10-12 11:33:52 -070042
43 {
44 std::lock_guard lock(mMutex);
45 for (const auto& [listener, listenerStats] : mListenerStats) {
46 listener->unlinkToDeath(mDeathRecipient);
47 }
48 }
49}
50
51void TransactionCompletedThread::run() {
52 std::lock_guard lock(mMutex);
53 if (mRunning) {
54 return;
55 }
56 mDeathRecipient = new ThreadDeathRecipient();
57 mRunning = true;
58 mThread = std::thread(&TransactionCompletedThread::threadMain, this);
59}
60
61void TransactionCompletedThread::registerPendingLatchedCallbackHandle(
62 const sp<CallbackHandle>& handle) {
63 std::lock_guard lock(mMutex);
64
65 sp<IBinder> listener = IInterface::asBinder(handle->listener);
66 const auto& callbackIds = handle->callbackIds;
67
68 mPendingTransactions[listener][callbackIds]++;
69}
70
71void TransactionCompletedThread::addLatchedCallbackHandles(
Marissa Wallfda30bb2018-10-12 11:34:28 -070072 const std::deque<sp<CallbackHandle>>& handles, nsecs_t latchTime,
73 const sp<Fence>& previousReleaseFence) {
Marissa Walle2ffb422018-10-12 11:33:52 -070074 std::lock_guard lock(mMutex);
75
Marissa Wallfda30bb2018-10-12 11:34:28 -070076 // If the previous release fences have not signaled, something as probably gone wrong.
77 // Store the fences and check them again before sending a callback.
78 if (previousReleaseFence &&
79 previousReleaseFence->getSignalTime() == Fence::SIGNAL_TIME_PENDING) {
80 ALOGD("release fence from the previous frame has not signaled");
81 mPreviousReleaseFences.push_back(previousReleaseFence);
82 }
83
Marissa Walle2ffb422018-10-12 11:33:52 -070084 for (const auto& handle : handles) {
85 auto listener = mPendingTransactions.find(IInterface::asBinder(handle->listener));
86 auto& pendingCallbacks = listener->second;
87 auto pendingCallback = pendingCallbacks.find(handle->callbackIds);
88
89 if (pendingCallback != pendingCallbacks.end()) {
90 auto& pendingCount = pendingCallback->second;
91
92 // Decrease the pending count for this listener
93 if (--pendingCount == 0) {
94 pendingCallbacks.erase(pendingCallback);
95 }
96 } else {
Marissa Wallfda30bb2018-10-12 11:34:28 -070097 ALOGE("there are more latched callbacks than there were registered callbacks");
Marissa Walle2ffb422018-10-12 11:33:52 -070098 }
99
Marissa Wallfda30bb2018-10-12 11:34:28 -0700100 addCallbackHandle(handle, latchTime);
Marissa Walle2ffb422018-10-12 11:33:52 -0700101 }
102}
103
104void TransactionCompletedThread::addUnlatchedCallbackHandle(const sp<CallbackHandle>& handle) {
105 std::lock_guard lock(mMutex);
106 addCallbackHandle(handle);
107}
108
Marissa Wallfda30bb2018-10-12 11:34:28 -0700109void TransactionCompletedThread::addCallbackHandle(const sp<CallbackHandle>& handle,
110 nsecs_t latchTime) {
Marissa Walle2ffb422018-10-12 11:33:52 -0700111 const sp<IBinder> listener = IInterface::asBinder(handle->listener);
112
113 // If we don't already have a reference to this listener, linkToDeath so we get a notification
114 // if it dies.
115 if (mListenerStats.count(listener) == 0) {
116 status_t error = listener->linkToDeath(mDeathRecipient);
117 if (error != NO_ERROR) {
118 ALOGE("cannot add callback handle because linkToDeath failed, err: %d", error);
119 return;
120 }
121 }
122
123 auto& listenerStats = mListenerStats[listener];
124 listenerStats.listener = handle->listener;
125
126 auto& transactionStats = listenerStats.transactionStats[handle->callbackIds];
Marissa Wallfda30bb2018-10-12 11:34:28 -0700127 transactionStats.latchTime = latchTime;
128 transactionStats.surfaceStats.emplace_back(handle->surfaceControl, handle->acquireTime,
129 handle->releasePreviousBuffer);
130}
131
132void TransactionCompletedThread::addPresentFence(const sp<Fence>& presentFence) {
133 std::lock_guard<std::mutex> lock(mMutex);
134 mPresentFence = presentFence;
Marissa Walle2ffb422018-10-12 11:33:52 -0700135}
136
137void TransactionCompletedThread::sendCallbacks() {
138 std::lock_guard lock(mMutex);
139 if (mRunning) {
140 mConditionVariable.notify_all();
141 }
142}
143
144void TransactionCompletedThread::threadMain() {
145 std::lock_guard lock(mMutex);
146
147 while (mKeepRunning) {
148 mConditionVariable.wait(mMutex);
149
Marissa Wallfda30bb2018-10-12 11:34:28 -0700150 // Present fence should fire almost immediately. If the fence has not signaled in 100ms,
151 // there is a major problem and it will probably never fire.
152 nsecs_t presentTime = -1;
153 if (mPresentFence) {
154 status_t status = mPresentFence->wait(100);
155 if (status == NO_ERROR) {
156 presentTime = mPresentFence->getSignalTime();
157 } else {
158 ALOGE("present fence has not signaled, err %d", status);
159 }
160 }
161
162 // We should never hit this case. The release fences from the previous frame should have
163 // signaled long before the current frame is presented.
164 for (const auto& fence : mPreviousReleaseFences) {
165 status_t status = fence->wait(100);
166 if (status != NO_ERROR) {
167 ALOGE("previous release fence has not signaled, err %d", status);
168 }
169 }
170
Marissa Walle2ffb422018-10-12 11:33:52 -0700171 // For each listener
172 auto it = mListenerStats.begin();
173 while (it != mListenerStats.end()) {
174 auto& [listener, listenerStats] = *it;
175
176 // For each transaction
177 bool sendCallback = true;
178 for (auto& [callbackIds, transactionStats] : listenerStats.transactionStats) {
179 // If we are still waiting on the callback handles for this transaction, skip it
180 if (mPendingTransactions[listener].count(callbackIds) != 0) {
181 sendCallback = false;
182 break;
183 }
Marissa Wallfda30bb2018-10-12 11:34:28 -0700184
185 // If the transaction has been latched
186 if (transactionStats.latchTime >= 0) {
187 // If the present time is < 0, this transaction has been latched but not
188 // presented. Skip it for now. This can happen when a new transaction comes
189 // in between the latch and present steps. sendCallbacks is called by
190 // SurfaceFlinger when the transaction is received to ensure that if the
191 // transaction that didn't update state it still got a callback.
192 if (presentTime < 0) {
193 sendCallback = false;
194 break;
195 }
196
197 transactionStats.presentTime = presentTime;
198 }
Marissa Walle2ffb422018-10-12 11:33:52 -0700199 }
200 // If the listener has no pending transactions and all latched transactions have been
201 // presented
202 if (sendCallback) {
203 // If the listener is still alive
204 if (listener->isBinderAlive()) {
205 // Send callback
206 listenerStats.listener->onTransactionCompleted(listenerStats);
207 listener->unlinkToDeath(mDeathRecipient);
208 }
209 it = mListenerStats.erase(it);
210 } else {
211 it++;
212 }
213 }
Marissa Wallfda30bb2018-10-12 11:34:28 -0700214
215 if (mPresentFence) {
216 mPresentFence.clear();
217 mPreviousReleaseFences.clear();
218 }
Marissa Walle2ffb422018-10-12 11:33:52 -0700219 }
220}
221
222// -----------------------------------------------------------------------
223
224CallbackHandle::CallbackHandle(const sp<ITransactionCompletedListener>& transactionListener,
225 const std::vector<CallbackId>& ids, const sp<IBinder>& sc)
226 : listener(transactionListener), callbackIds(ids), surfaceControl(sc) {}
227
228} // namespace android