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 <unordered_map> 20 21 #include "RefreshRateConfigs.h" 22 #include "VSyncModulator.h" 23 24 namespace android::scheduler { 25 26 /* 27 * This class encapsulates offsets for different refresh rates. Depending 28 * on what refresh rate we are using, and wheter we are composing in GL, 29 * different offsets will help us with latency. This class keeps track of 30 * which mode the device is on, and returns approprate offsets when needed. 31 */ 32 class PhaseConfiguration { 33 public: 34 using Offsets = VSyncModulator::OffsetsConfig; 35 36 virtual ~PhaseConfiguration(); 37 38 virtual Offsets getCurrentOffsets() const = 0; 39 virtual Offsets getOffsetsForRefreshRate(float fps) const = 0; 40 41 virtual void setRefreshRateFps(float fps) = 0; 42 43 virtual void dump(std::string& result) const = 0; 44 }; 45 46 namespace impl { 47 48 /* 49 * This is the old implementation of phase offsets and considered as deprecated. 50 * PhaseDurations is the new implementation. 51 */ 52 class PhaseOffsets : public scheduler::PhaseConfiguration { 53 public: 54 PhaseOffsets(const scheduler::RefreshRateConfigs&); 55 56 // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate. 57 Offsets getOffsetsForRefreshRate(float fps) const override; 58 59 // Returns early, early GL, and late offsets for Apps and SF. getCurrentOffsets()60 Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateFps); } 61 62 // This function should be called when the device is switching between different 63 // refresh rates, to properly update the offsets. setRefreshRateFps(float fps)64 void setRefreshRateFps(float fps) override { mRefreshRateFps = fps; } 65 66 // Returns current offsets in human friendly format. 67 void dump(std::string& result) const override; 68 69 protected: 70 // Used for unit tests 71 PhaseOffsets(const std::vector<float>& refreshRates, float currentFps, 72 nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, 73 std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGlSfOffsetNs, 74 std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGlAppOffsetNs, 75 nsecs_t thresholdForNextVsync); 76 std::unordered_map<float, Offsets> initializeOffsets( 77 const std::vector<float>& refreshRates) const; 78 Offsets getDefaultOffsets(nsecs_t vsyncPeriod) const; 79 Offsets getHighFpsOffsets(nsecs_t vsyncPeriod) const; 80 Offsets getPhaseOffsets(float fps, nsecs_t vsyncPeriod) const; 81 82 const nsecs_t mVSyncPhaseOffsetNs; 83 const nsecs_t mSfVSyncPhaseOffsetNs; 84 const std::optional<nsecs_t> mEarlySfOffsetNs; 85 const std::optional<nsecs_t> mEarlyGlSfOffsetNs; 86 const std::optional<nsecs_t> mEarlyAppOffsetNs; 87 const std::optional<nsecs_t> mEarlyGlAppOffsetNs; 88 const nsecs_t mThresholdForNextVsync; 89 const std::unordered_map<float, Offsets> mOffsets; 90 91 std::atomic<float> mRefreshRateFps; 92 }; 93 94 /* 95 * Class that encapsulates the phase offsets for SurfaceFlinger and App. 96 * The offsets are calculated from durations for each one of the (late, early, earlyGL) 97 * offset types. 98 */ 99 class PhaseDurations : public scheduler::PhaseConfiguration { 100 public: 101 PhaseDurations(const scheduler::RefreshRateConfigs&); 102 103 // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate. 104 Offsets getOffsetsForRefreshRate(float fps) const override; 105 106 // Returns early, early GL, and late offsets for Apps and SF. getCurrentOffsets()107 Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateFps); } 108 109 // This function should be called when the device is switching between different 110 // refresh rates, to properly update the offsets. setRefreshRateFps(float fps)111 void setRefreshRateFps(float fps) override { mRefreshRateFps = fps; } 112 113 // Returns current offsets in human friendly format. 114 void dump(std::string& result) const override; 115 116 protected: 117 // Used for unit tests 118 PhaseDurations(const std::vector<float>& refreshRates, float currentFps, nsecs_t sfDuration, 119 nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, 120 nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration); 121 122 private: 123 std::unordered_map<float, Offsets> initializeOffsets(const std::vector<float>&) const; 124 PhaseDurations::Offsets constructOffsets(nsecs_t vsyncDuration) const; 125 126 const nsecs_t mSfDuration; 127 const nsecs_t mAppDuration; 128 129 const nsecs_t mSfEarlyDuration; 130 const nsecs_t mAppEarlyDuration; 131 132 const nsecs_t mSfEarlyGlDuration; 133 const nsecs_t mAppEarlyGlDuration; 134 135 const std::unordered_map<float, Offsets> mOffsets; 136 137 std::atomic<float> mRefreshRateFps; 138 }; 139 140 } // namespace impl 141 } // namespace android::scheduler 142