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