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