xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/Scheduler/include/scheduler/FrameTargeter.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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