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