1 /* 2 * Copyright 2023 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 #pragma once 18 19 #include <array> 20 #include <atomic> 21 #include <memory> 22 #include <optional> 23 24 #include <ui/DisplayId.h> 25 #include <ui/Fence.h> 26 #include <ui/FenceTime.h> 27 28 #include <scheduler/Features.h> 29 #include <scheduler/FrameTime.h> 30 #include <scheduler/Time.h> 31 #include <scheduler/VsyncId.h> 32 #include <scheduler/interface/CompositeResult.h> 33 34 // TODO(b/185536303): Pull to FTL. 35 #include "../../../TracedOrdinal.h" 36 #include "../../../Utils/Dumper.h" 37 #include "../../../Utils/RingBuffer.h" 38 39 namespace android::scheduler { 40 41 struct IVsyncSource; 42 43 // Read-only interface to the metrics computed by FrameTargeter for the latest frame. 44 class FrameTarget { 45 public: vsyncId()46 VsyncId vsyncId() const { return mVsyncId; } 47 48 // The time when the frame actually began, as opposed to when it had been scheduled to begin. frameBeginTime()49 TimePoint frameBeginTime() const { return mFrameBeginTime; } 50 51 // Relative to when the frame actually began, as opposed to when it had been scheduled to begin. expectedFrameDuration()52 Duration expectedFrameDuration() const { return mExpectedPresentTime - mFrameBeginTime; } 53 expectedPresentTime()54 TimePoint expectedPresentTime() const { return mExpectedPresentTime; } 55 debugPresentDelay()56 std::optional<TimePoint> debugPresentDelay() const { return mDebugPresentTimeDelay; } 57 earliestPresentTime()58 std::optional<TimePoint> earliestPresentTime() const { return mEarliestPresentTime; } 59 60 // Equivalent to `expectedSignaledPresentFence` unless running N VSYNCs ahead. 61 const FenceTimePtr& presentFenceForPreviousFrame() const; 62 isFramePending()63 bool isFramePending() const { return mFramePending; } wouldBackpressureHwc()64 bool wouldBackpressureHwc() const { return mWouldBackpressureHwc; } didMissFrame()65 bool didMissFrame() const { return mFrameMissed; } didMissHwcFrame()66 bool didMissHwcFrame() const { return mHwcFrameMissed && !mGpuFrameMissed; } lastSignaledFrameTime()67 FrameTime lastSignaledFrameTime() const { return mLastSignaledFrameTime; } 68 69 protected: 70 explicit FrameTarget(const std::string& displayLabel); 71 ~FrameTarget() = default; 72 73 bool wouldPresentEarly(Period vsyncPeriod, Period minFramePeriod) const; 74 75 // Equivalent to `pastVsyncTime` unless running N VSYNCs ahead. previousFrameVsyncTime(Period minFramePeriod)76 TimePoint previousFrameVsyncTime(Period minFramePeriod) const { 77 return mExpectedPresentTime - minFramePeriod; 78 } 79 addFence(sp<Fence> presentFence,FenceTimePtr presentFenceTime,TimePoint expectedPresentTime)80 void addFence(sp<Fence> presentFence, FenceTimePtr presentFenceTime, 81 TimePoint expectedPresentTime) { 82 mPresentFences.next() = {std::move(presentFence), presentFenceTime, expectedPresentTime}; 83 } 84 85 VsyncId mVsyncId; 86 TimePoint mFrameBeginTime; 87 TimePoint mExpectedPresentTime; 88 std::optional<TimePoint> mEarliestPresentTime; 89 std::optional<TimePoint> mDebugPresentTimeDelay; 90 91 TracedOrdinal<bool> mFramePending; 92 TracedOrdinal<bool> mFrameMissed; 93 TracedOrdinal<bool> mHwcFrameMissed; 94 TracedOrdinal<bool> mGpuFrameMissed; 95 bool mWouldBackpressureHwc = false; 96 97 struct PresentFence { 98 sp<Fence> fence = Fence::NO_FENCE; 99 FenceTimePtr fenceTime = FenceTime::NO_FENCE; 100 TimePoint expectedPresentTime = TimePoint(); 101 }; 102 103 // The present fence for the frame that had targeted the most recent VSYNC before this frame. 104 // If the target VSYNC for any given frame is more than `vsyncPeriod` in the future, then the 105 // VSYNC of at least one previous frame has not yet passed. In other words, this is NOT the 106 // `presentFenceForPreviousFrame` if running N VSYNCs ahead, but the one that should have been 107 // signaled by now (unless that frame missed). 108 std::pair<bool /* wouldBackpressure */, PresentFence> expectedSignaledPresentFence( 109 Period vsyncPeriod, Period minFramePeriod) const; 110 std::array<PresentFence, 2> mPresentFencesLegacy; 111 utils::RingBuffer<PresentFence, 5> mPresentFences; 112 113 FrameTime mLastSignaledFrameTime; 114 115 private: 116 friend class FrameTargeterTestBase; 117 118 template <int N> targetsVsyncsAhead(Period minFramePeriod)119 inline bool targetsVsyncsAhead(Period minFramePeriod) const { 120 static_assert(N > 1); 121 return expectedFrameDuration() > (N - 1) * minFramePeriod; 122 } 123 }; 124 125 // Computes a display's per-frame metrics about past/upcoming targeting of present deadlines. 126 class FrameTargeter final : private FrameTarget { 127 public: FrameTargeter(PhysicalDisplayId displayId,FeatureFlags flags)128 FrameTargeter(PhysicalDisplayId displayId, FeatureFlags flags) 129 : FrameTarget(to_string(displayId)), 130 mBackpressureGpuComposition(flags.test(Feature::kBackpressureGpuComposition)), 131 mSupportsExpectedPresentTime(flags.test(Feature::kExpectedPresentTime)) {} 132 target()133 const FrameTarget& target() const { return *this; } 134 135 struct BeginFrameArgs { 136 TimePoint frameBeginTime; 137 VsyncId vsyncId; 138 TimePoint expectedVsyncTime; 139 Duration sfWorkDuration; 140 Duration hwcMinWorkDuration; 141 std::optional<TimePoint> debugPresentTimeDelay; // used to introduce jank for testing 142 }; 143 144 void beginFrame(const BeginFrameArgs&, const IVsyncSource&); 145 146 std::optional<TimePoint> computeEarliestPresentTime(Period vsyncPeriod, Period minFramePeriod, 147 Duration hwcMinWorkDuration); 148 149 // TODO(b/241285191): Merge with FrameTargeter::endFrame. 150 FenceTimePtr setPresentFence(sp<Fence>); 151 152 void endFrame(const CompositeResult&); 153 154 void dump(utils::Dumper&) const; 155 156 private: 157 friend class FrameTargeterTestBase; 158 159 // For tests. 160 using IsFencePendingFuncPtr = bool (*)(const FenceTimePtr&, int graceTimeMs); 161 void beginFrame(const BeginFrameArgs&, const IVsyncSource&, IsFencePendingFuncPtr); 162 FenceTimePtr setPresentFence(sp<Fence>, FenceTimePtr); 163 164 static bool isFencePending(const FenceTimePtr&, int graceTimeMs); 165 166 const bool mBackpressureGpuComposition; 167 const bool mSupportsExpectedPresentTime; 168 169 TimePoint mScheduledPresentTime; 170 CompositionCoverageFlags mCompositionCoverage; 171 172 std::atomic_uint mFrameMissedCount = 0; 173 std::atomic_uint mHwcFrameMissedCount = 0; 174 std::atomic_uint mGpuFrameMissedCount = 0; 175 }; 176 177 } // namespace android::scheduler 178