Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8594399d authored by Marin Shalamanov's avatar Marin Shalamanov Committed by Android (Google) Code Review
Browse files

Merge "SF: Break dependency between VsyncConfiguration and RefreshRateConfigs"

parents ab27902f 526c3389
Loading
Loading
Loading
Loading
+36 −56
Original line number Diff line number Diff line
@@ -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");
@@ -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 {
@@ -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 {
@@ -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"),
@@ -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),
@@ -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()) {
@@ -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),
@@ -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
+31 −17
Original line number Diff line number Diff line
@@ -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 {
@@ -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;
};

@@ -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;
};

/*
@@ -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,
@@ -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;
+9 −3
Original line number Diff line number Diff line
@@ -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;
    }

@@ -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
+3 −3
Original line number Diff line number Diff line
@@ -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);
    }
}

+1 −1
Original line number Diff line number Diff line
@@ -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