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 virtual ~FrameEventHistory(); 110 111 FrameEvents* getFrame(uint64_t frameNumber); 112 FrameEvents* getFrame(uint64_t frameNumber, size_t* iHint); 113 void checkFencesForCompletion(); 114 void dump(std::string& outString) const; 115 116 static constexpr size_t MAX_FRAME_HISTORY = 8; 117 118 protected: 119 std::array<FrameEvents, MAX_FRAME_HISTORY> mFrames; 120 121 CompositorTiming mCompositorTiming; 122 }; 123 124 125 // The producer's interface to FrameEventHistory 126 class ProducerFrameEventHistory : public FrameEventHistory { 127 public: 128 ~ProducerFrameEventHistory() override; 129 130 // Public for testing. 131 static nsecs_t snapToNextTick( 132 nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval); 133 134 nsecs_t getNextCompositeDeadline(const nsecs_t now) const; getCompositeInterval()135 nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; } getCompositeToPresentLatency()136 nsecs_t getCompositeToPresentLatency() const { 137 return mCompositorTiming.presentLatency; 138 } 139 140 // virtual for testing. 141 virtual void updateAcquireFence( 142 uint64_t frameNumber, std::shared_ptr<FenceTime>&& acquire); 143 void applyDelta(const FrameEventHistoryDelta& delta); 144 145 void updateSignalTimes(); 146 147 protected: 148 void applyFenceDelta(FenceTimeline* timeline, 149 std::shared_ptr<FenceTime>* dst, 150 const FenceTime::Snapshot& src) const; 151 152 // virtual for testing. 153 virtual std::shared_ptr<FenceTime> createFenceTime( 154 const sp<Fence>& fence) const; 155 156 size_t mAcquireOffset{0}; 157 158 // The consumer updates it's timelines in Layer and SurfaceFlinger since 159 // they can coordinate shared timelines better. The producer doesn't have 160 // shared timelines though, so just let it own and update all of them. 161 FenceTimeline mAcquireTimeline; 162 FenceTimeline mGpuCompositionDoneTimeline; 163 FenceTimeline mPresentTimeline; 164 FenceTimeline mReleaseTimeline; 165 }; 166 167 168 // Used by the consumer to create a new frame event record that is 169 // partially complete. 170 struct NewFrameEventsEntry { 171 uint64_t frameNumber{0}; 172 nsecs_t postedTime{0}; 173 nsecs_t requestedPresentTime{0}; 174 std::shared_ptr<FenceTime> acquireFence{FenceTime::NO_FENCE}; 175 }; 176 177 178 // Used by the consumer to keep track of which fields it already sent to 179 // the producer. 180 class FrameEventDirtyFields { 181 public: reset()182 inline void reset() { mBitset.reset(); } anyDirty()183 inline bool anyDirty() const { return mBitset.any(); } 184 185 template <FrameEvent event> setDirty()186 inline void setDirty() { 187 constexpr size_t eventIndex = static_cast<size_t>(event); 188 static_assert(eventIndex < FrameEvents::EVENT_COUNT, "Bad index."); 189 mBitset.set(eventIndex); 190 } 191 192 template <FrameEvent event> isDirty()193 inline bool isDirty() const { 194 constexpr size_t eventIndex = static_cast<size_t>(event); 195 static_assert(eventIndex < FrameEvents::EVENT_COUNT, "Bad index."); 196 return mBitset[eventIndex]; 197 } 198 199 private: 200 std::bitset<FrameEvents::EVENT_COUNT> mBitset; 201 }; 202 203 204 // The consumer's interface to FrameEventHistory 205 class ConsumerFrameEventHistory : public FrameEventHistory { 206 public: 207 ~ConsumerFrameEventHistory() override; 208 209 void onDisconnect(); 210 211 void initializeCompositorTiming(const CompositorTiming& compositorTiming); 212 213 void addQueue(const NewFrameEventsEntry& newEntry); 214 void addLatch(uint64_t frameNumber, nsecs_t latchTime); 215 void addPreComposition(uint64_t frameNumber, nsecs_t refreshStartTime); 216 void addPostComposition(uint64_t frameNumber, 217 const std::shared_ptr<FenceTime>& gpuCompositionDone, 218 const std::shared_ptr<FenceTime>& displayPresent, 219 const CompositorTiming& compositorTiming); 220 void addRelease(uint64_t frameNumber, nsecs_t dequeueReadyTime, 221 std::shared_ptr<FenceTime>&& release); 222 223 void getAndResetDelta(FrameEventHistoryDelta* delta); 224 225 private: 226 void getFrameDelta(FrameEventHistoryDelta* delta, 227 const std::array<FrameEvents, MAX_FRAME_HISTORY>::iterator& frame); 228 229 std::array<FrameEventDirtyFields, MAX_FRAME_HISTORY> mFramesDirty; 230 231 size_t mQueueOffset{0}; 232 size_t mCompositionOffset{0}; 233 size_t mReleaseOffset{0}; 234 235 int mCurrentConnectId{0}; 236 bool mProducerWantsEvents{false}; 237 }; 238 239 240 // A single frame update from the consumer to producer that can be sent 241 // through Binder. 242 // Although this may be sent multiple times for the same frame as new 243 // timestamps are set, Fences only need to be sent once. 244 class FrameEventsDelta : public Flattenable<FrameEventsDelta> { 245 friend class ProducerFrameEventHistory; 246 public: 247 FrameEventsDelta() = default; 248 FrameEventsDelta(size_t index, 249 const FrameEvents& frameTimestamps, 250 const FrameEventDirtyFields& dirtyFields); 251 252 // Movable. 253 FrameEventsDelta(FrameEventsDelta&& src) = default; 254 FrameEventsDelta& operator=(FrameEventsDelta&& src) = default; 255 // Not copyable. 256 FrameEventsDelta(const FrameEventsDelta& src) = delete; 257 FrameEventsDelta& operator=(const FrameEventsDelta& src) = delete; 258 259 // Flattenable implementation 260 size_t getFlattenedSize() const; 261 size_t getFdCount() const; 262 status_t flatten(void*& buffer, size_t& size, int*& fds, 263 size_t& count) const; 264 status_t unflatten(void const*& buffer, size_t& size, int const*& fds, 265 size_t& count); 266 267 private: 268 static constexpr size_t minFlattenedSize(); 269 270 size_t mIndex{0}; 271 uint64_t mFrameNumber{0}; 272 273 bool mAddPostCompositeCalled{0}; 274 bool mAddReleaseCalled{0}; 275 276 nsecs_t mPostedTime{FrameEvents::TIMESTAMP_PENDING}; 277 nsecs_t mRequestedPresentTime{FrameEvents::TIMESTAMP_PENDING}; 278 nsecs_t mLatchTime{FrameEvents::TIMESTAMP_PENDING}; 279 nsecs_t mFirstRefreshStartTime{FrameEvents::TIMESTAMP_PENDING}; 280 nsecs_t mLastRefreshStartTime{FrameEvents::TIMESTAMP_PENDING}; 281 nsecs_t mDequeueReadyTime{FrameEvents::TIMESTAMP_PENDING}; 282 283 FenceTime::Snapshot mGpuCompositionDoneFence; 284 FenceTime::Snapshot mDisplayPresentFence; 285 FenceTime::Snapshot mReleaseFence; 286 287 // This is a static method with an auto return value so we can call 288 // it without needing const and non-const versions. 289 template <typename ThisT> 290 static inline auto allFences(ThisT fed) -> 291 std::array<decltype(&fed->mReleaseFence), 3> { 292 return {{ 293 &fed->mGpuCompositionDoneFence, &fed->mDisplayPresentFence, 294 &fed->mReleaseFence 295 }}; 296 } 297 }; 298 299 300 // A collection of updates from consumer to producer that can be sent 301 // through Binder. 302 class FrameEventHistoryDelta 303 : public Flattenable<FrameEventHistoryDelta> { 304 305 friend class ConsumerFrameEventHistory; 306 friend class ProducerFrameEventHistory; 307 308 public: 309 FrameEventHistoryDelta() = default; 310 311 // Movable. 312 FrameEventHistoryDelta(FrameEventHistoryDelta&& src) = default; 313 FrameEventHistoryDelta& operator=(FrameEventHistoryDelta&& src) noexcept; 314 // Not copyable. 315 FrameEventHistoryDelta(const FrameEventHistoryDelta& src) = delete; 316 FrameEventHistoryDelta& operator=( 317 const FrameEventHistoryDelta& src) = delete; 318 319 // Flattenable implementation. 320 size_t getFlattenedSize() const; 321 size_t getFdCount() const; 322 status_t flatten(void*& buffer, size_t& size, int*& fds, 323 size_t& count) const; 324 status_t unflatten(void const*& buffer, size_t& size, int const*& fds, 325 size_t& count); 326 327 private: 328 static constexpr size_t minFlattenedSize(); 329 330 std::vector<FrameEventsDelta> mDeltas; 331 CompositorTiming mCompositorTiming; 332 }; 333 334 335 } // namespace android 336 #endif 337