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 "JankInfo.h" 20 21 #include <binder/IInterface.h> 22 #include <binder/Parcel.h> 23 #include <binder/Parcelable.h> 24 #include <binder/SafeInterface.h> 25 26 #include <gui/FrameTimestamps.h> 27 #include <ui/Fence.h> 28 #include <utils/Timers.h> 29 30 #include <cstdint> 31 #include <unordered_map> 32 #include <unordered_set> 33 #include <variant> 34 35 namespace android { 36 37 class ITransactionCompletedListener; 38 class ListenerCallbacks; 39 40 class CallbackId : public Parcelable { 41 public: 42 int64_t id; 43 enum class Type : int32_t { ON_COMPLETE, ON_COMMIT } type; 44 CallbackId()45 CallbackId() {} CallbackId(int64_t id,Type type)46 CallbackId(int64_t id, Type type) : id(id), type(type) {} 47 status_t writeToParcel(Parcel* output) const override; 48 status_t readFromParcel(const Parcel* input) override; 49 50 bool operator==(const CallbackId& rhs) const { return id == rhs.id && type == rhs.type; } 51 }; 52 53 struct CallbackIdHash { operatorCallbackIdHash54 std::size_t operator()(const CallbackId& key) const { return std::hash<int64_t>()(key.id); } 55 }; 56 57 class ReleaseCallbackId : public Parcelable { 58 public: 59 static const ReleaseCallbackId INVALID_ID; 60 61 uint64_t bufferId; 62 uint64_t framenumber; ReleaseCallbackId()63 ReleaseCallbackId() {} ReleaseCallbackId(uint64_t bufferId,uint64_t framenumber)64 ReleaseCallbackId(uint64_t bufferId, uint64_t framenumber) 65 : bufferId(bufferId), framenumber(framenumber) {} 66 status_t writeToParcel(Parcel* output) const override; 67 status_t readFromParcel(const Parcel* input) override; 68 69 bool operator==(const ReleaseCallbackId& rhs) const { 70 return bufferId == rhs.bufferId && framenumber == rhs.framenumber; 71 } 72 bool operator!=(const ReleaseCallbackId& rhs) const { return !operator==(rhs); } to_string()73 std::string to_string() const { 74 if (*this == INVALID_ID) return "INVALID_ID"; 75 76 return "bufferId:" + std::to_string(bufferId) + 77 " framenumber:" + std::to_string(framenumber); 78 } 79 }; 80 81 struct ReleaseBufferCallbackIdHash { operatorReleaseBufferCallbackIdHash82 std::size_t operator()(const ReleaseCallbackId& key) const { 83 return std::hash<uint64_t>()(key.bufferId); 84 } 85 }; 86 87 class FrameEventHistoryStats : public Parcelable { 88 public: 89 status_t writeToParcel(Parcel* output) const override; 90 status_t readFromParcel(const Parcel* input) override; 91 92 FrameEventHistoryStats() = default; FrameEventHistoryStats(uint64_t fn,const sp<Fence> & gpuCompFence,CompositorTiming compTiming,nsecs_t refreshTime,nsecs_t dequeueReadyTime)93 FrameEventHistoryStats(uint64_t fn, const sp<Fence>& gpuCompFence, CompositorTiming compTiming, 94 nsecs_t refreshTime, nsecs_t dequeueReadyTime) 95 : frameNumber(fn), 96 gpuCompositionDoneFence(gpuCompFence), 97 compositorTiming(compTiming), 98 refreshStartTime(refreshTime), 99 dequeueReadyTime(dequeueReadyTime) {} 100 101 uint64_t frameNumber; 102 sp<Fence> gpuCompositionDoneFence; 103 CompositorTiming compositorTiming; 104 nsecs_t refreshStartTime; 105 nsecs_t dequeueReadyTime; 106 }; 107 108 /** 109 * Jank information representing SurfaceFlinger's jank classification about frames for a specific 110 * surface. 111 */ 112 class JankData : public Parcelable { 113 public: 114 status_t writeToParcel(Parcel* output) const override; 115 status_t readFromParcel(const Parcel* input) override; 116 117 JankData(); JankData(int64_t frameVsyncId,int32_t jankType)118 JankData(int64_t frameVsyncId, int32_t jankType) 119 : frameVsyncId(frameVsyncId), jankType(jankType) {} 120 121 // Identifier for the frame submitted with Transaction.setFrameTimelineVsyncId 122 int64_t frameVsyncId; 123 124 // Bitmask of janks that occurred 125 int32_t jankType; 126 }; 127 128 class SurfaceStats : public Parcelable { 129 public: 130 status_t writeToParcel(Parcel* output) const override; 131 status_t readFromParcel(const Parcel* input) override; 132 133 SurfaceStats() = default; SurfaceStats(const sp<IBinder> & sc,std::variant<nsecs_t,sp<Fence>> acquireTimeOrFence,const sp<Fence> & prevReleaseFence,uint32_t hint,uint32_t currentMaxAcquiredBuffersCount,FrameEventHistoryStats frameEventStats,std::vector<JankData> jankData,ReleaseCallbackId previousReleaseCallbackId)134 SurfaceStats(const sp<IBinder>& sc, std::variant<nsecs_t, sp<Fence>> acquireTimeOrFence, 135 const sp<Fence>& prevReleaseFence, uint32_t hint, 136 uint32_t currentMaxAcquiredBuffersCount, FrameEventHistoryStats frameEventStats, 137 std::vector<JankData> jankData, ReleaseCallbackId previousReleaseCallbackId) 138 : surfaceControl(sc), 139 acquireTimeOrFence(std::move(acquireTimeOrFence)), 140 previousReleaseFence(prevReleaseFence), 141 transformHint(hint), 142 currentMaxAcquiredBufferCount(currentMaxAcquiredBuffersCount), 143 eventStats(frameEventStats), 144 jankData(std::move(jankData)), 145 previousReleaseCallbackId(previousReleaseCallbackId) {} 146 147 sp<IBinder> surfaceControl; 148 std::variant<nsecs_t, sp<Fence>> acquireTimeOrFence = -1; 149 sp<Fence> previousReleaseFence; 150 uint32_t transformHint = 0; 151 uint32_t currentMaxAcquiredBufferCount = 0; 152 FrameEventHistoryStats eventStats; 153 std::vector<JankData> jankData; 154 ReleaseCallbackId previousReleaseCallbackId; 155 }; 156 157 class TransactionStats : public Parcelable { 158 public: 159 status_t writeToParcel(Parcel* output) const override; 160 status_t readFromParcel(const Parcel* input) override; 161 162 TransactionStats() = default; TransactionStats(const std::vector<CallbackId> & ids)163 TransactionStats(const std::vector<CallbackId>& ids) : callbackIds(ids) {} TransactionStats(const std::unordered_set<CallbackId,CallbackIdHash> & ids)164 TransactionStats(const std::unordered_set<CallbackId, CallbackIdHash>& ids) 165 : callbackIds(ids.begin(), ids.end()) {} TransactionStats(const std::vector<CallbackId> & ids,nsecs_t latch,const sp<Fence> & present,const std::vector<SurfaceStats> & surfaces)166 TransactionStats(const std::vector<CallbackId>& ids, nsecs_t latch, const sp<Fence>& present, 167 const std::vector<SurfaceStats>& surfaces) 168 : callbackIds(ids), latchTime(latch), presentFence(present), surfaceStats(surfaces) {} 169 170 std::vector<CallbackId> callbackIds; 171 nsecs_t latchTime = -1; 172 sp<Fence> presentFence = nullptr; 173 std::vector<SurfaceStats> surfaceStats; 174 }; 175 176 class ListenerStats : public Parcelable { 177 public: 178 status_t writeToParcel(Parcel* output) const override; 179 status_t readFromParcel(const Parcel* input) override; 180 181 static ListenerStats createEmpty( 182 const sp<IBinder>& listener, 183 const std::unordered_set<CallbackId, CallbackIdHash>& callbackIds); 184 185 sp<IBinder> listener; 186 std::vector<TransactionStats> transactionStats; 187 }; 188 189 class ITransactionCompletedListener : public IInterface { 190 public: 191 DECLARE_META_INTERFACE(TransactionCompletedListener) 192 193 virtual void onTransactionCompleted(ListenerStats stats) = 0; 194 195 virtual void onReleaseBuffer(ReleaseCallbackId callbackId, sp<Fence> releaseFence, 196 uint32_t currentMaxAcquiredBufferCount) = 0; 197 virtual void onTransactionQueueStalled() = 0; 198 }; 199 200 class BnTransactionCompletedListener : public SafeBnInterface<ITransactionCompletedListener> { 201 public: BnTransactionCompletedListener()202 BnTransactionCompletedListener() 203 : SafeBnInterface<ITransactionCompletedListener>("BnTransactionCompletedListener") {} 204 205 status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, 206 uint32_t flags = 0) override; 207 }; 208 209 class ListenerCallbacks { 210 public: ListenerCallbacks(const sp<IBinder> & listener,const std::unordered_set<CallbackId,CallbackIdHash> & callbacks)211 ListenerCallbacks(const sp<IBinder>& listener, 212 const std::unordered_set<CallbackId, CallbackIdHash>& callbacks) 213 : transactionCompletedListener(listener), 214 callbackIds(callbacks.begin(), callbacks.end()) {} 215 ListenerCallbacks(const sp<IBinder> & listener,const std::vector<CallbackId> & ids)216 ListenerCallbacks(const sp<IBinder>& listener, const std::vector<CallbackId>& ids) 217 : transactionCompletedListener(listener), callbackIds(ids) {} 218 219 bool operator==(const ListenerCallbacks& rhs) const { 220 if (transactionCompletedListener != rhs.transactionCompletedListener) { 221 return false; 222 } 223 if (callbackIds.empty()) { 224 return rhs.callbackIds.empty(); 225 } 226 return callbackIds.front().id == rhs.callbackIds.front().id; 227 } 228 229 // Returns a new ListenerCallbacks filtered by type 230 ListenerCallbacks filter(CallbackId::Type type) const; 231 232 sp<IBinder> transactionCompletedListener; 233 std::vector<CallbackId> callbackIds; 234 }; 235 236 struct IListenerHash { operatorIListenerHash237 std::size_t operator()(const sp<IBinder>& strongPointer) const { 238 return std::hash<IBinder*>{}(strongPointer.get()); 239 } 240 }; 241 242 struct CallbackIdsHash { 243 // CallbackId vectors have several properties that let us get away with this simple hash. 244 // 1) CallbackIds are never 0 so if something has gone wrong and our CallbackId vector is 245 // empty we can still hash 0. 246 // 2) CallbackId vectors for the same listener either are identical or contain none of the 247 // same members. It is sufficient to just check the first CallbackId in the vectors. If 248 // they match, they are the same. If they do not match, they are not the same. operatorCallbackIdsHash249 std::size_t operator()(const std::vector<CallbackId>& callbackIds) const { 250 return std::hash<int64_t>{}((callbackIds.empty()) ? 0 : callbackIds.front().id); 251 } 252 }; 253 254 struct ListenerCallbacksHash { HashCombineListenerCallbacksHash255 std::size_t HashCombine(size_t value1, size_t value2) const { 256 return value1 ^ (value2 + 0x9e3779b9 + (value1 << 6) + (value1 >> 2)); 257 } 258 operatorListenerCallbacksHash259 std::size_t operator()(const ListenerCallbacks& listenerCallbacks) const { 260 struct IListenerHash listenerHasher; 261 struct CallbackIdsHash callbackIdsHasher; 262 263 std::size_t listenerHash = listenerHasher(listenerCallbacks.transactionCompletedListener); 264 std::size_t callbackIdsHash = callbackIdsHasher(listenerCallbacks.callbackIds); 265 266 return HashCombine(listenerHash, callbackIdsHash); 267 } 268 }; 269 270 } // namespace android 271