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 
34 
35 // Identifiers for all the events that may be recorded or reported.
36 enum class FrameEvent {
37     POSTED,
38     REQUESTED_PRESENT,
39     LATCH,
40     ACQUIRE,
41     FIRST_REFRESH_START,
42     LAST_REFRESH_START,
43     GPU_COMPOSITION_DONE,
44     DISPLAY_PRESENT,
45     DEQUEUE_READY,
46     RELEASE,
47     EVENT_COUNT, // Not an actual event.
48 };
49 
50 
51 // A collection of timestamps corresponding to a single frame.
52 struct FrameEvents {
53     static constexpr auto EVENT_COUNT =
54             static_cast<size_t>(FrameEvent::EVENT_COUNT);
55     static_assert(EVENT_COUNT <= 32, "Event count sanity check failed.");
56     static constexpr nsecs_t TIMESTAMP_PENDING = -2;
57 
isValidTimestampFrameEvents58     static inline bool isValidTimestamp(nsecs_t time) {
59         return time != TIMESTAMP_PENDING;
60     }
61 
62     bool hasPostedInfo() const;
63     bool hasRequestedPresentInfo() const;
64     bool hasLatchInfo() const;
65     bool hasFirstRefreshStartInfo() const;
66     bool hasLastRefreshStartInfo() const;
67     bool hasAcquireInfo() const;
68     bool hasGpuCompositionDoneInfo() const;
69     bool hasDisplayPresentInfo() const;
70     bool hasReleaseInfo() const;
71     bool hasDequeueReadyInfo() const;
72 
73     void checkFencesForCompletion();
74     void dump(std::string& outString) const;
75 
76     bool valid{false};
77     int connectId{0};
78     uint64_t frameNumber{0};
79 
80     // Whether or not certain points in the frame's life cycle have been
81     // encountered help us determine if timestamps aren't available because
82     // a) we'll just never get them or b) they're not ready yet.
83     bool addPostCompositeCalled{false};
84     bool addReleaseCalled{false};
85 
86     nsecs_t postedTime{TIMESTAMP_PENDING};
87     nsecs_t requestedPresentTime{TIMESTAMP_PENDING};
88     nsecs_t latchTime{TIMESTAMP_PENDING};
89     nsecs_t firstRefreshStartTime{TIMESTAMP_PENDING};
90     nsecs_t lastRefreshStartTime{TIMESTAMP_PENDING};
91     nsecs_t dequeueReadyTime{TIMESTAMP_PENDING};
92 
93     std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE};
94     std::shared_ptr<FenceTime> gpuCompositionDoneFence{FenceTime::NO_FENCE};
95     std::shared_ptr<FenceTime> displayPresentFence{FenceTime::NO_FENCE};
96     std::shared_ptr<FenceTime> releaseFence{FenceTime::NO_FENCE};
97 };
98 
99 struct CompositorTiming {
100     nsecs_t deadline{0};
101     nsecs_t interval{16666667};
102     nsecs_t presentLatency{16666667};
103 };
104 
105 // A short history of frames that are synchronized between the consumer and
106 // producer via deltas.
107 class FrameEventHistory {
108 public:
109     FrameEventHistory();
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(std::string& outString) const;
116 
117     static const size_t MAX_FRAME_HISTORY;
118 
119 protected:
120     std::vector<FrameEvents> 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();
209     ~ConsumerFrameEventHistory() override;
210 
211     void onDisconnect();
212 
213     void initializeCompositorTiming(const CompositorTiming& compositorTiming);
214 
215     void addQueue(const NewFrameEventsEntry& newEntry);
216     void addLatch(uint64_t frameNumber, nsecs_t latchTime);
217     void addPreComposition(uint64_t frameNumber, nsecs_t refreshStartTime);
218     void addPostComposition(uint64_t frameNumber,
219             const std::shared_ptr<FenceTime>& gpuCompositionDone,
220             const std::shared_ptr<FenceTime>& displayPresent,
221             const CompositorTiming& compositorTiming);
222     void addRelease(uint64_t frameNumber, nsecs_t dequeueReadyTime,
223             std::shared_ptr<FenceTime>&& release);
224 
225     void getAndResetDelta(FrameEventHistoryDelta* delta);
226 
227 private:
228     void getFrameDelta(FrameEventHistoryDelta* delta,
229                        const std::vector<FrameEvents>::iterator& frame);
230 
231     std::vector<FrameEventDirtyFields> mFramesDirty;
232 
233     size_t mQueueOffset{0};
234     size_t mCompositionOffset{0};
235     size_t mReleaseOffset{0};
236 
237     int mCurrentConnectId{0};
238     bool mProducerWantsEvents{false};
239 };
240 
241 
242 // A single frame update from the consumer to producer that can be sent
243 // through Binder.
244 // Although this may be sent multiple times for the same frame as new
245 // timestamps are set, Fences only need to be sent once.
246 class FrameEventsDelta : public Flattenable<FrameEventsDelta> {
247 friend class ProducerFrameEventHistory;
248 public:
249     FrameEventsDelta() = default;
250     FrameEventsDelta(size_t index,
251             const FrameEvents& frameTimestamps,
252             const FrameEventDirtyFields& dirtyFields);
253 
254     // Movable.
255     FrameEventsDelta(FrameEventsDelta&& src) = default;
256     FrameEventsDelta& operator=(FrameEventsDelta&& src) = default;
257     // Not copyable.
258     FrameEventsDelta(const FrameEventsDelta& src) = delete;
259     FrameEventsDelta& operator=(const FrameEventsDelta& src) = delete;
260 
261     // Flattenable implementation
262     size_t getFlattenedSize() const;
263     size_t getFdCount() const;
264     status_t flatten(void*& buffer, size_t& size, int*& fds,
265             size_t& count) const;
266     status_t unflatten(void const*& buffer, size_t& size, int const*& fds,
267             size_t& count);
268 
269 private:
270     static constexpr size_t minFlattenedSize();
271 
272     size_t mIndex{0};
273     uint64_t mFrameNumber{0};
274 
275     bool mAddPostCompositeCalled{0};
276     bool mAddReleaseCalled{0};
277 
278     nsecs_t mPostedTime{FrameEvents::TIMESTAMP_PENDING};
279     nsecs_t mRequestedPresentTime{FrameEvents::TIMESTAMP_PENDING};
280     nsecs_t mLatchTime{FrameEvents::TIMESTAMP_PENDING};
281     nsecs_t mFirstRefreshStartTime{FrameEvents::TIMESTAMP_PENDING};
282     nsecs_t mLastRefreshStartTime{FrameEvents::TIMESTAMP_PENDING};
283     nsecs_t mDequeueReadyTime{FrameEvents::TIMESTAMP_PENDING};
284 
285     FenceTime::Snapshot mGpuCompositionDoneFence;
286     FenceTime::Snapshot mDisplayPresentFence;
287     FenceTime::Snapshot mReleaseFence;
288 
289     // This is a static method with an auto return value so we can call
290     // it without needing const and non-const versions.
291     template <typename ThisT>
292     static inline auto allFences(ThisT fed) ->
293             std::array<decltype(&fed->mReleaseFence), 3> {
294         return {{
295             &fed->mGpuCompositionDoneFence, &fed->mDisplayPresentFence,
296             &fed->mReleaseFence
297         }};
298     }
299 };
300 
301 
302 // A collection of updates from consumer to producer that can be sent
303 // through Binder.
304 class FrameEventHistoryDelta
305         : public Flattenable<FrameEventHistoryDelta> {
306 
307 friend class ConsumerFrameEventHistory;
308 friend class ProducerFrameEventHistory;
309 
310 public:
311     FrameEventHistoryDelta() = default;
312 
313     // Movable.
314     FrameEventHistoryDelta(FrameEventHistoryDelta&& src) = default;
315     FrameEventHistoryDelta& operator=(FrameEventHistoryDelta&& src) noexcept;
316     // Not copyable.
317     FrameEventHistoryDelta(const FrameEventHistoryDelta& src) = delete;
318     FrameEventHistoryDelta& operator=(
319             const FrameEventHistoryDelta& src) = delete;
320 
321     // Flattenable implementation.
322     size_t getFlattenedSize() const;
323     size_t getFdCount() const;
324     status_t flatten(void*& buffer, size_t& size, int*& fds,
325             size_t& count) const;
326     status_t unflatten(void const*& buffer, size_t& size, int const*& fds,
327             size_t& count);
328 
329 private:
330     static constexpr size_t minFlattenedSize();
331 
332     std::vector<FrameEventsDelta> mDeltas;
333     CompositorTiming mCompositorTiming;
334 };
335 
336 
337 } // namespace android
338 #endif
339