FrameTimestamps.h revision 3d4039d7a291cd9b6f2dd4b46fcdb576f2db3356
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    GL_COMPOSITION_DONE,
45    DISPLAY_PRESENT,
46    DISPLAY_RETIRE,
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    bool hasPostedInfo() const;
55    bool hasRequestedPresentInfo() const;
56    bool hasLatchInfo() const;
57    bool hasFirstRefreshStartInfo() const;
58    bool hasLastRefreshStartInfo() const;
59    bool hasAcquireInfo() const;
60    bool hasGpuCompositionDoneInfo() const;
61    bool hasDisplayPresentInfo() const;
62    bool hasDisplayRetireInfo() const;
63    bool hasReleaseInfo() const;
64
65    void checkFencesForCompletion();
66    void dump(String8& outString) const;
67
68    static constexpr size_t EVENT_COUNT =
69            static_cast<size_t>(FrameEvent::EVENT_COUNT);
70    static_assert(EVENT_COUNT <= 32, "Event count sanity check failed.");
71
72    bool valid{false};
73    uint64_t frameNumber{0};
74
75    // Whether or not certain points in the frame's life cycle have been
76    // encountered help us determine if timestamps aren't available because
77    // a) we'll just never get them or b) they're not ready yet.
78    bool addPostCompositeCalled{false};
79    bool addRetireCalled{false};
80    bool addReleaseCalled{false};
81
82    nsecs_t postedTime{-1};
83    nsecs_t requestedPresentTime{-1};
84    nsecs_t latchTime{-1};
85    nsecs_t firstRefreshStartTime{-1};
86    nsecs_t lastRefreshStartTime{-1};
87
88    std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE};
89    std::shared_ptr<FenceTime> gpuCompositionDoneFence{FenceTime::NO_FENCE};
90    std::shared_ptr<FenceTime> displayPresentFence{FenceTime::NO_FENCE};
91    std::shared_ptr<FenceTime> displayRetireFence{FenceTime::NO_FENCE};
92    std::shared_ptr<FenceTime> releaseFence{FenceTime::NO_FENCE};
93};
94
95
96// A short history of frames that are synchronized between the consumer and
97// producer via deltas.
98class FrameEventHistory {
99public:
100    virtual ~FrameEventHistory();
101
102    FrameEvents* getFrame(uint64_t frameNumber);
103    FrameEvents* getFrame(uint64_t frameNumber, size_t* iHint);
104    void checkFencesForCompletion();
105    void dump(String8& outString) const;
106
107    static constexpr size_t MAX_FRAME_HISTORY = 8;
108
109protected:
110    std::array<FrameEvents, MAX_FRAME_HISTORY> mFrames;
111};
112
113
114// The producer's interface to FrameEventHistory
115class ProducerFrameEventHistory : public FrameEventHistory {
116public:
117    ~ProducerFrameEventHistory() override;
118
119    void updateAcquireFence(
120            uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire);
121    void applyDelta(const FrameEventHistoryDelta& delta);
122
123    void updateSignalTimes();
124
125private:
126    size_t mAcquireOffset{0};
127
128    // The consumer updates it's timelines in Layer and SurfaceFlinger since
129    // they can coordinate shared timelines better. The producer doesn't have
130    // shared timelines though, so just let it own and update all of them.
131    FenceTimeline mAcquireTimeline;
132    FenceTimeline mGpuCompositionDoneTimeline;
133    FenceTimeline mPresentTimeline;
134    FenceTimeline mRetireTimeline;
135    FenceTimeline mReleaseTimeline;
136};
137
138
139// Used by the consumer to create a new frame event record that is
140// partially complete.
141struct NewFrameEventsEntry {
142    uint64_t frameNumber{0};
143    nsecs_t postedTime{0};
144    nsecs_t requestedPresentTime{0};
145    std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE};
146};
147
148
149// Used by the consumer to keep track of which fields it already sent to
150// the producer.
151class FrameEventDirtyFields {
152public:
153    inline void reset() { mBitset.reset(); }
154    inline bool anyDirty() const { return mBitset.any(); }
155
156    template <FrameEvent event>
157    inline void setDirty() {
158        constexpr size_t eventIndex = static_cast<size_t>(event);
159        static_assert(eventIndex < FrameEvents::EVENT_COUNT, "Bad index.");
160        mBitset.set(eventIndex);
161    }
162
163    template <FrameEvent event>
164    inline bool isDirty() const {
165        constexpr size_t eventIndex = static_cast<size_t>(event);
166        static_assert(eventIndex < FrameEvents::EVENT_COUNT, "Bad index.");
167        return mBitset[eventIndex];
168    }
169
170private:
171    std::bitset<FrameEvents::EVENT_COUNT> mBitset;
172};
173
174
175// The consumer's interface to FrameEventHistory
176class ConsumerFrameEventHistory : public FrameEventHistory {
177public:
178    ~ConsumerFrameEventHistory() override;
179
180    void addQueue(const NewFrameEventsEntry& newEntry);
181    void addLatch(uint64_t frameNumber, nsecs_t latchTime);
182    void addPreComposition(uint64_t frameNumber, nsecs_t refreshStartTime);
183    void addPostComposition(uint64_t frameNumber,
184            const std::shared_ptr<FenceTime>& gpuCompositionDone,
185            const std::shared_ptr<FenceTime>& displayPresent);
186    void addRetire(uint64_t frameNumber,
187            const std::shared_ptr<FenceTime>& displayRetire);
188    void addRelease(uint64_t frameNumber,
189            std::shared_ptr<FenceTime>&& release);
190
191    void getAndResetDelta(FrameEventHistoryDelta* delta);
192
193private:
194    void getFrameDelta(FrameEventHistoryDelta* delta,
195            const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame);
196
197    std::array<FrameEventDirtyFields, MAX_FRAME_HISTORY> mFramesDirty;
198    size_t mQueueOffset{0};
199    size_t mCompositionOffset{0};
200    size_t mRetireOffset{0};
201    size_t mReleaseOffset{0};
202};
203
204
205// A single frame update from the consumer to producer that can be sent
206// through Binder.
207// Although this may be sent multiple times for the same frame as new
208// timestamps are set, Fences only need to be sent once.
209class FrameEventsDelta : public Flattenable<FrameEventsDelta> {
210friend class ProducerFrameEventHistory;
211public:
212    FrameEventsDelta() = default;
213    FrameEventsDelta(size_t index,
214            const FrameEvents& frameTimestamps,
215            const FrameEventDirtyFields& dirtyFields);
216
217    // Movable.
218    FrameEventsDelta(FrameEventsDelta&& src) = default;
219    FrameEventsDelta& operator=(FrameEventsDelta&& src) = default;
220    // Not copyable.
221    FrameEventsDelta(const FrameEventsDelta& src) = delete;
222    FrameEventsDelta& operator=(const FrameEventsDelta& src) = delete;
223
224    // Flattenable implementation
225    size_t getFlattenedSize() const;
226    size_t getFdCount() const;
227    status_t flatten(void*& buffer, size_t& size, int*& fds,
228            size_t& count) const;
229    status_t unflatten(void const*& buffer, size_t& size, int const*& fds,
230            size_t& count);
231
232private:
233    static size_t minFlattenedSize();
234
235    size_t mIndex{0};
236    uint64_t mFrameNumber{0};
237
238    bool mAddPostCompositeCalled{0};
239    bool mAddRetireCalled{0};
240    bool mAddReleaseCalled{0};
241
242    nsecs_t mPostedTime{0};
243    nsecs_t mRequestedPresentTime{0};
244    nsecs_t mLatchTime{0};
245    nsecs_t mFirstRefreshStartTime{0};
246    nsecs_t mLastRefreshStartTime{0};
247
248    FenceTime::Snapshot mGpuCompositionDoneFence;
249    FenceTime::Snapshot mDisplayPresentFence;
250    FenceTime::Snapshot mDisplayRetireFence;
251    FenceTime::Snapshot mReleaseFence;
252
253    // This is a static method with an auto return value so we can call
254    // it without needing const and non-const versions.
255    template <typename ThisT>
256    static inline auto allFences(ThisT fed) ->
257            std::array<decltype(&fed->mReleaseFence), 4> {
258        return {{
259            &fed->mGpuCompositionDoneFence, &fed->mDisplayPresentFence,
260            &fed->mDisplayRetireFence, &fed->mReleaseFence
261        }};
262    }
263};
264
265
266// A collection of updates from consumer to producer that can be sent
267// through Binder.
268class FrameEventHistoryDelta
269        : public Flattenable<FrameEventHistoryDelta> {
270
271friend class ConsumerFrameEventHistory;
272friend class ProducerFrameEventHistory;
273
274public:
275    FrameEventHistoryDelta() = default;
276
277    // Movable.
278    FrameEventHistoryDelta(FrameEventHistoryDelta&& src) = default;
279    FrameEventHistoryDelta& operator=(FrameEventHistoryDelta&& src);
280    // Not copyable.
281    FrameEventHistoryDelta(const FrameEventHistoryDelta& src) = delete;
282    FrameEventHistoryDelta& operator=(
283            const FrameEventHistoryDelta& src) = delete;
284
285    // Flattenable implementation.
286    size_t getFlattenedSize() const;
287    size_t getFdCount() const;
288    status_t flatten(void*& buffer, size_t& size, int*& fds,
289            size_t& count) const;
290    status_t unflatten(void const*& buffer, size_t& size, int const*& fds,
291            size_t& count);
292
293private:
294    static size_t minFlattenedSize();
295
296    std::vector<FrameEventsDelta> mDeltas;
297};
298
299
300} // namespace android
301#endif
302