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

Commit 2fc37691 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "goldfish_ignore_present_fences"

* changes:
  SurfaceFlinger: add a sysprop to ignore present fences
  SurfaceFlinger: expose duration as part of phase offsets
parents 8432ef1d ce139ad4
Loading
Loading
Loading
Loading
+246 −209

File changed.

Preview size limit exceeded, changes collapsed.

+63 −53
Original line number Diff line number Diff line
@@ -24,19 +24,18 @@
namespace android::scheduler {

/*
 * This class encapsulates offsets for different refresh rates. Depending
 * This class encapsulates vsync configurations 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 {
class VsyncConfiguration {
public:
    using Offsets = VsyncModulator::OffsetsConfig;
    using VsyncConfigSet = VsyncModulator::VsyncConfigSet;

    virtual ~PhaseConfiguration();

    virtual Offsets getCurrentOffsets() const = 0;
    virtual Offsets getOffsetsForRefreshRate(float fps) const = 0;
    virtual ~VsyncConfiguration() = default;
    virtual VsyncConfigSet getCurrentConfigs() const = 0;
    virtual VsyncConfigSet getConfigsForRefreshRate(float fps) const = 0;

    virtual void setRefreshRateFps(float fps) = 0;

@@ -46,18 +45,21 @@ public:
namespace impl {

/*
 * This is the old implementation of phase offsets and considered as deprecated.
 * PhaseDurations is the new implementation.
 * This is a common implementation for both phase offsets and durations.
 * PhaseOffsets and WorkDuration derive from this class and implement the
 * constructOffsets method
 */
class PhaseOffsets : public scheduler::PhaseConfiguration {
class VsyncConfiguration : public scheduler::VsyncConfiguration {
public:
    PhaseOffsets(const scheduler::RefreshRateConfigs&);
    explicit VsyncConfiguration(float currentFps);

    // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
    Offsets getOffsetsForRefreshRate(float fps) const override;
    VsyncConfigSet getConfigsForRefreshRate(float fps) const override;

    // Returns early, early GL, and late offsets for Apps and SF.
    Offsets getCurrentOffsets() const override { return getOffsetsForRefreshRate(mRefreshRateFps); }
    VsyncConfigSet getCurrentConfigs() const override {
        return getConfigsForRefreshRate(mRefreshRateFps);
    }

    // This function should be called when the device is switching between different
    // refresh rates, to properly update the offsets.
@@ -66,62 +68,74 @@ public:
    // Returns current offsets in human friendly format.
    void dump(std::string& result) const override;

protected:
    void initializeOffsets(const std::vector<float>& refreshRates);
    virtual VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const = 0;

    std::unordered_map<float, VsyncConfigSet> mOffsets;
    std::atomic<float> mRefreshRateFps;
};

/*
 * This is the old implementation of phase offsets and considered as deprecated.
 * WorkDuration is the new implementation.
 */
class PhaseOffsets : public VsyncConfiguration {
public:
    explicit PhaseOffsets(const scheduler::RefreshRateConfigs&);

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;
                 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);

private:
    VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;

    VsyncConfigSet getDefaultOffsets(nsecs_t vsyncPeriod) const;
    VsyncConfigSet getHighFpsOffsets(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> mEarlyGpuSfOffsetNs;
    const std::optional<nsecs_t> mEarlyAppOffsetNs;
    const std::optional<nsecs_t> mEarlyGlAppOffsetNs;
    const nsecs_t mThresholdForNextVsync;
    const std::unordered_map<float, Offsets> mOffsets;
    const std::optional<nsecs_t> mEarlyGpuAppOffsetNs;

    std::atomic<float> mRefreshRateFps;
    const nsecs_t mHighFpsVSyncPhaseOffsetNs;
    const nsecs_t mHighFpsSfVSyncPhaseOffsetNs;
    const std::optional<nsecs_t> mHighFpsEarlySfOffsetNs;
    const std::optional<nsecs_t> mHighFpsEarlyGpuSfOffsetNs;
    const std::optional<nsecs_t> mHighFpsEarlyAppOffsetNs;
    const std::optional<nsecs_t> mHighFpsEarlyGpuAppOffsetNs;

    const nsecs_t mThresholdForNextVsync;
};

/*
 * Class that encapsulates the phase offsets for SurfaceFlinger and App.
 * The offsets are calculated from durations for each one of the (late, early, earlyGL)
 * The offsets are calculated from durations for each one of the (late, early, earlyGpu)
 * offset types.
 */
class PhaseDurations : public scheduler::PhaseConfiguration {
class WorkDuration : public VsyncConfiguration {
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;
    explicit WorkDuration(const scheduler::RefreshRateConfigs&);

protected:
    // Used for unit tests
    PhaseDurations(const std::vector<float>& refreshRates, float currentFps, nsecs_t sfDuration,
    WorkDuration(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);
                 nsecs_t sfEarlyGpuDuration, nsecs_t appEarlyGpuDuration);

private:
    std::unordered_map<float, Offsets> initializeOffsets(const std::vector<float>&) const;
    PhaseDurations::Offsets constructOffsets(nsecs_t vsyncDuration) const;
    VsyncConfiguration::VsyncConfigSet constructOffsets(nsecs_t vsyncDuration) const override;

    const nsecs_t mSfDuration;
    const nsecs_t mAppDuration;
@@ -129,12 +143,8 @@ private:
    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;
    const nsecs_t mSfEarlyGpuDuration;
    const nsecs_t mAppEarlyGpuDuration;
};

} // namespace impl
+30 −29
Original line number Diff line number Diff line
@@ -35,18 +35,19 @@ namespace android::scheduler {

const std::chrono::nanoseconds VsyncModulator::MIN_EARLY_TRANSACTION_TIME = 1ms;

VsyncModulator::VsyncModulator(const OffsetsConfig& config, Now now)
      : mOffsetsConfig(config),
VsyncModulator::VsyncModulator(const VsyncConfigSet& config, Now now)
      : mVsyncConfigSet(config),
        mNow(now),
        mTraceDetailedInfo(base::GetBoolProperty("debug.sf.vsync_trace_detailed_info", false)) {}

VsyncModulator::Offsets VsyncModulator::setPhaseOffsets(const OffsetsConfig& config) {
VsyncModulator::VsyncConfig VsyncModulator::setVsyncConfigSet(const VsyncConfigSet& config) {
    std::lock_guard<std::mutex> lock(mMutex);
    mOffsetsConfig = config;
    return updateOffsetsLocked();
    mVsyncConfigSet = config;
    return updateVsyncConfigLocked();
}

VsyncModulator::OffsetsOpt VsyncModulator::setTransactionSchedule(TransactionSchedule schedule) {
VsyncModulator::VsyncConfigOpt VsyncModulator::setTransactionSchedule(
        TransactionSchedule schedule) {
    switch (schedule) {
        case Schedule::EarlyStart:
            ALOGW_IF(mExplicitEarlyWakeup, "%s: Duplicate EarlyStart", __FUNCTION__);
@@ -76,29 +77,29 @@ VsyncModulator::OffsetsOpt VsyncModulator::setTransactionSchedule(TransactionSch
        return std::nullopt;
    }
    mTransactionSchedule = schedule;
    return updateOffsets();
    return updateVsyncConfig();
}

VsyncModulator::OffsetsOpt VsyncModulator::onTransactionCommit() {
VsyncModulator::VsyncConfigOpt VsyncModulator::onTransactionCommit() {
    mLastTransactionCommitTime = mNow();
    if (mTransactionSchedule == Schedule::Late) return std::nullopt;
    mTransactionSchedule = Schedule::Late;
    return updateOffsets();
    return updateVsyncConfig();
}

VsyncModulator::OffsetsOpt VsyncModulator::onRefreshRateChangeInitiated() {
VsyncModulator::VsyncConfigOpt VsyncModulator::onRefreshRateChangeInitiated() {
    if (mRefreshRateChangePending) return std::nullopt;
    mRefreshRateChangePending = true;
    return updateOffsets();
    return updateVsyncConfig();
}

VsyncModulator::OffsetsOpt VsyncModulator::onRefreshRateChangeCompleted() {
VsyncModulator::VsyncConfigOpt VsyncModulator::onRefreshRateChangeCompleted() {
    if (!mRefreshRateChangePending) return std::nullopt;
    mRefreshRateChangePending = false;
    return updateOffsets();
    return updateVsyncConfig();
}

VsyncModulator::OffsetsOpt VsyncModulator::onDisplayRefresh(bool usedGpuComposition) {
VsyncModulator::VsyncConfigOpt VsyncModulator::onDisplayRefresh(bool usedGpuComposition) {
    bool updateOffsetsNeeded = false;

    if (mEarlyTransactionStartTime.load() + MIN_EARLY_TRANSACTION_TIME <=
@@ -117,40 +118,40 @@ VsyncModulator::OffsetsOpt VsyncModulator::onDisplayRefresh(bool usedGpuComposit
    }

    if (!updateOffsetsNeeded) return std::nullopt;
    return updateOffsets();
    return updateVsyncConfig();
}

VsyncModulator::Offsets VsyncModulator::getOffsets() const {
VsyncModulator::VsyncConfig VsyncModulator::getVsyncConfig() const {
    std::lock_guard<std::mutex> lock(mMutex);
    return mOffsets;
    return mVsyncConfig;
}

const VsyncModulator::Offsets& VsyncModulator::getNextOffsets() const {
const VsyncModulator::VsyncConfig& VsyncModulator::getNextVsyncConfig() const {
    // Early offsets are used if we're in the middle of a refresh rate
    // change, or if we recently begin a transaction.
    if (mExplicitEarlyWakeup || mTransactionSchedule == Schedule::EarlyEnd ||
        mEarlyTransactionFrames > 0 || mRefreshRateChangePending) {
        return mOffsetsConfig.early;
        return mVsyncConfigSet.early;
    } else if (mEarlyGpuFrames > 0) {
        return mOffsetsConfig.earlyGpu;
        return mVsyncConfigSet.earlyGpu;
    } else {
        return mOffsetsConfig.late;
        return mVsyncConfigSet.late;
    }
}

VsyncModulator::Offsets VsyncModulator::updateOffsets() {
VsyncModulator::VsyncConfig VsyncModulator::updateVsyncConfig() {
    std::lock_guard<std::mutex> lock(mMutex);
    return updateOffsetsLocked();
    return updateVsyncConfigLocked();
}

VsyncModulator::Offsets VsyncModulator::updateOffsetsLocked() {
    const Offsets& offsets = getNextOffsets();
    mOffsets = offsets;
VsyncModulator::VsyncConfig VsyncModulator::updateVsyncConfigLocked() {
    const VsyncConfig& offsets = getNextVsyncConfig();
    mVsyncConfig = offsets;

    if (mTraceDetailedInfo) {
        const bool isEarly = &offsets == &mOffsetsConfig.early;
        const bool isEarlyGpu = &offsets == &mOffsetsConfig.earlyGpu;
        const bool isLate = &offsets == &mOffsetsConfig.late;
        const bool isEarly = &offsets == &mVsyncConfigSet.early;
        const bool isEarlyGpu = &offsets == &mVsyncConfigSet.earlyGpu;
        const bool isLate = &offsets == &mVsyncConfigSet.late;

        ATRACE_INT("Vsync-EarlyOffsetsOn", isEarly);
        ATRACE_INT("Vsync-EarlyGpuOffsetsOn", isEarlyGpu);
+33 −26
Original line number Diff line number Diff line
@@ -48,62 +48,69 @@ public:
    // This may keep early offsets for an extra frame, but avoids a race with transaction commit.
    static const std::chrono::nanoseconds MIN_EARLY_TRANSACTION_TIME;

    // Phase offsets for SF and app deadlines from VSYNC.
    struct Offsets {
        nsecs_t sf;
        nsecs_t app;
    // Phase offsets and work durations for SF and app deadlines from VSYNC.
    struct VsyncConfig {
        nsecs_t sfOffset;
        nsecs_t appOffset;
        std::chrono::nanoseconds sfWorkDuration;
        std::chrono::nanoseconds appWorkDuration;

        bool operator==(const VsyncConfig& other) const {
            return sfOffset == other.sfOffset && appOffset == other.appOffset &&
                    sfWorkDuration == other.sfWorkDuration &&
                    appWorkDuration == other.appWorkDuration;
        }

        bool operator==(const Offsets& other) const { return sf == other.sf && app == other.app; }
        bool operator!=(const Offsets& other) const { return !(*this == other); }
        bool operator!=(const VsyncConfig& other) const { return !(*this == other); }
    };

    using OffsetsOpt = std::optional<Offsets>;
    using VsyncConfigOpt = std::optional<VsyncConfig>;

    struct OffsetsConfig {
        Offsets early;    // Used for early transactions, and during refresh rate change.
        Offsets earlyGpu; // Used during GPU composition.
        Offsets late;     // Default.
    struct VsyncConfigSet {
        VsyncConfig early;    // Used for early transactions, and during refresh rate change.
        VsyncConfig earlyGpu; // Used during GPU composition.
        VsyncConfig late;     // Default.

        bool operator==(const OffsetsConfig& other) const {
        bool operator==(const VsyncConfigSet& other) const {
            return early == other.early && earlyGpu == other.earlyGpu && late == other.late;
        }

        bool operator!=(const OffsetsConfig& other) const { return !(*this == other); }
        bool operator!=(const VsyncConfigSet& other) const { return !(*this == other); }
    };

    using Clock = std::chrono::steady_clock;
    using TimePoint = Clock::time_point;
    using Now = TimePoint (*)();

    explicit VsyncModulator(const OffsetsConfig&, Now = Clock::now);
    explicit VsyncModulator(const VsyncConfigSet&, Now = Clock::now);

    Offsets getOffsets() const EXCLUDES(mMutex);
    VsyncConfig getVsyncConfig() const EXCLUDES(mMutex);

    [[nodiscard]] Offsets setPhaseOffsets(const OffsetsConfig&) EXCLUDES(mMutex);
    [[nodiscard]] VsyncConfig setVsyncConfigSet(const VsyncConfigSet&) EXCLUDES(mMutex);

    // Changes offsets in response to transaction flags or commit.
    [[nodiscard]] OffsetsOpt setTransactionSchedule(TransactionSchedule);
    [[nodiscard]] OffsetsOpt onTransactionCommit();
    [[nodiscard]] VsyncConfigOpt setTransactionSchedule(TransactionSchedule);
    [[nodiscard]] VsyncConfigOpt onTransactionCommit();

    // Called when we send a refresh rate change to hardware composer, so that
    // we can move into early offsets.
    [[nodiscard]] OffsetsOpt onRefreshRateChangeInitiated();
    [[nodiscard]] VsyncConfigOpt onRefreshRateChangeInitiated();

    // Called when we detect from VSYNC signals that the refresh rate changed.
    // This way we can move out of early offsets if no longer necessary.
    [[nodiscard]] OffsetsOpt onRefreshRateChangeCompleted();
    [[nodiscard]] VsyncConfigOpt onRefreshRateChangeCompleted();

    [[nodiscard]] OffsetsOpt onDisplayRefresh(bool usedGpuComposition);
    [[nodiscard]] VsyncConfigOpt onDisplayRefresh(bool usedGpuComposition);

private:
    const Offsets& getNextOffsets() const REQUIRES(mMutex);
    [[nodiscard]] Offsets updateOffsets() EXCLUDES(mMutex);
    [[nodiscard]] Offsets updateOffsetsLocked() REQUIRES(mMutex);
    const VsyncConfig& getNextVsyncConfig() const REQUIRES(mMutex);
    [[nodiscard]] VsyncConfig updateVsyncConfig() EXCLUDES(mMutex);
    [[nodiscard]] VsyncConfig updateVsyncConfigLocked() REQUIRES(mMutex);

    mutable std::mutex mMutex;
    OffsetsConfig mOffsetsConfig GUARDED_BY(mMutex);
    VsyncConfigSet mVsyncConfigSet GUARDED_BY(mMutex);

    Offsets mOffsets GUARDED_BY(mMutex){mOffsetsConfig.late};
    VsyncConfig mVsyncConfig GUARDED_BY(mMutex){mVsyncConfigSet.late};

    using Schedule = TransactionSchedule;
    std::atomic<Schedule> mTransactionSchedule = Schedule::Late;
+30 −21
Original line number Diff line number Diff line
@@ -948,9 +948,10 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken,
        const nsecs_t period = hwConfig->getVsyncPeriod();
        config.refreshRate = 1e9f / period;

        const auto offsets = mPhaseConfiguration->getOffsetsForRefreshRate(config.refreshRate);
        config.appVsyncOffset = offsets.late.app;
        config.sfVsyncOffset = offsets.late.sf;
        const auto vsyncConfigSet =
                mVsyncConfiguration->getConfigsForRefreshRate(config.refreshRate);
        config.appVsyncOffset = vsyncConfigSet.late.appOffset;
        config.sfVsyncOffset = vsyncConfigSet.late.sfOffset;
        config.configGroup = hwConfig->getConfigGroup();

        // This is how far in advance a buffer must be queued for
@@ -1789,7 +1790,7 @@ sp<Fence> SurfaceFlinger::previousFrameFence() {
    // We are storing the last 2 present fences. If sf's phase offset is to be
    // woken up before the actual vsync but targeting the next vsync, we need to check
    // fence N-2
    return mVsyncModulator->getOffsets().sf > 0 ? mPreviousPresentFences[0]
    return mVsyncModulator->getVsyncConfig().sfOffset > 0 ? mPreviousPresentFences[0]
                                                          : mPreviousPresentFences[1];
}

@@ -1822,7 +1823,8 @@ nsecs_t SurfaceFlinger::calculateExpectedPresentTime(nsecs_t now) const {
    mScheduler->getDisplayStatInfo(&stats);
    const nsecs_t presentTime = mScheduler->getDispSyncExpectedPresentTime(now);
    // Inflate the expected present time if we're targetting the next vsync.
    return mVsyncModulator->getOffsets().sf > 0 ? presentTime : presentTime + stats.vsyncPeriod;
    return mVsyncModulator->getVsyncConfig().sfOffset > 0 ? presentTime
                                                          : presentTime + stats.vsyncPeriod;
}

void SurfaceFlinger::onMessageReceived(int32_t what, nsecs_t expectedVSyncTime) {
@@ -2182,12 +2184,12 @@ void SurfaceFlinger::setCompositorTimingSnapped(const DisplayStatInfo& stats,
                                                nsecs_t compositeToPresentLatency) {
    // Integer division and modulo round toward 0 not -inf, so we need to
    // treat negative and positive offsets differently.
    nsecs_t idealLatency = (mPhaseConfiguration->getCurrentOffsets().late.sf > 0)
    nsecs_t idealLatency = (mVsyncConfiguration->getCurrentConfigs().late.sfOffset > 0)
            ? (stats.vsyncPeriod -
               (mPhaseConfiguration->getCurrentOffsets().late.sf % stats.vsyncPeriod))
            : ((-mPhaseConfiguration->getCurrentOffsets().late.sf) % stats.vsyncPeriod);
               (mVsyncConfiguration->getCurrentConfigs().late.sfOffset % stats.vsyncPeriod))
            : ((-mVsyncConfiguration->getCurrentConfigs().late.sfOffset) % stats.vsyncPeriod);

    // Just in case mPhaseConfiguration->getCurrentOffsets().late.sf == -vsyncInterval.
    // Just in case mVsyncConfiguration->getCurrentConfigs().late.sf == -vsyncInterval.
    if (idealLatency <= 0) {
        idealLatency = stats.vsyncPeriod;
    }
@@ -2197,7 +2199,7 @@ void SurfaceFlinger::setCompositorTimingSnapped(const DisplayStatInfo& stats,
    // Reducing jitter is important if an app attempts to extrapolate
    // something (such as user input) to an accurate diasplay time.
    // Snapping also allows an app to precisely calculate
    // mPhaseConfiguration->getCurrentOffsets().late.sf with (presentLatency % interval).
    // mVsyncConfiguration->getCurrentConfigs().late.sf with (presentLatency % interval).
    nsecs_t bias = stats.vsyncPeriod / 2;
    int64_t extraVsyncs = (compositeToPresentLatency - idealLatency + bias) / stats.vsyncPeriod;
    nsecs_t snappedCompositeToPresentLatency =
@@ -2977,16 +2979,18 @@ void SurfaceFlinger::initScheduler(PhysicalDisplayId primaryDisplayId) {
                                                          currentConfig, hal::PowerMode::OFF);
    mRefreshRateStats->setConfigMode(currentConfig);

    mPhaseConfiguration = getFactory().createPhaseConfiguration(*mRefreshRateConfigs);
    mVsyncModulator.emplace(mPhaseConfiguration->getCurrentOffsets());
    mVsyncConfiguration = getFactory().createVsyncConfiguration(*mRefreshRateConfigs);
    mVsyncModulator.emplace(mVsyncConfiguration->getCurrentConfigs());

    // start the EventThread
    mScheduler = getFactory().createScheduler(*mRefreshRateConfigs, *this);
    mAppConnectionHandle =
            mScheduler->createConnection("app", mPhaseConfiguration->getCurrentOffsets().late.app,
            mScheduler->createConnection("app",
                                         mVsyncConfiguration->getCurrentConfigs().late.appOffset,
                                         impl::EventThread::InterceptVSyncsCallback());
    mSfConnectionHandle =
            mScheduler->createConnection("sf", mPhaseConfiguration->getCurrentOffsets().late.sf,
            mScheduler->createConnection("sf",
                                         mVsyncConfiguration->getCurrentConfigs().late.sfOffset,
                                         [this](nsecs_t timestamp) {
                                             mInterceptor->saveVSyncEvent(timestamp);
                                         });
@@ -3007,16 +3011,21 @@ void SurfaceFlinger::initScheduler(PhysicalDisplayId primaryDisplayId) {
            mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig).getVsyncPeriod();
    mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, primaryDisplayId, currentConfig,
                                              vsyncPeriod);
    static auto ignorePresentFences =
            base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s, false);
    mScheduler->setIgnorePresentFences(
            ignorePresentFences ||
            getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE));
}

void SurfaceFlinger::updatePhaseConfiguration(const RefreshRate& refreshRate) {
    mPhaseConfiguration->setRefreshRateFps(refreshRate.getFps());
    setPhaseOffsets(mVsyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets()));
    mVsyncConfiguration->setRefreshRateFps(refreshRate.getFps());
    setVsyncConfig(mVsyncModulator->setVsyncConfigSet(mVsyncConfiguration->getCurrentConfigs()));
}

void SurfaceFlinger::setPhaseOffsets(const VsyncModulator::Offsets& offsets) {
    mScheduler->setPhaseOffset(mAppConnectionHandle, offsets.app);
    mScheduler->setPhaseOffset(mSfConnectionHandle, offsets.sf);
void SurfaceFlinger::setVsyncConfig(const VsyncModulator::VsyncConfig& config) {
    mScheduler->setPhaseOffset(mAppConnectionHandle, config.appOffset);
    mScheduler->setPhaseOffset(mSfConnectionHandle, config.sfOffset);
}

void SurfaceFlinger::commitTransaction() {
@@ -4456,7 +4465,7 @@ void SurfaceFlinger::dumpVSync(std::string& result) const {
    mRefreshRateStats->dump(result);
    result.append("\n");

    mPhaseConfiguration->dump(result);
    mVsyncConfiguration->dump(result);
    StringAppendF(&result,
                  "      present offset: %9" PRId64 " ns\t     VSYNC period: %9" PRId64 " ns\n\n",
                  dispSyncPresentTimeOffset, getVsyncPeriodFromHWC());
Loading