diff options
Diffstat (limited to 'services/surfaceflinger/Scheduler/PhaseOffsets.h')
-rw-r--r-- | services/surfaceflinger/Scheduler/PhaseOffsets.h | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.h b/services/surfaceflinger/Scheduler/PhaseOffsets.h new file mode 100644 index 0000000000..9ec6d56fdf --- /dev/null +++ b/services/surfaceflinger/Scheduler/PhaseOffsets.h @@ -0,0 +1,141 @@ +/* + * Copyright 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <unordered_map> + +#include "RefreshRateConfigs.h" +#include "VSyncModulator.h" + +namespace android::scheduler { + +/* + * This class encapsulates offsets for different refresh rates. Depending + * on what refresh rate we are using, and wheter we are composing in GL, + * different offsets will help us with latency. This class keeps track of + * which mode the device is on, and returns approprate offsets when needed. + */ +class PhaseConfiguration { +public: + using Offsets = VSyncModulator::OffsetsConfig; + + virtual ~PhaseConfiguration(); + + virtual Offsets getCurrentOffsets() const = 0; + virtual Offsets getOffsetsForRefreshRate(float fps) const = 0; + + virtual void setRefreshRateFps(float fps) = 0; + + virtual void dump(std::string& result) const = 0; +}; + +namespace impl { + +/* + * This is the old implementation of phase offsets and considered as deprecated. + * PhaseDurations is the new implementation. + */ +class PhaseOffsets : public scheduler::PhaseConfiguration { +public: + PhaseOffsets(const scheduler::RefreshRateConfigs&); + + // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate. + Offsets getOffsetsForRefreshRate(float fps) const override; + + // Returns early, early GL, and late offsets for Apps and SF. + Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateFps); } + + // This function should be called when the device is switching between different + // refresh rates, to properly update the offsets. + void setRefreshRateFps(float fps) override { mRefreshRateFps = fps; } + + // Returns current offsets in human friendly format. + void dump(std::string& result) const override; + +protected: + // Used for unit tests + PhaseOffsets(const std::vector<float>& refreshRates, float currentFps, + nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, + std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGlSfOffsetNs, + std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGlAppOffsetNs, + nsecs_t thresholdForNextVsync); + std::unordered_map<float, Offsets> initializeOffsets( + const std::vector<float>& refreshRates) const; + Offsets getDefaultOffsets(nsecs_t vsyncPeriod) const; + Offsets getHighFpsOffsets(nsecs_t vsyncPeriod) const; + Offsets getPhaseOffsets(float fps, nsecs_t vsyncPeriod) const; + + const nsecs_t mVSyncPhaseOffsetNs; + const nsecs_t mSfVSyncPhaseOffsetNs; + const std::optional<nsecs_t> mEarlySfOffsetNs; + const std::optional<nsecs_t> mEarlyGlSfOffsetNs; + const std::optional<nsecs_t> mEarlyAppOffsetNs; + const std::optional<nsecs_t> mEarlyGlAppOffsetNs; + const nsecs_t mThresholdForNextVsync; + const std::unordered_map<float, Offsets> mOffsets; + + std::atomic<float> mRefreshRateFps; +}; + +/* + * Class that encapsulates the phase offsets for SurfaceFlinger and App. + * The offsets are calculated from durations for each one of the (late, early, earlyGL) + * offset types. + */ +class PhaseDurations : public scheduler::PhaseConfiguration { +public: + PhaseDurations(const scheduler::RefreshRateConfigs&); + + // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate. + Offsets getOffsetsForRefreshRate(float fps) const override; + + // Returns early, early GL, and late offsets for Apps and SF. + Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateFps); } + + // This function should be called when the device is switching between different + // refresh rates, to properly update the offsets. + void setRefreshRateFps(float fps) override { mRefreshRateFps = fps; } + + // Returns current offsets in human friendly format. + void dump(std::string& result) const override; + +protected: + // Used for unit tests + PhaseDurations(const std::vector<float>& refreshRates, float currentFps, nsecs_t sfDuration, + nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, + nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration); + +private: + std::unordered_map<float, Offsets> initializeOffsets(const std::vector<float>&) const; + PhaseDurations::Offsets constructOffsets(nsecs_t vsyncDuration) const; + + const nsecs_t mSfDuration; + const nsecs_t mAppDuration; + + const nsecs_t mSfEarlyDuration; + const nsecs_t mAppEarlyDuration; + + const nsecs_t mSfEarlyGlDuration; + const nsecs_t mAppEarlyGlDuration; + + const std::unordered_map<float, Offsets> mOffsets; + + std::atomic<float> mRefreshRateFps; +}; + +} // namespace impl +} // namespace android::scheduler |