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

Commit 090d42c7 authored by Ady Abraham's avatar Ady Abraham Committed by Marin Shalamanov
Browse files

SurfaceFlinger: use margin when comparing fps in PhaseOffsets

To avoid any incorrect float equality due to precision errors
use 0.01Hz margin.

Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Bug: 147358911
Change-Id: Ief43eb7b5064b250a6255fd41542640d9c77529d
parent e950a4e1
Loading
Loading
Loading
Loading
+22 −7
Original line number Original line Diff line number Diff line
@@ -31,6 +31,11 @@ std::optional<nsecs_t> getProperty(const char* name) {
    return std::nullopt;
    return std::nullopt;
}
}


bool fpsEqualsWithMargin(float fpsA, float fpsB) {
    static constexpr float MARGIN = 0.01f;
    return std::abs(fpsA - fpsB) <= MARGIN;
}

} // namespace
} // namespace


namespace android::scheduler {
namespace android::scheduler {
@@ -61,16 +66,15 @@ void PhaseOffsets::dump(std::string& result) const {
                  mThresholdForNextVsync);
                  mThresholdForNextVsync);
}
}


std::unordered_map<float, PhaseDurations::Offsets> PhaseOffsets::initializeOffsets(
std::unordered_map<float, PhaseOffsets::Offsets> PhaseOffsets::initializeOffsets(
        const scheduler::RefreshRateConfigs& refreshRateConfigs) const {
        const scheduler::RefreshRateConfigs& refreshRateConfigs) const {
    std::unordered_map<float, PhaseDurations::Offsets> offsets;
    std::unordered_map<float, Offsets> offsets;


    for (const auto& [ignored, refreshRate] : refreshRateConfigs.getAllRefreshRates()) {
    for (const auto& [ignored, refreshRate] : refreshRateConfigs.getAllRefreshRates()) {
        const nsecs_t vsyncDuration = static_cast<nsecs_t>(1e9f / refreshRate.fps);
        if (refreshRate.fps > 65.0f) {
        if (refreshRate.fps > 65.0f) {
            offsets.emplace(refreshRate.fps, getHighFpsOffsets(vsyncDuration));
            offsets.emplace(refreshRate.fps, getHighFpsOffsets(refreshRate.vsyncPeriod));
        } else {
        } else {
            offsets.emplace(refreshRate.fps, getDefaultOffsets(vsyncDuration));
            offsets.emplace(refreshRate.fps, getDefaultOffsets(refreshRate.vsyncPeriod));
        }
        }
    }
    }
    return offsets;
    return offsets;
@@ -150,6 +154,15 @@ PhaseOffsets::Offsets PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDuration) con
    };
    };
}
}


PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate(float fps) const {
    const auto iter = std::find_if(mOffsets.begin(), mOffsets.end(),
                                   [&fps](const std::pair<float, Offsets>& candidateFps) {
                                       return fpsEqualsWithMargin(fps, candidateFps.first);
                                   });
    LOG_ALWAYS_FATAL_IF(iter == mOffsets.end());
    return iter->second;
}

static void validateSysprops() {
static void validateSysprops() {
    const auto validatePropertyBool = [](const char* prop) {
    const auto validatePropertyBool = [](const char* prop) {
        LOG_ALWAYS_FATAL_IF(!property_get_bool(prop, false), "%s is false", prop);
        LOG_ALWAYS_FATAL_IF(!property_get_bool(prop, false), "%s is false", prop);
@@ -207,7 +220,7 @@ static std::vector<float> getRefreshRatesFromConfigs(


std::unordered_map<float, PhaseDurations::Offsets> PhaseDurations::initializeOffsets(
std::unordered_map<float, PhaseDurations::Offsets> PhaseDurations::initializeOffsets(
        const std::vector<float>& refreshRates) const {
        const std::vector<float>& refreshRates) const {
    std::unordered_map<float, PhaseDurations::Offsets> offsets;
    std::unordered_map<float, Offsets> offsets;


    for (const auto fps : refreshRates) {
    for (const auto fps : refreshRates) {
        const nsecs_t vsyncDuration = static_cast<nsecs_t>(1e9f / fps);
        const nsecs_t vsyncDuration = static_cast<nsecs_t>(1e9f / fps);
@@ -275,7 +288,9 @@ PhaseDurations::PhaseDurations(const std::vector<float>& refreshRates, float cur
        mRefreshRateFps(currentFps) {}
        mRefreshRateFps(currentFps) {}


PhaseOffsets::Offsets PhaseDurations::getOffsetsForRefreshRate(float fps) const {
PhaseOffsets::Offsets PhaseDurations::getOffsetsForRefreshRate(float fps) const {
    const auto iter = mOffsets.find(fps);
    const auto iter = std::find_if(mOffsets.begin(), mOffsets.end(), [=](const auto& candidateFps) {
        return fpsEqualsWithMargin(fps, candidateFps.first);
    });
    LOG_ALWAYS_FATAL_IF(iter == mOffsets.end());
    LOG_ALWAYS_FATAL_IF(iter == mOffsets.end());
    return iter->second;
    return iter->second;
}
}
+3 −8
Original line number Original line Diff line number Diff line
@@ -54,11 +54,7 @@ public:
    PhaseOffsets(const scheduler::RefreshRateConfigs&);
    PhaseOffsets(const scheduler::RefreshRateConfigs&);


    // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
    // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
    Offsets getOffsetsForRefreshRate(float fps) const override {
    Offsets getOffsetsForRefreshRate(float fps) const override;
        const auto iter = mOffsets.find(fps);
        LOG_ALWAYS_FATAL_IF(iter == mOffsets.end());
        return iter->second;
    }


    // Returns early, early GL, and late offsets for Apps and SF.
    // Returns early, early GL, and late offsets for Apps and SF.
    Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateFps); }
    Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateFps); }
@@ -71,7 +67,7 @@ public:
    void dump(std::string& result) const override;
    void dump(std::string& result) const override;


private:
private:
    std::unordered_map<float, PhaseOffsets::Offsets> initializeOffsets(
    std::unordered_map<float, Offsets> initializeOffsets(
            const scheduler::RefreshRateConfigs&) const;
            const scheduler::RefreshRateConfigs&) const;
    Offsets getDefaultOffsets(nsecs_t vsyncDuration) const;
    Offsets getDefaultOffsets(nsecs_t vsyncDuration) const;
    Offsets getHighFpsOffsets(nsecs_t vsyncDuration) const;
    Offsets getHighFpsOffsets(nsecs_t vsyncDuration) const;
@@ -111,8 +107,7 @@ protected:
                   nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration);
                   nsecs_t sfEarlyGlDuration, nsecs_t appEarlyGlDuration);


private:
private:
    std::unordered_map<float, PhaseDurations::Offsets> initializeOffsets(
    std::unordered_map<float, Offsets> initializeOffsets(const std::vector<float>&) const;
            const std::vector<float>&) const;


    const nsecs_t mSfDuration;
    const nsecs_t mSfDuration;
    const nsecs_t mAppDuration;
    const nsecs_t mAppDuration;