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