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