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 23 #include <ui/DisplayId.h> 24 #include <ui/Fence.h> 25 #include <ui/FenceTime.h> 26 27 #include <scheduler/Time.h> 28 #include <scheduler/VsyncId.h> 29 #include <scheduler/interface/CompositeResult.h> 30 31 // TODO(b/185536303): Pull to FTL. 32 #include "../../../TracedOrdinal.h" 33 #include "../../../Utils/Dumper.h" 34 35 namespace android::scheduler { 36 37 struct IVsyncSource; 38 39 // Read-only interface to the metrics computed by FrameTargeter for the latest frame. 40 class FrameTarget { 41 public: vsyncId()42 VsyncId vsyncId() const { return mVsyncId; } 43 44 // The time when the frame actually began, as opposed to when it had been scheduled to begin. frameBeginTime()45 TimePoint frameBeginTime() const { return mFrameBeginTime; } 46 47 // Relative to when the frame actually began, as opposed to when it had been scheduled to begin. expectedFrameDuration()48 Duration expectedFrameDuration() const { return mExpectedPresentTime - mFrameBeginTime; } 49 expectedPresentTime()50 TimePoint expectedPresentTime() const { return mExpectedPresentTime; } 51 52 // The time of the VSYNC that preceded this frame. See `presentFenceForPastVsync` for details. 53 TimePoint pastVsyncTime(Period vsyncPeriod) const; 54 55 // Equivalent to `pastVsyncTime` unless running N VSYNCs ahead. previousFrameVsyncTime(Period vsyncPeriod)56 TimePoint previousFrameVsyncTime(Period vsyncPeriod) const { 57 return mExpectedPresentTime - vsyncPeriod; 58 } 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 const FenceTimePtr& presentFenceForPastVsync(Period vsyncPeriod) const; 66 67 // Equivalent to `presentFenceForPastVsync` unless running N VSYNCs ahead. presentFenceForPreviousFrame()68 const FenceTimePtr& presentFenceForPreviousFrame() const { 69 return mPresentFences.front().fenceTime; 70 } 71 72 bool wouldPresentEarly(Period vsyncPeriod) const; 73 isFramePending()74 bool isFramePending() const { return mFramePending; } didMissFrame()75 bool didMissFrame() const { return mFrameMissed; } didMissHwcFrame()76 bool didMissHwcFrame() const { return mHwcFrameMissed && !mGpuFrameMissed; } 77 78 protected: 79 explicit FrameTarget(const std::string& displayLabel); 80 ~FrameTarget() = default; 81 82 VsyncId mVsyncId; 83 TimePoint mFrameBeginTime; 84 TimePoint mExpectedPresentTime; 85 86 TracedOrdinal<bool> mFramePending; 87 TracedOrdinal<bool> mFrameMissed; 88 TracedOrdinal<bool> mHwcFrameMissed; 89 TracedOrdinal<bool> mGpuFrameMissed; 90 91 struct FenceWithFenceTime { 92 sp<Fence> fence = Fence::NO_FENCE; 93 FenceTimePtr fenceTime = FenceTime::NO_FENCE; 94 }; 95 std::array<FenceWithFenceTime, 2> mPresentFences; 96 97 private: 98 template <int N> targetsVsyncsAhead(Period vsyncPeriod)99 inline bool targetsVsyncsAhead(Period vsyncPeriod) const { 100 static_assert(N > 1); 101 return expectedFrameDuration() > (N - 1) * vsyncPeriod; 102 } 103 }; 104 105 // Computes a display's per-frame metrics about past/upcoming targeting of present deadlines. 106 class FrameTargeter final : private FrameTarget { 107 public: FrameTargeter(PhysicalDisplayId displayId,bool backpressureGpuComposition)108 FrameTargeter(PhysicalDisplayId displayId, bool backpressureGpuComposition) 109 : FrameTarget(to_string(displayId)), 110 mBackpressureGpuComposition(backpressureGpuComposition) {} 111 target()112 const FrameTarget& target() const { return *this; } 113 114 struct BeginFrameArgs { 115 TimePoint frameBeginTime; 116 VsyncId vsyncId; 117 TimePoint expectedVsyncTime; 118 Duration sfWorkDuration; 119 }; 120 121 void beginFrame(const BeginFrameArgs&, const IVsyncSource&); 122 123 // TODO(b/241285191): Merge with FrameTargeter::endFrame. 124 FenceTimePtr setPresentFence(sp<Fence>); 125 126 void endFrame(const CompositeResult&); 127 128 void dump(utils::Dumper&) const; 129 130 private: 131 friend class FrameTargeterTest; 132 133 // For tests. 134 using IsFencePendingFuncPtr = bool (*)(const FenceTimePtr&, int graceTimeMs); 135 void beginFrame(const BeginFrameArgs&, const IVsyncSource&, IsFencePendingFuncPtr); 136 FenceTimePtr setPresentFence(sp<Fence>, FenceTimePtr); 137 138 static bool isFencePending(const FenceTimePtr&, int graceTimeMs); 139 140 const bool mBackpressureGpuComposition; 141 142 TimePoint mScheduledPresentTime; 143 CompositionCoverageFlags mCompositionCoverage; 144 145 std::atomic_uint mFrameMissedCount = 0; 146 std::atomic_uint mHwcFrameMissedCount = 0; 147 std::atomic_uint mGpuFrameMissedCount = 0; 148 }; 149 150 } // namespace android::scheduler 151