xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/Scheduler/VsyncConfiguration.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2019 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <mutex>
20*38e8c45fSAndroid Build Coastguard Worker #include <optional>
21*38e8c45fSAndroid Build Coastguard Worker #include <string>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <ftl/small_map.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <utils/Timers.h>
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/Fps.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <scheduler/VsyncConfig.h>
29*38e8c45fSAndroid Build Coastguard Worker 
30*38e8c45fSAndroid Build Coastguard Worker namespace android::scheduler {
31*38e8c45fSAndroid Build Coastguard Worker 
32*38e8c45fSAndroid Build Coastguard Worker /*
33*38e8c45fSAndroid Build Coastguard Worker  * This class encapsulates vsync configurations for different refresh rates. Depending
34*38e8c45fSAndroid Build Coastguard Worker  * on what refresh rate we are using, and wheter we are composing in GL,
35*38e8c45fSAndroid Build Coastguard Worker  * different offsets will help us with latency. This class keeps track of
36*38e8c45fSAndroid Build Coastguard Worker  * which mode the device is on, and returns approprate offsets when needed.
37*38e8c45fSAndroid Build Coastguard Worker  */
38*38e8c45fSAndroid Build Coastguard Worker class VsyncConfiguration {
39*38e8c45fSAndroid Build Coastguard Worker public:
40*38e8c45fSAndroid Build Coastguard Worker     virtual ~VsyncConfiguration() = default;
41*38e8c45fSAndroid Build Coastguard Worker     virtual VsyncConfigSet getCurrentConfigs() const = 0;
42*38e8c45fSAndroid Build Coastguard Worker     virtual VsyncConfigSet getConfigsForRefreshRate(Fps fps) const = 0;
43*38e8c45fSAndroid Build Coastguard Worker     virtual void reset() = 0;
44*38e8c45fSAndroid Build Coastguard Worker 
45*38e8c45fSAndroid Build Coastguard Worker     virtual void setRefreshRateFps(Fps fps) = 0;
46*38e8c45fSAndroid Build Coastguard Worker     virtual void dump(std::string& result) const = 0;
47*38e8c45fSAndroid Build Coastguard Worker };
48*38e8c45fSAndroid Build Coastguard Worker 
49*38e8c45fSAndroid Build Coastguard Worker namespace impl {
50*38e8c45fSAndroid Build Coastguard Worker 
51*38e8c45fSAndroid Build Coastguard Worker /*
52*38e8c45fSAndroid Build Coastguard Worker  * This is a common implementation for both phase offsets and durations.
53*38e8c45fSAndroid Build Coastguard Worker  * PhaseOffsets and WorkDuration derive from this class and implement the
54*38e8c45fSAndroid Build Coastguard Worker  * constructOffsets method
55*38e8c45fSAndroid Build Coastguard Worker  */
56*38e8c45fSAndroid Build Coastguard Worker class VsyncConfiguration : public scheduler::VsyncConfiguration {
57*38e8c45fSAndroid Build Coastguard Worker public:
58*38e8c45fSAndroid Build Coastguard Worker     explicit VsyncConfiguration(Fps currentFps);
59*38e8c45fSAndroid Build Coastguard Worker 
60*38e8c45fSAndroid Build Coastguard Worker     // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
61*38e8c45fSAndroid Build Coastguard Worker     VsyncConfigSet getConfigsForRefreshRate(Fps fps) const override EXCLUDES(mLock);
62*38e8c45fSAndroid Build Coastguard Worker 
63*38e8c45fSAndroid Build Coastguard Worker     // Returns early, early GL, and late offsets for Apps and SF.
getCurrentConfigs()64*38e8c45fSAndroid Build Coastguard Worker     VsyncConfigSet getCurrentConfigs() const override EXCLUDES(mLock) {
65*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mLock);
66*38e8c45fSAndroid Build Coastguard Worker         return getConfigsForRefreshRateLocked(mRefreshRateFps);
67*38e8c45fSAndroid Build Coastguard Worker     }
68*38e8c45fSAndroid Build Coastguard Worker 
69*38e8c45fSAndroid Build Coastguard Worker     // Cleans the internal cache.
reset()70*38e8c45fSAndroid Build Coastguard Worker     void reset() override EXCLUDES(mLock) {
71*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mLock);
72*38e8c45fSAndroid Build Coastguard Worker         mOffsetsCache.clear();
73*38e8c45fSAndroid Build Coastguard Worker     }
74*38e8c45fSAndroid Build Coastguard Worker 
75*38e8c45fSAndroid Build Coastguard Worker     // This function should be called when the device is switching between different
76*38e8c45fSAndroid Build Coastguard Worker     // refresh rates, to properly update the offsets.
setRefreshRateFps(Fps fps)77*38e8c45fSAndroid Build Coastguard Worker     void setRefreshRateFps(Fps fps) override EXCLUDES(mLock) {
78*38e8c45fSAndroid Build Coastguard Worker         std::lock_guard lock(mLock);
79*38e8c45fSAndroid Build Coastguard Worker         mRefreshRateFps = fps;
80*38e8c45fSAndroid Build Coastguard Worker     }
81*38e8c45fSAndroid Build Coastguard Worker 
82*38e8c45fSAndroid Build Coastguard Worker     // Returns current offsets in human friendly format.
83*38e8c45fSAndroid Build Coastguard Worker     void dump(std::string& result) const override;
84*38e8c45fSAndroid Build Coastguard Worker 
85*38e8c45fSAndroid Build Coastguard Worker protected:
86*38e8c45fSAndroid Build Coastguard Worker     virtual VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const = 0;
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker     VsyncConfigSet getConfigsForRefreshRateLocked(Fps fps) const REQUIRES(mLock);
89*38e8c45fSAndroid Build Coastguard Worker 
90*38e8c45fSAndroid Build Coastguard Worker     mutable ftl::SmallMap<Fps, VsyncConfigSet, 2, FpsApproxEqual> mOffsetsCache GUARDED_BY(mLock);
91*38e8c45fSAndroid Build Coastguard Worker     Fps mRefreshRateFps GUARDED_BY(mLock);
92*38e8c45fSAndroid Build Coastguard Worker     mutable std::mutex mLock;
93*38e8c45fSAndroid Build Coastguard Worker };
94*38e8c45fSAndroid Build Coastguard Worker 
95*38e8c45fSAndroid Build Coastguard Worker /*
96*38e8c45fSAndroid Build Coastguard Worker  * This is the old implementation of phase offsets and considered as deprecated.
97*38e8c45fSAndroid Build Coastguard Worker  * WorkDuration is the new implementation.
98*38e8c45fSAndroid Build Coastguard Worker  */
99*38e8c45fSAndroid Build Coastguard Worker class PhaseOffsets : public VsyncConfiguration {
100*38e8c45fSAndroid Build Coastguard Worker public:
101*38e8c45fSAndroid Build Coastguard Worker     explicit PhaseOffsets(Fps currentRefreshRate);
102*38e8c45fSAndroid Build Coastguard Worker 
103*38e8c45fSAndroid Build Coastguard Worker protected:
104*38e8c45fSAndroid Build Coastguard Worker     // Used for unit tests
105*38e8c45fSAndroid Build Coastguard Worker     PhaseOffsets(Fps currentRefreshRate, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
106*38e8c45fSAndroid Build Coastguard Worker                  std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs,
107*38e8c45fSAndroid Build Coastguard Worker                  std::optional<nsecs_t> earlyAppOffsetNs,
108*38e8c45fSAndroid Build Coastguard Worker                  std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs,
109*38e8c45fSAndroid Build Coastguard Worker                  nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs,
110*38e8c45fSAndroid Build Coastguard Worker                  std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs,
111*38e8c45fSAndroid Build Coastguard Worker                  std::optional<nsecs_t> highFpsEarlyAppOffsetNs,
112*38e8c45fSAndroid Build Coastguard Worker                  std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync,
113*38e8c45fSAndroid Build Coastguard Worker                  nsecs_t hwcMinWorkDuration);
114*38e8c45fSAndroid Build Coastguard Worker 
115*38e8c45fSAndroid Build Coastguard Worker private:
116*38e8c45fSAndroid Build Coastguard Worker     VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;
117*38e8c45fSAndroid Build Coastguard Worker 
118*38e8c45fSAndroid Build Coastguard Worker     VsyncConfigSet getDefaultOffsets(nsecs_t vsyncPeriod) const;
119*38e8c45fSAndroid Build Coastguard Worker     VsyncConfigSet getHighFpsOffsets(nsecs_t vsyncPeriod) const;
120*38e8c45fSAndroid Build Coastguard Worker 
121*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mVSyncPhaseOffsetNs;
122*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mSfVSyncPhaseOffsetNs;
123*38e8c45fSAndroid Build Coastguard Worker     const std::optional<nsecs_t> mEarlySfOffsetNs;
124*38e8c45fSAndroid Build Coastguard Worker     const std::optional<nsecs_t> mEarlyGpuSfOffsetNs;
125*38e8c45fSAndroid Build Coastguard Worker     const std::optional<nsecs_t> mEarlyAppOffsetNs;
126*38e8c45fSAndroid Build Coastguard Worker     const std::optional<nsecs_t> mEarlyGpuAppOffsetNs;
127*38e8c45fSAndroid Build Coastguard Worker 
128*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mHighFpsVSyncPhaseOffsetNs;
129*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mHighFpsSfVSyncPhaseOffsetNs;
130*38e8c45fSAndroid Build Coastguard Worker     const std::optional<nsecs_t> mHighFpsEarlySfOffsetNs;
131*38e8c45fSAndroid Build Coastguard Worker     const std::optional<nsecs_t> mHighFpsEarlyGpuSfOffsetNs;
132*38e8c45fSAndroid Build Coastguard Worker     const std::optional<nsecs_t> mHighFpsEarlyAppOffsetNs;
133*38e8c45fSAndroid Build Coastguard Worker     const std::optional<nsecs_t> mHighFpsEarlyGpuAppOffsetNs;
134*38e8c45fSAndroid Build Coastguard Worker 
135*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mThresholdForNextVsync;
136*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mHwcMinWorkDuration;
137*38e8c45fSAndroid Build Coastguard Worker };
138*38e8c45fSAndroid Build Coastguard Worker 
139*38e8c45fSAndroid Build Coastguard Worker /*
140*38e8c45fSAndroid Build Coastguard Worker  * Class that encapsulates the phase offsets for SurfaceFlinger and App.
141*38e8c45fSAndroid Build Coastguard Worker  * The offsets are calculated from durations for each one of the (late, early, earlyGpu)
142*38e8c45fSAndroid Build Coastguard Worker  * offset types.
143*38e8c45fSAndroid Build Coastguard Worker  */
144*38e8c45fSAndroid Build Coastguard Worker class WorkDuration : public VsyncConfiguration {
145*38e8c45fSAndroid Build Coastguard Worker public:
146*38e8c45fSAndroid Build Coastguard Worker     explicit WorkDuration(Fps currentRefreshRate);
147*38e8c45fSAndroid Build Coastguard Worker 
148*38e8c45fSAndroid Build Coastguard Worker protected:
149*38e8c45fSAndroid Build Coastguard Worker     // Used for unit tests
150*38e8c45fSAndroid Build Coastguard Worker     WorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration,
151*38e8c45fSAndroid Build Coastguard Worker                  nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration,
152*38e8c45fSAndroid Build Coastguard Worker                  nsecs_t hwcMinWorkDuration);
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker private:
155*38e8c45fSAndroid Build Coastguard Worker     VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;
156*38e8c45fSAndroid Build Coastguard Worker 
157*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mSfDuration;
158*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mAppDuration;
159*38e8c45fSAndroid Build Coastguard Worker 
160*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mSfEarlyDuration;
161*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mAppEarlyDuration;
162*38e8c45fSAndroid Build Coastguard Worker 
163*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mSfEarlyGpuDuration;
164*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mAppEarlyGpuDuration;
165*38e8c45fSAndroid Build Coastguard Worker 
166*38e8c45fSAndroid Build Coastguard Worker     const nsecs_t mHwcMinWorkDuration;
167*38e8c45fSAndroid Build Coastguard Worker };
168*38e8c45fSAndroid Build Coastguard Worker 
169*38e8c45fSAndroid Build Coastguard Worker } // namespace impl
170*38e8c45fSAndroid Build Coastguard Worker } // namespace android::scheduler
171