• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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);
getReportedCompositeDeadline()134     nsecs_t getReportedCompositeDeadline() const { return mCompositorTiming.deadline; };
135 
136     nsecs_t getNextCompositeDeadline(const nsecs_t now) const;
getCompositeInterval()137     nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; }
getCompositeToPresentLatency()138     nsecs_t getCompositeToPresentLatency() const {
139         return mCompositorTiming.presentLatency;
140     }
141 
142     // virtual for testing.
143     virtual void updateAcquireFence(
144             uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire);
145     void applyDelta(const FrameEventHistoryDelta& delta);
146 
147     void updateSignalTimes();
148 
149 protected:
150     void applyFenceDelta(FenceTimeline* timeline,
151             std::shared_ptr<FenceTime>* dst,
152             const FenceTime::Snapshot& src) const;
153 
154     // virtual for testing.
155     virtual std::shared_ptr<FenceTime> createFenceTime(
156             const sp<Fence>& fence) const;
157 
158     size_t mAcquireOffset{0};
159 
160     // The consumer updates it's timelines in Layer and SurfaceFlinger since
161     // they can coordinate shared timelines better. The producer doesn't have
162     // shared timelines though, so just let it own and update all of them.
163     FenceTimeline mAcquireTimeline;
164     FenceTimeline mGpuCompositionDoneTimeline;
165     FenceTimeline mPresentTimeline;
166     FenceTimeline mReleaseTimeline;
167 };
168 
169 
170 // Used by the consumer to create a new frame event record that is
171 // partially complete.
172 struct NewFrameEventsEntry {
173     uint64_t frameNumber{0};
174     nsecs_t postedTime{0};
175     nsecs_t requestedPresentTime{0};
176     std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE};
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     void setProducerWantsEvents();
213 
214     void initializeCompositorTiming(const CompositorTiming& compositorTiming);
215 
216     void addQueue(const NewFrameEventsEntry& newEntry);
217     void addLatch(uint64_t frameNumber, nsecs_t latchTime);
218     void addPreComposition(uint64_t frameNumber, nsecs_t refreshStartTime);
219     void addPostComposition(uint64_t frameNumber,
220             const std::shared_ptr<FenceTime>& gpuCompositionDone,
221             const std::shared_ptr<FenceTime>& displayPresent,
222             const CompositorTiming& compositorTiming);
223     void addRelease(uint64_t frameNumber, nsecs_t dequeueReadyTime,
224             std::shared_ptr<FenceTime>&& release);
225 
226     void getAndResetDelta(FrameEventHistoryDelta* delta);
227 
228 private:
229     void getFrameDelta(FrameEventHistoryDelta* delta,
230                        const std::vector<FrameEvents>::iterator& frame);
231 
232     std::vector<FrameEventDirtyFields> mFramesDirty;
233 
234     size_t mQueueOffset{0};
235     size_t mCompositionOffset{0};
236     size_t mReleaseOffset{0};
237 
238     int mCurrentConnectId{0};
239     bool mProducerWantsEvents{false};
240 };
241 
242 
243 // A single frame update from the consumer to producer that can be sent
244 // through Binder.
245 // Although this may be sent multiple times for the same frame as new
246 // timestamps are set, Fences only need to be sent once.
247 class FrameEventsDelta : public Flattenable<FrameEventsDelta> {
248 friend class ProducerFrameEventHistory;
249 public:
250     FrameEventsDelta() = default;
251     FrameEventsDelta(size_t index,
252             const FrameEvents& frameTimestamps,
253             const FrameEventDirtyFields& dirtyFields);
254 
255     // Movable.
256     FrameEventsDelta(FrameEventsDelta&& src) = default;
257     FrameEventsDelta& operator=(FrameEventsDelta&& src) = default;
258     // Not copyable.
259     FrameEventsDelta(const FrameEventsDelta& src) = delete;
260     FrameEventsDelta& operator=(const FrameEventsDelta& src) = delete;
261 
262     // Flattenable implementation
263     size_t getFlattenedSize() const;
264     size_t getFdCount() const;
265     status_t flatten(void*& buffer, size_t& size, int*& fds,
266             size_t& count) const;
267     status_t unflatten(void const*& buffer, size_t& size, int const*& fds,
268             size_t& count);
269 
270 private:
271     static constexpr size_t minFlattenedSize();
272 
273     size_t mIndex{0};
274     uint64_t mFrameNumber{0};
275 
276     bool mAddPostCompositeCalled{0};
277     bool mAddReleaseCalled{0};
278 
279     nsecs_t mPostedTime{FrameEvents::TIMESTAMP_PENDING};
280     nsecs_t mRequestedPresentTime{FrameEvents::TIMESTAMP_PENDING};
281     nsecs_t mLatchTime{FrameEvents::TIMESTAMP_PENDING};
282     nsecs_t mFirstRefreshStartTime{FrameEvents::TIMESTAMP_PENDING};
283     nsecs_t mLastRefreshStartTime{FrameEvents::TIMESTAMP_PENDING};
284     nsecs_t mDequeueReadyTime{FrameEvents::TIMESTAMP_PENDING};
285 
286     FenceTime::Snapshot mGpuCompositionDoneFence;
287     FenceTime::Snapshot mDisplayPresentFence;
288     FenceTime::Snapshot mReleaseFence;
289 
290     // This is a static method with an auto return value so we can call
291     // it without needing const and non-const versions.
292     template <typename ThisT>
293     static inline auto allFences(ThisT fed) ->
294             std::array<decltype(&fed->mReleaseFence), 3> {
295         return {{
296             &fed->mGpuCompositionDoneFence, &fed->mDisplayPresentFence,
297             &fed->mReleaseFence
298         }};
299     }
300 };
301 
302 
303 // A collection of updates from consumer to producer that can be sent
304 // through Binder.
305 class FrameEventHistoryDelta
306         : public Flattenable<FrameEventHistoryDelta> {
307 
308 friend class ConsumerFrameEventHistory;
309 friend class ProducerFrameEventHistory;
310 
311 public:
312     FrameEventHistoryDelta() = default;
313 
314     // Movable.
315     FrameEventHistoryDelta(FrameEventHistoryDelta&& src) = default;
316     FrameEventHistoryDelta& operator=(FrameEventHistoryDelta&& src) noexcept;
317     // Not copyable.
318     FrameEventHistoryDelta(const FrameEventHistoryDelta& src) = delete;
319     FrameEventHistoryDelta& operator=(
320             const FrameEventHistoryDelta& src) = delete;
321 
322     // Flattenable implementation.
323     size_t getFlattenedSize() const;
324     size_t getFdCount() const;
325     status_t flatten(void*& buffer, size_t& size, int*& fds,
326             size_t& count) const;
327     status_t unflatten(void const*& buffer, size_t& size, int const*& fds,
328             size_t& count);
329 
330 private:
331     static constexpr size_t minFlattenedSize();
332 
333     std::vector<FrameEventsDelta> mDeltas;
334     CompositorTiming mCompositorTiming;
335 };
336 
337 
338 } // namespace android
339 #endif
340