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
29namespace android {
30
31struct FrameEvents;
32class FrameEventHistoryDelta;
33class String8;
34
35
36// Identifiers for all the events that may be recorded or reported.
37enum 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.
53struct 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
59    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
100struct 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.
108class FrameEventHistory {
109public:
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
119protected:
120    std::array<FrameEvents, MAX_FRAME_HISTORY> mFrames;
121
122    CompositorTiming mCompositorTiming;
123};
124
125
126// The producer's interface to FrameEventHistory
127class ProducerFrameEventHistory : public FrameEventHistory {
128public:
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;
136    nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; }
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
148protected:
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.
171struct 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.
181class FrameEventDirtyFields {
182public:
183    inline void reset() { mBitset.reset(); }
184    inline bool anyDirty() const { return mBitset.any(); }
185
186    template <FrameEvent event>
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>
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
200private:
201    std::bitset<FrameEvents::EVENT_COUNT> mBitset;
202};
203
204
205// The consumer's interface to FrameEventHistory
206class ConsumerFrameEventHistory : public FrameEventHistory {
207public:
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
226private:
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.
245class FrameEventsDelta : public Flattenable<FrameEventsDelta> {
246friend class ProducerFrameEventHistory;
247public:
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
268private:
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.
303class FrameEventHistoryDelta
304        : public Flattenable<FrameEventHistoryDelta> {
305
306friend class ConsumerFrameEventHistory;
307friend class ProducerFrameEventHistory;
308
309public:
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
328private:
329    static constexpr size_t minFlattenedSize();
330
331    std::vector<FrameEventsDelta> mDeltas;
332    CompositorTiming mCompositorTiming;
333};
334
335
336} // namespace android
337#endif
338