Home | History | Annotate | Download | only in gui
      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 
     58     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;
    135     nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; }
    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:
    182     inline void reset() { mBitset.reset(); }
    183     inline bool anyDirty() const { return mBitset.any(); }
    184 
    185     template <FrameEvent event>
    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>
    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