1 /*
2  * Copyright 2016 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 #ifndef ANDROID_GUI_FRAMETIMESTAMPS_H
18 #define ANDROID_GUI_FRAMETIMESTAMPS_H
19 
20 #include <ui/FenceTime.h>
21 #include <utils/Flattenable.h>
22 #include <utils/StrongPointer.h>
23 #include <utils/Timers.h>
24 
25 #include <array>
26 #include <bitset>
27 #include <vector>
28 
29 namespace android {
30 
31 struct FrameEvents;
32 class FrameEventHistoryDelta;
33 class String8;
34 
35 
36 // Identifiers for all the events that may be recorded or reported.
37 enum class FrameEvent {
38     POSTED,
39     REQUESTED_PRESENT,
40     LATCH,
41     ACQUIRE,
42     FIRST_REFRESH_START,
43     LAST_REFRESH_START,
44     GPU_COMPOSITION_DONE,
45     DISPLAY_PRESENT,
46     DEQUEUE_READY,
47     RELEASE,
48     EVENT_COUNT, // Not an actual event.
49 };
50 
51 
52 // A collection of timestamps corresponding to a single frame.
53 struct FrameEvents {
54     static constexpr auto EVENT_COUNT =
55             static_cast<size_t>(FrameEvent::EVENT_COUNT);
56     static_assert(EVENT_COUNT <= 32, "Event count sanity check failed.");
57     static constexpr nsecs_t TIMESTAMP_PENDING = -2;
58 
isValidTimestampFrameEvents59     static inline bool isValidTimestamp(nsecs_t time) {
60         return time != TIMESTAMP_PENDING;
61     }
62 
63     bool hasPostedInfo() const;
64     bool hasRequestedPresentInfo() const;
65     bool hasLatchInfo() const;
66     bool hasFirstRefreshStartInfo() const;
67     bool hasLastRefreshStartInfo() const;
68     bool hasAcquireInfo() const;
69     bool hasGpuCompositionDoneInfo() const;
70     bool hasDisplayPresentInfo() const;
71     bool hasReleaseInfo() const;
72     bool hasDequeueReadyInfo() const;
73 
74     void checkFencesForCompletion();
75     void dump(String8& outString) const;
76 
77     bool valid{false};
78     int connectId{0};
79     uint64_t frameNumber{0};
80 
81     // Whether or not certain points in the frame's life cycle have been
82     // encountered help us determine if timestamps aren't available because
83     // a) we'll just never get them or b) they're not ready yet.
84     bool addPostCompositeCalled{false};
85     bool addReleaseCalled{false};
86 
87     nsecs_t postedTime{TIMESTAMP_PENDING};
88     nsecs_t requestedPresentTime{TIMESTAMP_PENDING};
89     nsecs_t latchTime{TIMESTAMP_PENDING};
90     nsecs_t firstRefreshStartTime{TIMESTAMP_PENDING};
91     nsecs_t lastRefreshStartTime{TIMESTAMP_PENDING};
92     nsecs_t dequeueReadyTime{TIMESTAMP_PENDING};
93 
94     std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE};
95     std::shared_ptr<FenceTime> gpuCompositionDoneFence{FenceTime::NO_FENCE};
96     std::shared_ptr<FenceTime> displayPresentFence{FenceTime::NO_FENCE};
97     std::shared_ptr<FenceTime> releaseFence{FenceTime::NO_FENCE};
98 };
99 
100 struct CompositorTiming {
101     nsecs_t deadline{0};
102     nsecs_t interval{16666667};
103     nsecs_t presentLatency{16666667};
104 };
105 
106 // A short history of frames that are synchronized between the consumer and
107 // producer via deltas.
108 class FrameEventHistory {
109 public:
110     virtual ~FrameEventHistory();
111 
112     FrameEvents* getFrame(uint64_t frameNumber);
113     FrameEvents* getFrame(uint64_t frameNumber, size_t* iHint);
114     void checkFencesForCompletion();
115     void dump(String8& outString) const;
116 
117     static constexpr size_t MAX_FRAME_HISTORY = 8;
118 
119 protected:
120     std::array<FrameEvents, MAX_FRAME_HISTORY> mFrames;
121 
122     CompositorTiming mCompositorTiming;
123 };
124 
125 
126 // The producer's interface to FrameEventHistory
127 class ProducerFrameEventHistory : public FrameEventHistory {
128 public:
129     ~ProducerFrameEventHistory() override;
130 
131     // Public for testing.
132     static nsecs_t snapToNextTick(
133             nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval);
134 
135     nsecs_t getNextCompositeDeadline(const nsecs_t now) const;
getCompositeInterval()136     nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; }
getCompositeToPresentLatency()137     nsecs_t getCompositeToPresentLatency() const {
138         return mCompositorTiming.presentLatency;
139     }
140 
141     // virtual for testing.
142     virtual void updateAcquireFence(
143             uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire);
144     void applyDelta(const FrameEventHistoryDelta& delta);
145 
146     void updateSignalTimes();
147 
148 protected:
149     void applyFenceDelta(FenceTimeline* timeline,
150             std::shared_ptr<FenceTime>* dst,
151             const FenceTime::Snapshot& src) const;
152 
153     // virtual for testing.
154     virtual std::shared_ptr<FenceTime> createFenceTime(
155             const sp<Fence>& fence) const;
156 
157     size_t mAcquireOffset{0};
158 
159     // The consumer updates it's timelines in Layer and SurfaceFlinger since
160     // they can coordinate shared timelines better. The producer doesn't have
161     // shared timelines though, so just let it own and update all of them.
162     FenceTimeline mAcquireTimeline;
163     FenceTimeline mGpuCompositionDoneTimeline;
164     FenceTimeline mPresentTimeline;
165     FenceTimeline mReleaseTimeline;
166 };
167 
168 
169 // Used by the consumer to create a new frame event record that is
170 // partially complete.
171 struct NewFrameEventsEntry {
172     uint64_t frameNumber{0};
173     nsecs_t postedTime{0};
174     nsecs_t requestedPresentTime{0};
175     std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE};
176 };
177 
178 
179 // Used by the consumer to keep track of which fields it already sent to
180 // the producer.
181 class FrameEventDirtyFields {
182 public:
reset()183     inline void reset() { mBitset.reset(); }
anyDirty()184     inline bool anyDirty() const { return mBitset.any(); }
185 
186     template <FrameEvent event>
setDirty()187     inline void setDirty() {
188         constexpr size_t eventIndex = static_cast<size_t>(event);
189         static_assert(eventIndex < FrameEvents::EVENT_COUNT, "Bad index.");
190         mBitset.set(eventIndex);
191     }
192 
193     template <FrameEvent event>
isDirty()194     inline bool isDirty() const {
195         constexpr size_t eventIndex = static_cast<size_t>(event);
196         static_assert(eventIndex < FrameEvents::EVENT_COUNT, "Bad index.");
197         return mBitset[eventIndex];
198     }
199 
200 private:
201     std::bitset<FrameEvents::EVENT_COUNT> mBitset;
202 };
203 
204 
205 // The consumer's interface to FrameEventHistory
206 class ConsumerFrameEventHistory : public FrameEventHistory {
207 public:
208     ~ConsumerFrameEventHistory() override;
209 
210     void onDisconnect();
211 
212     void initializeCompositorTiming(const CompositorTiming& compositorTiming);
213 
214     void addQueue(const NewFrameEventsEntry& newEntry);
215     void addLatch(uint64_t frameNumber, nsecs_t latchTime);
216     void addPreComposition(uint64_t frameNumber, nsecs_t refreshStartTime);
217     void addPostComposition(uint64_t frameNumber,
218             const std::shared_ptr<FenceTime>& gpuCompositionDone,
219             const std::shared_ptr<FenceTime>& displayPresent,
220             const CompositorTiming& compositorTiming);
221     void addRelease(uint64_t frameNumber, nsecs_t dequeueReadyTime,
222             std::shared_ptr<FenceTime>&& release);
223 
224     void getAndResetDelta(FrameEventHistoryDelta* delta);
225 
226 private:
227     void getFrameDelta(FrameEventHistoryDelta* delta,
228             const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame);
229 
230     std::array<FrameEventDirtyFields, MAX_FRAME_HISTORY> mFramesDirty;
231 
232     size_t mQueueOffset{0};
233     size_t mCompositionOffset{0};
234     size_t mReleaseOffset{0};
235 
236     int mCurrentConnectId{0};
237     bool mProducerWantsEvents{false};
238 };
239 
240 
241 // A single frame update from the consumer to producer that can be sent
242 // through Binder.
243 // Although this may be sent multiple times for the same frame as new
244 // timestamps are set, Fences only need to be sent once.
245 class FrameEventsDelta : public Flattenable<FrameEventsDelta> {
246 friend class ProducerFrameEventHistory;
247 public:
248     FrameEventsDelta() = default;
249     FrameEventsDelta(size_t index,
250             const FrameEvents& frameTimestamps,
251             const FrameEventDirtyFields& dirtyFields);
252 
253     // Movable.
254     FrameEventsDelta(FrameEventsDelta&& src) = default;
255     FrameEventsDelta& operator=(FrameEventsDelta&& src) = default;
256     // Not copyable.
257     FrameEventsDelta(const FrameEventsDelta& src) = delete;
258     FrameEventsDelta& operator=(const FrameEventsDelta& src) = delete;
259 
260     // Flattenable implementation
261     size_t getFlattenedSize() const;
262     size_t getFdCount() const;
263     status_t flatten(void*& buffer, size_t& size, int*& fds,
264             size_t& count) const;
265     status_t unflatten(void const*& buffer, size_t& size, int const*& fds,
266             size_t& count);
267 
268 private:
269     static constexpr size_t minFlattenedSize();
270 
271     size_t mIndex{0};
272     uint64_t mFrameNumber{0};
273 
274     bool mAddPostCompositeCalled{0};
275     bool mAddReleaseCalled{0};
276 
277     nsecs_t mPostedTime{FrameEvents::TIMESTAMP_PENDING};
278     nsecs_t mRequestedPresentTime{FrameEvents::TIMESTAMP_PENDING};
279     nsecs_t mLatchTime{FrameEvents::TIMESTAMP_PENDING};
280     nsecs_t mFirstRefreshStartTime{FrameEvents::TIMESTAMP_PENDING};
281     nsecs_t mLastRefreshStartTime{FrameEvents::TIMESTAMP_PENDING};
282     nsecs_t mDequeueReadyTime{FrameEvents::TIMESTAMP_PENDING};
283 
284     FenceTime::Snapshot mGpuCompositionDoneFence;
285     FenceTime::Snapshot mDisplayPresentFence;
286     FenceTime::Snapshot mReleaseFence;
287 
288     // This is a static method with an auto return value so we can call
289     // it without needing const and non-const versions.
290     template <typename ThisT>
291     static inline auto allFences(ThisT fed) ->
292             std::array<decltype(&fed->mReleaseFence), 3> {
293         return {{
294             &fed->mGpuCompositionDoneFence, &fed->mDisplayPresentFence,
295             &fed->mReleaseFence
296         }};
297     }
298 };
299 
300 
301 // A collection of updates from consumer to producer that can be sent
302 // through Binder.
303 class FrameEventHistoryDelta
304         : public Flattenable<FrameEventHistoryDelta> {
305 
306 friend class ConsumerFrameEventHistory;
307 friend class ProducerFrameEventHistory;
308 
309 public:
310     FrameEventHistoryDelta() = default;
311 
312     // Movable.
313     FrameEventHistoryDelta(FrameEventHistoryDelta&& src) = default;
314     FrameEventHistoryDelta& operator=(FrameEventHistoryDelta&& src);
315     // Not copyable.
316     FrameEventHistoryDelta(const FrameEventHistoryDelta& src) = delete;
317     FrameEventHistoryDelta& operator=(
318             const FrameEventHistoryDelta& src) = delete;
319 
320     // Flattenable implementation.
321     size_t getFlattenedSize() const;
322     size_t getFdCount() const;
323     status_t flatten(void*& buffer, size_t& size, int*& fds,
324             size_t& count) const;
325     status_t unflatten(void const*& buffer, size_t& size, int const*& fds,
326             size_t& count);
327 
328 private:
329     static constexpr size_t minFlattenedSize();
330 
331     std::vector<FrameEventsDelta> mDeltas;
332     CompositorTiming mCompositorTiming;
333 };
334 
335 
336 } // namespace android
337 #endif
338