Loading services/surfaceflinger/Scheduler/VsyncConfiguration.cpp +36 −56 Original line number Diff line number Diff line Loading @@ -16,14 +16,19 @@ #include "VsyncConfiguration.h" #include <cutils/properties.h> #include <chrono> #include <cinttypes> #include <optional> #include <cutils/properties.h> #include <log/log.h> #include "SurfaceFlingerProperties.h" namespace { using namespace std::chrono_literals; std::optional<nsecs_t> getProperty(const char* name) { char value[PROPERTY_VALUE_MAX]; property_get(name, value, "-1"); Loading @@ -31,19 +36,6 @@ std::optional<nsecs_t> getProperty(const char* name) { return std::nullopt; } std::vector<android::Fps> getRefreshRatesFromConfigs( const android::scheduler::RefreshRateConfigs& refreshRateConfigs) { const auto& allRefreshRates = refreshRateConfigs.getAllRefreshRates(); std::vector<android::Fps> refreshRates; refreshRates.reserve(allRefreshRates.size()); for (const auto& [ignored, refreshRate] : allRefreshRates) { refreshRates.emplace_back(refreshRate->getFps()); } return refreshRates; } } // namespace namespace android::scheduler::impl { Loading @@ -51,25 +43,19 @@ namespace android::scheduler::impl { VsyncConfiguration::VsyncConfiguration(Fps currentFps) : mRefreshRateFps(currentFps) {} PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRate(Fps fps) const { const auto iter = std::find_if(mOffsets.begin(), mOffsets.end(), [&fps](const std::pair<Fps, VsyncConfigSet>& candidateFps) { return fps.equalsWithMargin(candidateFps.first); }); if (iter != mOffsets.end()) { return iter->second; std::lock_guard lock(mLock); return getConfigsForRefreshRateLocked(fps); } // Unknown refresh rate. This might happen if we get a hotplug event for an external display. // In this case just construct the offset. ALOGW("Can't find offset for %s", to_string(fps).c_str()); return constructOffsets(fps.getPeriodNsecs()); PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRateLocked(Fps fps) const { const auto iter = mOffsetsCache.find(fps); if (iter != mOffsetsCache.end()) { return iter->second; } void VsyncConfiguration::initializeOffsets(const std::vector<Fps>& refreshRates) { for (const auto fps : refreshRates) { mOffsets.emplace(fps, constructOffsets(fps.getPeriodNsecs())); } const auto offset = constructOffsets(fps.getPeriodNsecs()); mOffsetsCache[fps] = offset; return offset; } void VsyncConfiguration::dump(std::string& result) const { Loading Loading @@ -98,10 +84,8 @@ void VsyncConfiguration::dump(std::string& result) const { earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count()); } PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfigs) : PhaseOffsets(getRefreshRatesFromConfigs(refreshRateConfigs), refreshRateConfigs.getCurrentRefreshRate().getFps(), sysprop::vsync_event_phase_offset_ns(1000000), PhaseOffsets::PhaseOffsets(Fps currentRefreshRate) : PhaseOffsets(currentRefreshRate, sysprop::vsync_event_phase_offset_ns(1000000), sysprop::vsync_sf_event_phase_offset_ns(1000000), getProperty("debug.sf.early_phase_offset_ns"), getProperty("debug.sf.early_gl_phase_offset_ns"), Loading @@ -121,15 +105,17 @@ PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfi getProperty("debug.sf.phase_offset_threshold_for_next_vsync_ns") .value_or(std::numeric_limits<nsecs_t>::max())) {} PhaseOffsets::PhaseOffsets( const std::vector<Fps>& refreshRates, Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs, std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs, nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs, PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs, std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs, nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, std::optional<nsecs_t> highFpsEarlyAppOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync) std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync) : VsyncConfiguration(currentFps), mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs), mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs), Loading @@ -143,9 +129,7 @@ PhaseOffsets::PhaseOffsets( mHighFpsEarlyGpuSfOffsetNs(highFpsEarlyGpuSfOffsetNs), mHighFpsEarlyAppOffsetNs(highFpsEarlyAppOffsetNs), mHighFpsEarlyGpuAppOffsetNs(highFpsEarlyGpuAppOffsetNs), mThresholdForNextVsync(thresholdForNextVsync) { initializeOffsets(refreshRates); } mThresholdForNextVsync(thresholdForNextVsync) {} PhaseOffsets::VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const { if (vsyncDuration < std::chrono::nanoseconds(15ms).count()) { Loading Loading @@ -361,10 +345,8 @@ WorkDuration::VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuratio }; } WorkDuration::WorkDuration(const scheduler::RefreshRateConfigs& refreshRateConfigs) : WorkDuration(getRefreshRatesFromConfigs(refreshRateConfigs), refreshRateConfigs.getCurrentRefreshRate().getFps(), getProperty("debug.sf.late.sf.duration").value_or(-1), WorkDuration::WorkDuration(Fps currentRefreshRate) : WorkDuration(currentRefreshRate, getProperty("debug.sf.late.sf.duration").value_or(-1), getProperty("debug.sf.late.app.duration").value_or(-1), getProperty("debug.sf.early.sf.duration").value_or(mSfDuration), getProperty("debug.sf.early.app.duration").value_or(mAppDuration), Loading @@ -373,17 +355,15 @@ WorkDuration::WorkDuration(const scheduler::RefreshRateConfigs& refreshRateConfi validateSysprops(); } WorkDuration::WorkDuration(const std::vector<Fps>& refreshRates, Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, WorkDuration::WorkDuration(Fps currentRefreshRate, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration) : VsyncConfiguration(currentFps), : VsyncConfiguration(currentRefreshRate), mSfDuration(sfDuration), mAppDuration(appDuration), mSfEarlyDuration(sfEarlyDuration), mAppEarlyDuration(appEarlyDuration), mSfEarlyGpuDuration(sfEarlyGpuDuration), mAppEarlyGpuDuration(appEarlyGpuDuration) { initializeOffsets(refreshRates); } mAppEarlyGpuDuration(appEarlyGpuDuration) {} } // namespace android::scheduler::impl services/surfaceflinger/Scheduler/VsyncConfiguration.h +31 −17 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ #pragma once #include <mutex> #include <type_traits> #include <unordered_map> #include <vector> #include <utils/Timers.h> #include "Fps.h" #include "RefreshRateConfigs.h" #include "VsyncModulator.h" namespace android::scheduler { Loading @@ -39,9 +41,9 @@ public: virtual ~VsyncConfiguration() = default; virtual VsyncConfigSet getCurrentConfigs() const = 0; virtual VsyncConfigSet getConfigsForRefreshRate(Fps fps) const = 0; virtual void reset() = 0; virtual void setRefreshRateFps(Fps fps) = 0; virtual void dump(std::string& result) const = 0; }; Loading @@ -57,26 +59,39 @@ public: explicit VsyncConfiguration(Fps currentFps); // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate. VsyncConfigSet getConfigsForRefreshRate(Fps fps) const override; VsyncConfigSet getConfigsForRefreshRate(Fps fps) const override EXCLUDES(mLock); // Returns early, early GL, and late offsets for Apps and SF. VsyncConfigSet getCurrentConfigs() const override { return getConfigsForRefreshRate(mRefreshRateFps); VsyncConfigSet getCurrentConfigs() const override EXCLUDES(mLock) { std::lock_guard lock(mLock); return getConfigsForRefreshRateLocked(mRefreshRateFps); } // Cleans the internal cache. void reset() override EXCLUDES(mLock) { std::lock_guard lock(mLock); mOffsetsCache.clear(); } // This function should be called when the device is switching between different // refresh rates, to properly update the offsets. void setRefreshRateFps(Fps fps) override { mRefreshRateFps = fps; } void setRefreshRateFps(Fps fps) override EXCLUDES(mLock) { std::lock_guard lock(mLock); mRefreshRateFps = fps; } // Returns current offsets in human friendly format. void dump(std::string& result) const override; protected: void initializeOffsets(const std::vector<Fps>& refreshRates); virtual VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const = 0; std::unordered_map<Fps, VsyncConfigSet, std::hash<Fps>, Fps::EqualsInBuckets> mOffsets; std::atomic<Fps> mRefreshRateFps; VsyncConfigSet getConfigsForRefreshRateLocked(Fps fps) const REQUIRES(mLock); mutable std::unordered_map<Fps, VsyncConfigSet, std::hash<Fps>, Fps::EqualsInBuckets> mOffsetsCache GUARDED_BY(mLock); std::atomic<Fps> mRefreshRateFps GUARDED_BY(mLock); mutable std::mutex mLock; }; /* Loading @@ -85,13 +100,13 @@ protected: */ class PhaseOffsets : public VsyncConfiguration { public: explicit PhaseOffsets(const scheduler::RefreshRateConfigs&); explicit PhaseOffsets(Fps currentRefreshRate); protected: // Used for unit tests PhaseOffsets(const std::vector<Fps>& refreshRates, Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs, std::optional<nsecs_t> earlyAppOffsetNs, PhaseOffsets(Fps currentRefreshRate, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs, std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs, nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, Loading Loading @@ -128,13 +143,12 @@ private: */ class WorkDuration : public VsyncConfiguration { public: explicit WorkDuration(const scheduler::RefreshRateConfigs&); explicit WorkDuration(Fps currentRefrshRate); protected: // Used for unit tests WorkDuration(const std::vector<Fps>& refreshRates, Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration); WorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration); private: VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override; Loading services/surfaceflinger/SurfaceFlinger.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -2621,10 +2621,16 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, setPowerModeInternal(display, hal::PowerMode::ON); // TODO(b/175678251) Call a listener instead. if (currentState.physical->hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) { const auto displayId = currentState.physical->id; const auto configs = getHwComposer().getConfigs(displayId); mVsyncConfiguration->reset(); updatePhaseConfiguration(mRefreshRateConfigs->getCurrentRefreshRate()); if (mRefreshRateOverlay) { mRefreshRateOverlay->reset(); } } } return; } Loading Loading @@ -2918,7 +2924,7 @@ void SurfaceFlinger::initScheduler(PhysicalDisplayId primaryDisplayId) { std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate.getFps(), hal::PowerMode::OFF); mVsyncConfiguration = getFactory().createVsyncConfiguration(*mRefreshRateConfigs); mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate.getFps()); mVsyncModulator.emplace(mVsyncConfiguration->getCurrentConfigs()); // start the EventThread Loading services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -56,11 +56,11 @@ std::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() { } std::unique_ptr<scheduler::VsyncConfiguration> DefaultFactory::createVsyncConfiguration( const scheduler::RefreshRateConfigs& refreshRateConfigs) { Fps currentRefreshRate) { if (property_get_bool("debug.sf.use_phase_offsets_as_durations", false)) { return std::make_unique<scheduler::impl::WorkDuration>(refreshRateConfigs); return std::make_unique<scheduler::impl::WorkDuration>(currentRefreshRate); } else { return std::make_unique<scheduler::impl::PhaseOffsets>(refreshRateConfigs); return std::make_unique<scheduler::impl::PhaseOffsets>(currentRefreshRate); } } Loading services/surfaceflinger/SurfaceFlingerDefaultFactory.h +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ public: std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) override; std::unique_ptr<MessageQueue> createMessageQueue() override; std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration( const scheduler::RefreshRateConfigs&) override; Fps currentRefreshRate) override; std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&, ISchedulerCallback&) override; sp<SurfaceInterceptor> createSurfaceInterceptor() override; Loading Loading
services/surfaceflinger/Scheduler/VsyncConfiguration.cpp +36 −56 Original line number Diff line number Diff line Loading @@ -16,14 +16,19 @@ #include "VsyncConfiguration.h" #include <cutils/properties.h> #include <chrono> #include <cinttypes> #include <optional> #include <cutils/properties.h> #include <log/log.h> #include "SurfaceFlingerProperties.h" namespace { using namespace std::chrono_literals; std::optional<nsecs_t> getProperty(const char* name) { char value[PROPERTY_VALUE_MAX]; property_get(name, value, "-1"); Loading @@ -31,19 +36,6 @@ std::optional<nsecs_t> getProperty(const char* name) { return std::nullopt; } std::vector<android::Fps> getRefreshRatesFromConfigs( const android::scheduler::RefreshRateConfigs& refreshRateConfigs) { const auto& allRefreshRates = refreshRateConfigs.getAllRefreshRates(); std::vector<android::Fps> refreshRates; refreshRates.reserve(allRefreshRates.size()); for (const auto& [ignored, refreshRate] : allRefreshRates) { refreshRates.emplace_back(refreshRate->getFps()); } return refreshRates; } } // namespace namespace android::scheduler::impl { Loading @@ -51,25 +43,19 @@ namespace android::scheduler::impl { VsyncConfiguration::VsyncConfiguration(Fps currentFps) : mRefreshRateFps(currentFps) {} PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRate(Fps fps) const { const auto iter = std::find_if(mOffsets.begin(), mOffsets.end(), [&fps](const std::pair<Fps, VsyncConfigSet>& candidateFps) { return fps.equalsWithMargin(candidateFps.first); }); if (iter != mOffsets.end()) { return iter->second; std::lock_guard lock(mLock); return getConfigsForRefreshRateLocked(fps); } // Unknown refresh rate. This might happen if we get a hotplug event for an external display. // In this case just construct the offset. ALOGW("Can't find offset for %s", to_string(fps).c_str()); return constructOffsets(fps.getPeriodNsecs()); PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRateLocked(Fps fps) const { const auto iter = mOffsetsCache.find(fps); if (iter != mOffsetsCache.end()) { return iter->second; } void VsyncConfiguration::initializeOffsets(const std::vector<Fps>& refreshRates) { for (const auto fps : refreshRates) { mOffsets.emplace(fps, constructOffsets(fps.getPeriodNsecs())); } const auto offset = constructOffsets(fps.getPeriodNsecs()); mOffsetsCache[fps] = offset; return offset; } void VsyncConfiguration::dump(std::string& result) const { Loading Loading @@ -98,10 +84,8 @@ void VsyncConfiguration::dump(std::string& result) const { earlyGpu.appWorkDuration.count(), earlyGpu.sfWorkDuration.count()); } PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfigs) : PhaseOffsets(getRefreshRatesFromConfigs(refreshRateConfigs), refreshRateConfigs.getCurrentRefreshRate().getFps(), sysprop::vsync_event_phase_offset_ns(1000000), PhaseOffsets::PhaseOffsets(Fps currentRefreshRate) : PhaseOffsets(currentRefreshRate, sysprop::vsync_event_phase_offset_ns(1000000), sysprop::vsync_sf_event_phase_offset_ns(1000000), getProperty("debug.sf.early_phase_offset_ns"), getProperty("debug.sf.early_gl_phase_offset_ns"), Loading @@ -121,15 +105,17 @@ PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfi getProperty("debug.sf.phase_offset_threshold_for_next_vsync_ns") .value_or(std::numeric_limits<nsecs_t>::max())) {} PhaseOffsets::PhaseOffsets( const std::vector<Fps>& refreshRates, Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs, std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs, nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs, PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs, std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs, nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, std::optional<nsecs_t> highFpsEarlyAppOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync) std::optional<nsecs_t> highFpsEarlyGpuAppOffsetNs, nsecs_t thresholdForNextVsync) : VsyncConfiguration(currentFps), mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs), mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs), Loading @@ -143,9 +129,7 @@ PhaseOffsets::PhaseOffsets( mHighFpsEarlyGpuSfOffsetNs(highFpsEarlyGpuSfOffsetNs), mHighFpsEarlyAppOffsetNs(highFpsEarlyAppOffsetNs), mHighFpsEarlyGpuAppOffsetNs(highFpsEarlyGpuAppOffsetNs), mThresholdForNextVsync(thresholdForNextVsync) { initializeOffsets(refreshRates); } mThresholdForNextVsync(thresholdForNextVsync) {} PhaseOffsets::VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const { if (vsyncDuration < std::chrono::nanoseconds(15ms).count()) { Loading Loading @@ -361,10 +345,8 @@ WorkDuration::VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuratio }; } WorkDuration::WorkDuration(const scheduler::RefreshRateConfigs& refreshRateConfigs) : WorkDuration(getRefreshRatesFromConfigs(refreshRateConfigs), refreshRateConfigs.getCurrentRefreshRate().getFps(), getProperty("debug.sf.late.sf.duration").value_or(-1), WorkDuration::WorkDuration(Fps currentRefreshRate) : WorkDuration(currentRefreshRate, getProperty("debug.sf.late.sf.duration").value_or(-1), getProperty("debug.sf.late.app.duration").value_or(-1), getProperty("debug.sf.early.sf.duration").value_or(mSfDuration), getProperty("debug.sf.early.app.duration").value_or(mAppDuration), Loading @@ -373,17 +355,15 @@ WorkDuration::WorkDuration(const scheduler::RefreshRateConfigs& refreshRateConfi validateSysprops(); } WorkDuration::WorkDuration(const std::vector<Fps>& refreshRates, Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, WorkDuration::WorkDuration(Fps currentRefreshRate, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration) : VsyncConfiguration(currentFps), : VsyncConfiguration(currentRefreshRate), mSfDuration(sfDuration), mAppDuration(appDuration), mSfEarlyDuration(sfEarlyDuration), mAppEarlyDuration(appEarlyDuration), mSfEarlyGpuDuration(sfEarlyGpuDuration), mAppEarlyGpuDuration(appEarlyGpuDuration) { initializeOffsets(refreshRates); } mAppEarlyGpuDuration(appEarlyGpuDuration) {} } // namespace android::scheduler::impl
services/surfaceflinger/Scheduler/VsyncConfiguration.h +31 −17 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ #pragma once #include <mutex> #include <type_traits> #include <unordered_map> #include <vector> #include <utils/Timers.h> #include "Fps.h" #include "RefreshRateConfigs.h" #include "VsyncModulator.h" namespace android::scheduler { Loading @@ -39,9 +41,9 @@ public: virtual ~VsyncConfiguration() = default; virtual VsyncConfigSet getCurrentConfigs() const = 0; virtual VsyncConfigSet getConfigsForRefreshRate(Fps fps) const = 0; virtual void reset() = 0; virtual void setRefreshRateFps(Fps fps) = 0; virtual void dump(std::string& result) const = 0; }; Loading @@ -57,26 +59,39 @@ public: explicit VsyncConfiguration(Fps currentFps); // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate. VsyncConfigSet getConfigsForRefreshRate(Fps fps) const override; VsyncConfigSet getConfigsForRefreshRate(Fps fps) const override EXCLUDES(mLock); // Returns early, early GL, and late offsets for Apps and SF. VsyncConfigSet getCurrentConfigs() const override { return getConfigsForRefreshRate(mRefreshRateFps); VsyncConfigSet getCurrentConfigs() const override EXCLUDES(mLock) { std::lock_guard lock(mLock); return getConfigsForRefreshRateLocked(mRefreshRateFps); } // Cleans the internal cache. void reset() override EXCLUDES(mLock) { std::lock_guard lock(mLock); mOffsetsCache.clear(); } // This function should be called when the device is switching between different // refresh rates, to properly update the offsets. void setRefreshRateFps(Fps fps) override { mRefreshRateFps = fps; } void setRefreshRateFps(Fps fps) override EXCLUDES(mLock) { std::lock_guard lock(mLock); mRefreshRateFps = fps; } // Returns current offsets in human friendly format. void dump(std::string& result) const override; protected: void initializeOffsets(const std::vector<Fps>& refreshRates); virtual VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const = 0; std::unordered_map<Fps, VsyncConfigSet, std::hash<Fps>, Fps::EqualsInBuckets> mOffsets; std::atomic<Fps> mRefreshRateFps; VsyncConfigSet getConfigsForRefreshRateLocked(Fps fps) const REQUIRES(mLock); mutable std::unordered_map<Fps, VsyncConfigSet, std::hash<Fps>, Fps::EqualsInBuckets> mOffsetsCache GUARDED_BY(mLock); std::atomic<Fps> mRefreshRateFps GUARDED_BY(mLock); mutable std::mutex mLock; }; /* Loading @@ -85,13 +100,13 @@ protected: */ class PhaseOffsets : public VsyncConfiguration { public: explicit PhaseOffsets(const scheduler::RefreshRateConfigs&); explicit PhaseOffsets(Fps currentRefreshRate); protected: // Used for unit tests PhaseOffsets(const std::vector<Fps>& refreshRates, Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs, std::optional<nsecs_t> earlyAppOffsetNs, PhaseOffsets(Fps currentRefreshRate, nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs, std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGpuSfOffsetNs, std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGpuAppOffsetNs, nsecs_t highFpsVsyncPhaseOffsetNs, nsecs_t highFpsSfVSyncPhaseOffsetNs, std::optional<nsecs_t> highFpsEarlySfOffsetNs, std::optional<nsecs_t> highFpsEarlyGpuSfOffsetNs, Loading Loading @@ -128,13 +143,12 @@ private: */ class WorkDuration : public VsyncConfiguration { public: explicit WorkDuration(const scheduler::RefreshRateConfigs&); explicit WorkDuration(Fps currentRefrshRate); protected: // Used for unit tests WorkDuration(const std::vector<Fps>& refreshRates, Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration); WorkDuration(Fps currentFps, nsecs_t sfDuration, nsecs_t appDuration, nsecs_t sfEarlyDuration, nsecs_t appEarlyDuration, nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration); private: VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override; Loading
services/surfaceflinger/SurfaceFlinger.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -2621,10 +2621,16 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, setPowerModeInternal(display, hal::PowerMode::ON); // TODO(b/175678251) Call a listener instead. if (currentState.physical->hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) { const auto displayId = currentState.physical->id; const auto configs = getHwComposer().getConfigs(displayId); mVsyncConfiguration->reset(); updatePhaseConfiguration(mRefreshRateConfigs->getCurrentRefreshRate()); if (mRefreshRateOverlay) { mRefreshRateOverlay->reset(); } } } return; } Loading Loading @@ -2918,7 +2924,7 @@ void SurfaceFlinger::initScheduler(PhysicalDisplayId primaryDisplayId) { std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate.getFps(), hal::PowerMode::OFF); mVsyncConfiguration = getFactory().createVsyncConfiguration(*mRefreshRateConfigs); mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate.getFps()); mVsyncModulator.emplace(mVsyncConfiguration->getCurrentConfigs()); // start the EventThread Loading
services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -56,11 +56,11 @@ std::unique_ptr<MessageQueue> DefaultFactory::createMessageQueue() { } std::unique_ptr<scheduler::VsyncConfiguration> DefaultFactory::createVsyncConfiguration( const scheduler::RefreshRateConfigs& refreshRateConfigs) { Fps currentRefreshRate) { if (property_get_bool("debug.sf.use_phase_offsets_as_durations", false)) { return std::make_unique<scheduler::impl::WorkDuration>(refreshRateConfigs); return std::make_unique<scheduler::impl::WorkDuration>(currentRefreshRate); } else { return std::make_unique<scheduler::impl::PhaseOffsets>(refreshRateConfigs); return std::make_unique<scheduler::impl::PhaseOffsets>(currentRefreshRate); } } Loading
services/surfaceflinger/SurfaceFlingerDefaultFactory.h +1 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,7 @@ public: std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) override; std::unique_ptr<MessageQueue> createMessageQueue() override; std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration( const scheduler::RefreshRateConfigs&) override; Fps currentRefreshRate) override; std::unique_ptr<Scheduler> createScheduler(const scheduler::RefreshRateConfigs&, ISchedulerCallback&) override; sp<SurfaceInterceptor> createSurfaceInterceptor() override; Loading