• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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