1 /* 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 #pragma once 18 19 #include <condition_variable> 20 #include <deque> 21 #include <mutex> 22 #include <thread> 23 #include <unordered_map> 24 25 #include <android-base/thread_annotations.h> 26 27 #include <binder/IBinder.h> 28 #include <gui/ITransactionCompletedListener.h> 29 #include <ui/Fence.h> 30 31 namespace android { 32 33 struct CallbackIdsHash { 34 // CallbackId vectors have several properties that let us get away with this simple hash. 35 // 1) CallbackIds are never 0 so if something has gone wrong and our CallbackId vector is 36 // empty we can still hash 0. 37 // 2) CallbackId vectors for the same listener either are identical or contain none of the 38 // same members. It is sufficient to just check the first CallbackId in the vectors. If 39 // they match, they are the same. If they do not match, they are not the same. operatorCallbackIdsHash40 std::size_t operator()(const std::vector<CallbackId>& callbackIds) const { 41 return std::hash<CallbackId>{}((callbackIds.empty()) ? 0 : callbackIds.front()); 42 } 43 }; 44 45 class CallbackHandle : public RefBase { 46 public: 47 CallbackHandle(const sp<ITransactionCompletedListener>& transactionListener, 48 const std::vector<CallbackId>& ids, const sp<IBinder>& sc); 49 50 sp<ITransactionCompletedListener> listener; 51 std::vector<CallbackId> callbackIds; 52 wp<IBinder> surfaceControl; 53 54 bool releasePreviousBuffer = false; 55 sp<Fence> previousReleaseFence; 56 nsecs_t acquireTime = -1; 57 nsecs_t latchTime = -1; 58 }; 59 60 class TransactionCompletedThread { 61 public: 62 ~TransactionCompletedThread(); 63 64 void run(); 65 66 // Adds listener and callbackIds in case there are no SurfaceControls that are supposed 67 // to be included in the callback. This functions should be call before attempting to add any 68 // callback handles. 69 status_t addCallback(const sp<ITransactionCompletedListener>& transactionListener, 70 const std::vector<CallbackId>& callbackIds); 71 72 // Informs the TransactionCompletedThread that there is a Transaction with a CallbackHandle 73 // that needs to be latched and presented this frame. This function should be called once the 74 // layer has received the CallbackHandle so the TransactionCompletedThread knows not to send 75 // a callback for that Listener/Transaction pair until that CallbackHandle has been latched and 76 // presented. 77 status_t registerPendingCallbackHandle(const sp<CallbackHandle>& handle); 78 // Notifies the TransactionCompletedThread that a pending CallbackHandle has been presented. 79 status_t addPresentedCallbackHandles(const std::deque<sp<CallbackHandle>>& handles); 80 81 // Adds the Transaction CallbackHandle from a layer that does not need to be relatched and 82 // presented this frame. 83 status_t addUnpresentedCallbackHandle(const sp<CallbackHandle>& handle); 84 85 void addPresentFence(const sp<Fence>& presentFence); 86 87 void sendCallbacks(); 88 89 private: 90 void threadMain(); 91 92 status_t findTransactionStats(const sp<ITransactionCompletedListener>& listener, 93 const std::vector<CallbackId>& callbackIds, 94 TransactionStats** outTransactionStats) REQUIRES(mMutex); 95 96 status_t addCallbackHandle(const sp<CallbackHandle>& handle) REQUIRES(mMutex); 97 98 class ThreadDeathRecipient : public IBinder::DeathRecipient { 99 public: 100 // This function is a no-op. isBinderAlive needs a linked DeathRecipient to work. 101 // Death recipients needs a binderDied function. 102 // 103 // (isBinderAlive checks if BpBinder's mAlive is 0. mAlive is only set to 0 in sendObituary. 104 // sendObituary is only called if linkToDeath was called with a DeathRecipient.) binderDied(const wp<IBinder> &)105 void binderDied(const wp<IBinder>& /*who*/) override {} 106 }; 107 sp<ThreadDeathRecipient> mDeathRecipient; 108 109 struct ITransactionCompletedListenerHash { operatorITransactionCompletedListenerHash110 std::size_t operator()(const sp<ITransactionCompletedListener>& listener) const { 111 return std::hash<IBinder*>{}((listener) ? IInterface::asBinder(listener).get() 112 : nullptr); 113 } 114 }; 115 116 // Protects the creation and destruction of mThread 117 std::mutex mThreadMutex; 118 119 std::thread mThread GUARDED_BY(mThreadMutex); 120 121 std::mutex mMutex; 122 std::condition_variable_any mConditionVariable; 123 124 std::unordered_map< 125 sp<ITransactionCompletedListener>, 126 std::unordered_map<std::vector<CallbackId>, uint32_t /*count*/, CallbackIdsHash>, 127 ITransactionCompletedListenerHash> 128 mPendingTransactions GUARDED_BY(mMutex); 129 std::unordered_map<sp<ITransactionCompletedListener>, std::deque<TransactionStats>, 130 ITransactionCompletedListenerHash> 131 mCompletedTransactions GUARDED_BY(mMutex); 132 133 bool mRunning GUARDED_BY(mMutex) = false; 134 bool mKeepRunning GUARDED_BY(mMutex) = true; 135 136 sp<Fence> mPresentFence GUARDED_BY(mMutex); 137 }; 138 139 } // namespace android 140