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