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