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