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 
32 namespace android {
33 
34 class ITransactionCompletedListener;
35 class ListenerCallbacks;
36 
37 using CallbackId = int64_t;
38 
39 class FrameEventHistoryStats : public Parcelable {
40 public:
41     status_t writeToParcel(Parcel* output) const override;
42     status_t readFromParcel(const Parcel* input) override;
43 
44     FrameEventHistoryStats() = default;
FrameEventHistoryStats(uint64_t fn,const sp<Fence> & gpuCompFence,CompositorTiming compTiming,nsecs_t refreshTime,nsecs_t dequeueReadyTime)45     FrameEventHistoryStats(uint64_t fn, const sp<Fence>& gpuCompFence, CompositorTiming compTiming,
46                            nsecs_t refreshTime, nsecs_t dequeueReadyTime)
47           : frameNumber(fn),
48             gpuCompositionDoneFence(gpuCompFence),
49             compositorTiming(compTiming),
50             refreshStartTime(refreshTime),
51             dequeueReadyTime(dequeueReadyTime) {}
52 
53     uint64_t frameNumber;
54     sp<Fence> gpuCompositionDoneFence;
55     CompositorTiming compositorTiming;
56     nsecs_t refreshStartTime;
57     nsecs_t dequeueReadyTime;
58 };
59 
60 class SurfaceStats : public Parcelable {
61 public:
62     status_t writeToParcel(Parcel* output) const override;
63     status_t readFromParcel(const Parcel* input) override;
64 
65     SurfaceStats() = default;
SurfaceStats(const sp<IBinder> & sc,nsecs_t time,const sp<Fence> & prevReleaseFence,uint32_t hint,FrameEventHistoryStats frameEventStats)66     SurfaceStats(const sp<IBinder>& sc, nsecs_t time, const sp<Fence>& prevReleaseFence,
67                  uint32_t hint, FrameEventHistoryStats frameEventStats)
68           : surfaceControl(sc),
69             acquireTime(time),
70             previousReleaseFence(prevReleaseFence),
71             transformHint(hint),
72             eventStats(frameEventStats) {}
73 
74     sp<IBinder> surfaceControl;
75     nsecs_t acquireTime = -1;
76     sp<Fence> previousReleaseFence;
77     uint32_t transformHint = 0;
78     FrameEventHistoryStats eventStats;
79 };
80 
81 class TransactionStats : public Parcelable {
82 public:
83     status_t writeToParcel(Parcel* output) const override;
84     status_t readFromParcel(const Parcel* input) override;
85 
86     TransactionStats() = default;
TransactionStats(const std::vector<CallbackId> & ids)87     TransactionStats(const std::vector<CallbackId>& ids) : callbackIds(ids) {}
TransactionStats(const std::unordered_set<CallbackId> & ids)88     TransactionStats(const std::unordered_set<CallbackId>& ids)
89           : callbackIds(ids.begin(), ids.end()) {}
TransactionStats(const std::vector<CallbackId> & ids,nsecs_t latch,const sp<Fence> & present,const std::vector<SurfaceStats> & surfaces)90     TransactionStats(const std::vector<CallbackId>& ids, nsecs_t latch, const sp<Fence>& present,
91                      const std::vector<SurfaceStats>& surfaces)
92           : callbackIds(ids), latchTime(latch), presentFence(present), surfaceStats(surfaces) {}
93 
94     std::vector<CallbackId> callbackIds;
95     nsecs_t latchTime = -1;
96     sp<Fence> presentFence = nullptr;
97     std::vector<SurfaceStats> surfaceStats;
98 };
99 
100 class ListenerStats : public Parcelable {
101 public:
102     status_t writeToParcel(Parcel* output) const override;
103     status_t readFromParcel(const Parcel* input) override;
104 
105     static ListenerStats createEmpty(const sp<IBinder>& listener,
106                                      const std::unordered_set<CallbackId>& callbackIds);
107 
108     sp<IBinder> listener;
109     std::vector<TransactionStats> transactionStats;
110 };
111 
112 class ITransactionCompletedListener : public IInterface {
113 public:
114     DECLARE_META_INTERFACE(TransactionCompletedListener)
115 
116     virtual void onTransactionCompleted(ListenerStats stats) = 0;
117 };
118 
119 class BnTransactionCompletedListener : public SafeBnInterface<ITransactionCompletedListener> {
120 public:
BnTransactionCompletedListener()121     BnTransactionCompletedListener()
122           : SafeBnInterface<ITransactionCompletedListener>("BnTransactionCompletedListener") {}
123 
124     status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
125                         uint32_t flags = 0) override;
126 };
127 
128 class ListenerCallbacks {
129 public:
ListenerCallbacks(const sp<IBinder> & listener,const std::unordered_set<CallbackId> & callbacks)130     ListenerCallbacks(const sp<IBinder>& listener, const std::unordered_set<CallbackId>& callbacks)
131           : transactionCompletedListener(listener),
132             callbackIds(callbacks.begin(), callbacks.end()) {}
133 
ListenerCallbacks(const sp<IBinder> & listener,const std::vector<CallbackId> & ids)134     ListenerCallbacks(const sp<IBinder>& listener, const std::vector<CallbackId>& ids)
135           : transactionCompletedListener(listener), callbackIds(ids) {}
136 
137     bool operator==(const ListenerCallbacks& rhs) const {
138         if (transactionCompletedListener != rhs.transactionCompletedListener) {
139             return false;
140         }
141         if (callbackIds.empty()) {
142             return rhs.callbackIds.empty();
143         }
144         return callbackIds.front() == rhs.callbackIds.front();
145     }
146 
147     sp<IBinder> transactionCompletedListener;
148     std::vector<CallbackId> callbackIds;
149 };
150 
151 struct IListenerHash {
operatorIListenerHash152     std::size_t operator()(const sp<IBinder>& strongPointer) const {
153         return std::hash<IBinder*>{}(strongPointer.get());
154     }
155 };
156 
157 struct CallbackIdsHash {
158     // CallbackId vectors have several properties that let us get away with this simple hash.
159     // 1) CallbackIds are never 0 so if something has gone wrong and our CallbackId vector is
160     // empty we can still hash 0.
161     // 2) CallbackId vectors for the same listener either are identical or contain none of the
162     // same members. It is sufficient to just check the first CallbackId in the vectors. If
163     // they match, they are the same. If they do not match, they are not the same.
operatorCallbackIdsHash164     std::size_t operator()(const std::vector<CallbackId>& callbackIds) const {
165         return std::hash<CallbackId>{}((callbackIds.empty()) ? 0 : callbackIds.front());
166     }
167 };
168 
169 struct ListenerCallbacksHash {
HashCombineListenerCallbacksHash170     std::size_t HashCombine(size_t value1, size_t value2) const {
171         return value1 ^ (value2 + 0x9e3779b9 + (value1 << 6) + (value1 >> 2));
172     }
173 
operatorListenerCallbacksHash174     std::size_t operator()(const ListenerCallbacks& listenerCallbacks) const {
175         struct IListenerHash listenerHasher;
176         struct CallbackIdsHash callbackIdsHasher;
177 
178         std::size_t listenerHash = listenerHasher(listenerCallbacks.transactionCompletedListener);
179         std::size_t callbackIdsHash = callbackIdsHasher(listenerCallbacks.callbackIds);
180 
181         return HashCombine(listenerHash, callbackIdsHash);
182     }
183 };
184 
185 } // namespace android
186