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