• 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 
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