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 <binder/IInterface.h> 20 #include <binder/Parcel.h> 21 #include <binder/Parcelable.h> 22 #include <binder/SafeInterface.h> 23 24 #include <gui/FrameTimestamps.h> 25 #include <ui/Fence.h> 26 #include <utils/Timers.h> 27 28 #include <cstdint> 29 #include <unordered_map> 30 #include <unordered_set> 31 32 namespace android { 33 34 class ITransactionCompletedListener; 35 class ListenerCallbacks; 36 37 using CallbackId = int64_t; 38 39 class FrameEventHistoryStats : public Parcelable { 40 public: 41 status_t writeToParcel(Parcel* output) const override; 42 status_t readFromParcel(const Parcel* input) override; 43 44 FrameEventHistoryStats() = default; FrameEventHistoryStats(uint64_t fn,const sp<Fence> & gpuCompFence,CompositorTiming compTiming,nsecs_t refreshTime,nsecs_t dequeueReadyTime)45 FrameEventHistoryStats(uint64_t fn, const sp<Fence>& gpuCompFence, CompositorTiming compTiming, 46 nsecs_t refreshTime, nsecs_t dequeueReadyTime) 47 : frameNumber(fn), 48 gpuCompositionDoneFence(gpuCompFence), 49 compositorTiming(compTiming), 50 refreshStartTime(refreshTime), 51 dequeueReadyTime(dequeueReadyTime) {} 52 53 uint64_t frameNumber; 54 sp<Fence> gpuCompositionDoneFence; 55 CompositorTiming compositorTiming; 56 nsecs_t refreshStartTime; 57 nsecs_t dequeueReadyTime; 58 }; 59 60 class SurfaceStats : public Parcelable { 61 public: 62 status_t writeToParcel(Parcel* output) const override; 63 status_t readFromParcel(const Parcel* input) override; 64 65 SurfaceStats() = default; SurfaceStats(const sp<IBinder> & sc,nsecs_t time,const sp<Fence> & prevReleaseFence,uint32_t hint,FrameEventHistoryStats frameEventStats)66 SurfaceStats(const sp<IBinder>& sc, nsecs_t time, const sp<Fence>& prevReleaseFence, 67 uint32_t hint, FrameEventHistoryStats frameEventStats) 68 : surfaceControl(sc), 69 acquireTime(time), 70 previousReleaseFence(prevReleaseFence), 71 transformHint(hint), 72 eventStats(frameEventStats) {} 73 74 sp<IBinder> surfaceControl; 75 nsecs_t acquireTime = -1; 76 sp<Fence> previousReleaseFence; 77 uint32_t transformHint = 0; 78 FrameEventHistoryStats eventStats; 79 }; 80 81 class TransactionStats : public Parcelable { 82 public: 83 status_t writeToParcel(Parcel* output) const override; 84 status_t readFromParcel(const Parcel* input) override; 85 86 TransactionStats() = default; TransactionStats(const std::vector<CallbackId> & ids)87 TransactionStats(const std::vector<CallbackId>& ids) : callbackIds(ids) {} TransactionStats(const std::unordered_set<CallbackId> & ids)88 TransactionStats(const std::unordered_set<CallbackId>& ids) 89 : callbackIds(ids.begin(), ids.end()) {} TransactionStats(const std::vector<CallbackId> & ids,nsecs_t latch,const sp<Fence> & present,const std::vector<SurfaceStats> & surfaces)90 TransactionStats(const std::vector<CallbackId>& ids, nsecs_t latch, const sp<Fence>& present, 91 const std::vector<SurfaceStats>& surfaces) 92 : callbackIds(ids), latchTime(latch), presentFence(present), surfaceStats(surfaces) {} 93 94 std::vector<CallbackId> callbackIds; 95 nsecs_t latchTime = -1; 96 sp<Fence> presentFence = nullptr; 97 std::vector<SurfaceStats> surfaceStats; 98 }; 99 100 class ListenerStats : public Parcelable { 101 public: 102 status_t writeToParcel(Parcel* output) const override; 103 status_t readFromParcel(const Parcel* input) override; 104 105 static ListenerStats createEmpty(const sp<IBinder>& listener, 106 const std::unordered_set<CallbackId>& callbackIds); 107 108 sp<IBinder> listener; 109 std::vector<TransactionStats> transactionStats; 110 }; 111 112 class ITransactionCompletedListener : public IInterface { 113 public: 114 DECLARE_META_INTERFACE(TransactionCompletedListener) 115 116 virtual void onTransactionCompleted(ListenerStats stats) = 0; 117 }; 118 119 class BnTransactionCompletedListener : public SafeBnInterface<ITransactionCompletedListener> { 120 public: BnTransactionCompletedListener()121 BnTransactionCompletedListener() 122 : SafeBnInterface<ITransactionCompletedListener>("BnTransactionCompletedListener") {} 123 124 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, 125 uint32_t flags = 0) override; 126 }; 127 128 class ListenerCallbacks { 129 public: ListenerCallbacks(const sp<IBinder> & listener,const std::unordered_set<CallbackId> & callbacks)130 ListenerCallbacks(const sp<IBinder>& listener, const std::unordered_set<CallbackId>& callbacks) 131 : transactionCompletedListener(listener), 132 callbackIds(callbacks.begin(), callbacks.end()) {} 133 ListenerCallbacks(const sp<IBinder> & listener,const std::vector<CallbackId> & ids)134 ListenerCallbacks(const sp<IBinder>& listener, const std::vector<CallbackId>& ids) 135 : transactionCompletedListener(listener), callbackIds(ids) {} 136 137 bool operator==(const ListenerCallbacks& rhs) const { 138 if (transactionCompletedListener != rhs.transactionCompletedListener) { 139 return false; 140 } 141 if (callbackIds.empty()) { 142 return rhs.callbackIds.empty(); 143 } 144 return callbackIds.front() == rhs.callbackIds.front(); 145 } 146 147 sp<IBinder> transactionCompletedListener; 148 std::vector<CallbackId> callbackIds; 149 }; 150 151 struct IListenerHash { operatorIListenerHash152 std::size_t operator()(const sp<IBinder>& strongPointer) const { 153 return std::hash<IBinder*>{}(strongPointer.get()); 154 } 155 }; 156 157 struct CallbackIdsHash { 158 // CallbackId vectors have several properties that let us get away with this simple hash. 159 // 1) CallbackIds are never 0 so if something has gone wrong and our CallbackId vector is 160 // empty we can still hash 0. 161 // 2) CallbackId vectors for the same listener either are identical or contain none of the 162 // same members. It is sufficient to just check the first CallbackId in the vectors. If 163 // they match, they are the same. If they do not match, they are not the same. operatorCallbackIdsHash164 std::size_t operator()(const std::vector<CallbackId>& callbackIds) const { 165 return std::hash<CallbackId>{}((callbackIds.empty()) ? 0 : callbackIds.front()); 166 } 167 }; 168 169 struct ListenerCallbacksHash { HashCombineListenerCallbacksHash170 std::size_t HashCombine(size_t value1, size_t value2) const { 171 return value1 ^ (value2 + 0x9e3779b9 + (value1 << 6) + (value1 >> 2)); 172 } 173 operatorListenerCallbacksHash174 std::size_t operator()(const ListenerCallbacks& listenerCallbacks) const { 175 struct IListenerHash listenerHasher; 176 struct CallbackIdsHash callbackIdsHasher; 177 178 std::size_t listenerHash = listenerHasher(listenerCallbacks.transactionCompletedListener); 179 std::size_t callbackIdsHash = callbackIdsHasher(listenerCallbacks.callbackIds); 180 181 return HashCombine(listenerHash, callbackIdsHash); 182 } 183 }; 184 185 } // namespace android 186