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