• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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 <mutex>
20 #include <optional>
21 #include <string>
22 
23 #include <ftl/small_map.h>
24 #include <utils/Timers.h>
25 
26 #include <scheduler/Fps.h>
27 
28 #include "VsyncModulator.h"
29 
30 namespace android::scheduler {
31 
32 /*
33  * This class encapsulates vsync configurations for different refresh rates. Depending
34  * on what refresh rate we are using, and wheter we are composing in GL,
35  * different offsets will help us with latency. This class keeps track of
36  * which mode the device is on, and returns approprate offsets when needed.
37  */
38 class VsyncConfiguration {
39 public:
40     using VsyncConfigSet = VsyncModulator::VsyncConfigSet;
41 
42     virtual ~VsyncConfiguration() = default;
43     virtual VsyncConfigSet getCurrentConfigs() const = 0;
44     virtual VsyncConfigSet getConfigsForRefreshRate(Fps fps) const = 0;
45     virtual void reset() = 0;
46 
47     virtual void setRefreshRateFps(Fps fps) = 0;
48     virtual void dump(std::string& result) const = 0;
49 };
50 
51 namespace impl {
52 
53 /*
54  * This is a common implementation for both phase offsets and durations.
55  * PhaseOffsets and WorkDuration derive from this class and implement the
56  * constructOffsets method
57  */
58 class VsyncConfiguration : public scheduler::VsyncConfiguration {
59 public:
60     explicit VsyncConfiguration(Fps currentFps);
61 
62     // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
63     VsyncConfigSet getConfigsForRefreshRate(Fps fps) const override EXCLUDES(mLock);
64 
65     // Returns early, early GL, and late offsets for Apps and SF.
getCurrentConfigs()66     VsyncConfigSet getCurrentConfigs() const override EXCLUDES(mLock) {
67         std::lock_guard lock(mLock);
68         return getConfigsForRefreshRateLocked(mRefreshRateFps);
69     }
70 
71     // Cleans the internal cache.
reset()72     void reset() override EXCLUDES(mLock) {
73         std::lock_guard lock(mLock);
74         mOffsetsCache.clear();
75     }
76 
77     // This function should be called when the device is switching between different
78     // refresh rates, to properly update the offsets.
setRefreshRateFps(Fps fps)79     void setRefreshRateFps(Fps fps) override EXCLUDES(mLock) {
80         std::lock_guard lock(mLock);
81         mRefreshRateFps = fps;
82     }
83 
84     // Returns current offsets in human friendly format.
85     void dump(std::string& result) const override;
86 
87 protected:
88     virtual VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const = 0;
89 
90     VsyncConfigSet getConfigsForRefreshRateLocked(Fps fps) const REQUIRES(mLock);
91 
92     mutable ftl::SmallMap<Fps, VsyncConfigSet, 2, FpsApproxEqual> mOffsetsCache GUARDED_BY(mLock);
93     Fps mRefreshRateFps GUARDED_BY(mLock);
94     mutable std::mutex mLock;
95 };
96 
97 /*
98  * This is the old implementation of phase offsets and considered as deprecated.
99  * WorkDuration is the new implementation.
100  */
101 class PhaseOffsets : public VsyncConfiguration {
102 public:
103     explicit PhaseOffsets(Fps currentRefreshRate);
104 
105 protected:
106     // Used for unit tests
107     PhaseOffsets(Fps currentRefreshRate, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
108                  std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs,
109                  std::optional<nsecs_t> earlyAppOffsetNs,
110                  std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs,
111                  nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs,
112                  std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs,
113                  std::optional<nsecs_t> highFpsEarlyAppOffsetNs,
114                  std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync,
115                  nsecs_t hwcMinWorkDuration);
116 
117 private:
118     VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;
119 
120     VsyncConfigSet getDefaultOffsets(nsecs_t vsyncPeriod) const;
121     VsyncConfigSet getHighFpsOffsets(nsecs_t vsyncPeriod) const;
122 
123     const nsecs_t mVSyncPhaseOffsetNs;
124     const nsecs_t mSfVSyncPhaseOffsetNs;
125     const std::optional<nsecs_t> mEarlySfOffsetNs;
126     const std::optional<nsecs_t> mEarlyGpuSfOffsetNs;
127     const std::optional<nsecs_t> mEarlyAppOffsetNs;
128     const std::optional<nsecs_t> mEarlyGpuAppOffsetNs;
129 
130     const nsecs_t mHighFpsVSyncPhaseOffsetNs;
131     const nsecs_t mHighFpsSfVSyncPhaseOffsetNs;
132     const std::optional<nsecs_t> mHighFpsEarlySfOffsetNs;
133     const std::optional<nsecs_t> mHighFpsEarlyGpuSfOffsetNs;
134     const std::optional<nsecs_t> mHighFpsEarlyAppOffsetNs;
135     const std::optional<nsecs_t> mHighFpsEarlyGpuAppOffsetNs;
136 
137     const nsecs_t mThresholdForNextVsync;
138     const nsecs_t mHwcMinWorkDuration;
139 };
140 
141 /*
142  * Class that encapsulates the phase offsets for SurfaceFlinger and App.
143  * The offsets are calculated from durations for each one of the (late, early, earlyGpu)
144  * offset types.
145  */
146 class WorkDuration : public VsyncConfiguration {
147 public:
148     explicit WorkDuration(Fps currentRefrshRate);
149 
150 protected:
151     // Used for unit tests
152     WorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration,
153                  nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration,
154                  nsecs_t hwcMinWorkDuration);
155 
156 private:
157     VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;
158 
159     const nsecs_t mSfDuration;
160     const nsecs_t mAppDuration;
161 
162     const nsecs_t mSfEarlyDuration;
163     const nsecs_t mAppEarlyDuration;
164 
165     const nsecs_t mSfEarlyGpuDuration;
166     const nsecs_t mAppEarlyGpuDuration;
167 
168     const nsecs_t mHwcMinWorkDuration;
169 };
170 
171 } // namespace impl
172 } // namespace android::scheduler
173