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

Commit 45622511 authored by Leon Scroggins's avatar Leon Scroggins Committed by Android (Google) Code Review
Browse files

Merge "Move VsyncConfiguration from SF to Scheduler" into main

parents 7bc2ce3c 823d4ca5
Loading
Loading
Loading
Loading
+38 −8
Original line number Diff line number Diff line
@@ -51,8 +51,12 @@
#include "FrameRateOverrideMappings.h"
#include "FrontEnd/LayerHandle.h"
#include "OneShotTimer.h"
#include "RefreshRateStats.h"
#include "SurfaceFlingerFactory.h"
#include "SurfaceFlingerProperties.h"
#include "TimeStats/TimeStats.h"
#include "VSyncTracker.h"
#include "VsyncConfiguration.h"
#include "VsyncController.h"
#include "VsyncSchedule.h"

@@ -67,10 +71,14 @@
namespace android::scheduler {

Scheduler::Scheduler(ICompositor& compositor, ISchedulerCallback& callback, FeatureFlags features,
                     sp<VsyncModulator> modulatorPtr, IVsyncTrackerCallback& vsyncTrackerCallback)
      : impl::MessageQueue(compositor),
                     surfaceflinger::Factory& factory, Fps activeRefreshRate, TimeStats& timeStats,
                     IVsyncTrackerCallback& vsyncTrackerCallback)
      : android::impl::MessageQueue(compositor),
        mFeatures(features),
        mVsyncModulator(std::move(modulatorPtr)),
        mVsyncConfiguration(factory.createVsyncConfiguration(activeRefreshRate)),
        mVsyncModulator(sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs())),
        mRefreshRateStats(std::make_unique<RefreshRateStats>(timeStats, activeRefreshRate,
                                                             hal::PowerMode::OFF)),
        mSchedulerCallback(callback),
        mVsyncTrackerCallback(vsyncTrackerCallback) {}

@@ -307,7 +315,8 @@ ConnectionHandle Scheduler::createEventThread(Cycle cycle,
                                              frametimeline::TokenManager* tokenManager,
                                              std::chrono::nanoseconds workDuration,
                                              std::chrono::nanoseconds readyDuration) {
    auto eventThread = std::make_unique<impl::EventThread>(cycle == Cycle::Render ? "app" : "appSf",
    auto eventThread =
            std::make_unique<android::impl::EventThread>(cycle == Cycle::Render ? "app" : "appSf",
                                                         getVsyncSchedule(), tokenManager, *this,
                                                         workDuration, readyDuration);

@@ -495,8 +504,23 @@ void Scheduler::setDuration(ConnectionHandle handle, std::chrono::nanoseconds wo
    thread->setDuration(workDuration, readyDuration);
}

void Scheduler::setVsyncConfigSet(const VsyncConfigSet& configs, Period vsyncPeriod) {
    setVsyncConfig(mVsyncModulator->setVsyncConfigSet(configs), vsyncPeriod);
void Scheduler::updatePhaseConfiguration(Fps refreshRate) {
    mRefreshRateStats->setRefreshRate(refreshRate);
    mVsyncConfiguration->setRefreshRateFps(refreshRate);
    setVsyncConfig(mVsyncModulator->setVsyncConfigSet(mVsyncConfiguration->getCurrentConfigs()),
                   refreshRate.getPeriod());
}

void Scheduler::resetPhaseConfiguration(Fps refreshRate) {
    // Cancel the pending refresh rate change, if any, before updating the phase configuration.
    mVsyncModulator->cancelRefreshRateChange();

    mVsyncConfiguration->reset();
    updatePhaseConfiguration(refreshRate);
}

void Scheduler::setActiveDisplayPowerModeForRefreshRateStats(hal::PowerMode powerMode) {
    mRefreshRateStats->setPowerMode(powerMode);
}

void Scheduler::setVsyncConfig(const VsyncConfig& config, Period vsyncPeriod) {
@@ -869,6 +893,12 @@ void Scheduler::dump(utils::Dumper& dumper) const {
    mFrameRateOverrideMappings.dump(dumper);
    dumper.eol();

    mVsyncConfiguration->dump(dumper.out());
    dumper.eol();

    mRefreshRateStats->dump(dumper.out());
    dumper.eol();

    {
        utils::Dumper::Section section(dumper, "Frame Targeting"sv);

+22 −5
Original line number Diff line number Diff line
@@ -88,23 +88,30 @@ struct hash<android::scheduler::ConnectionHandle> {
namespace android {

class FenceTime;
class TimeStats;

namespace frametimeline {
class TokenManager;
} // namespace frametimeline

namespace surfaceflinger {
class Factory;
} // namespace surfaceflinger

namespace scheduler {

using GlobalSignals = RefreshRateSelector::GlobalSignals;

class RefreshRateStats;
class VsyncConfiguration;
class VsyncSchedule;

class Scheduler : public IEventThreadCallback, android::impl::MessageQueue {
    using Impl = android::impl::MessageQueue;

public:
    Scheduler(ICompositor&, ISchedulerCallback&, FeatureFlags, sp<VsyncModulator>,
              IVsyncTrackerCallback&);
    Scheduler(ICompositor&, ISchedulerCallback&, FeatureFlags, surfaceflinger::Factory&,
              Fps activeRefreshRate, TimeStats&, IVsyncTrackerCallback&);
    virtual ~Scheduler();

    void startTimers();
@@ -201,7 +208,10 @@ public:
        }
    }

    void setVsyncConfigSet(const VsyncConfigSet&, Period vsyncPeriod);
    void updatePhaseConfiguration(Fps);
    void resetPhaseConfiguration(Fps) REQUIRES(kMainThreadContext);

    const VsyncConfiguration& getVsyncConfiguration() const { return *mVsyncConfiguration; }

    // Sets the render rate for the scheduler to run at.
    void setRenderRate(PhysicalDisplayId, Fps);
@@ -249,8 +259,10 @@ public:
    // Indicates that touch interaction is taking place.
    void onTouchHint();

    void setDisplayPowerMode(PhysicalDisplayId, hal::PowerMode powerMode)
            REQUIRES(kMainThreadContext);
    void setDisplayPowerMode(PhysicalDisplayId, hal::PowerMode) REQUIRES(kMainThreadContext);

    // TODO(b/255635821): Track this per display.
    void setActiveDisplayPowerModeForRefreshRateStats(hal::PowerMode) REQUIRES(kMainThreadContext);

    ConstVsyncSchedulePtr getVsyncSchedule(std::optional<PhysicalDisplayId> = std::nullopt) const
            EXCLUDES(mDisplayLock);
@@ -464,9 +476,14 @@ private:

    const FeatureFlags mFeatures;

    // Stores phase offsets configured per refresh rate.
    const std::unique_ptr<VsyncConfiguration> mVsyncConfiguration;

    // Shifts the VSYNC phase during certain transactions and refresh rate changes.
    const sp<VsyncModulator> mVsyncModulator;

    const std::unique_ptr<RefreshRateStats> mRefreshRateStats;

    // Used to choose refresh rate if content detection is enabled.
    LayerHistory mLayerHistory;

+16 −40
Original line number Diff line number Diff line
@@ -1108,7 +1108,7 @@ void SurfaceFlinger::getDynamicDisplayInfoInternal(ui::DynamicDisplayInfo*& info
        outMode.peakRefreshRate = peakFps.getValue();
        outMode.vsyncRate = mode->getVsyncRate().getValue();

        const auto vsyncConfigSet = mVsyncConfiguration->getConfigsForRefreshRate(
        const auto vsyncConfigSet = mScheduler->getVsyncConfiguration().getConfigsForRefreshRate(
                Fps::fromValue(outMode.peakRefreshRate));
        outMode.appVsyncOffset = vsyncConfigSet.late.appOffset;
        outMode.sfVsyncOffset = vsyncConfigSet.late.sfOffset;
@@ -1267,7 +1267,7 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& request, bool
            mScheduler->modulateVsync(displayId, &VsyncModulator::onRefreshRateChangeInitiated);

            if (displayId == mActiveDisplayId) {
                updatePhaseConfiguration(mode.fps);
                mScheduler->updatePhaseConfiguration(mode.fps);
            }

            mScheduler->setModeChangePending(true);
@@ -1276,8 +1276,7 @@ void SurfaceFlinger::setDesiredMode(display::DisplayModeRequest&& request, bool
            mScheduler->setRenderRate(displayId, mode.fps);

            if (displayId == mActiveDisplayId) {
                updatePhaseConfiguration(mode.fps);
                mRefreshRateStats->setRefreshRate(mode.fps);
                mScheduler->updatePhaseConfiguration(mode.fps);
            }

            if (emitEvent) {
@@ -1369,8 +1368,7 @@ void SurfaceFlinger::finalizeDisplayModeChange(DisplayDevice& display) {
                               activeMode.fps);

    if (displayId == mActiveDisplayId) {
        mRefreshRateStats->setRefreshRate(activeMode.fps);
        updatePhaseConfiguration(activeMode.fps);
        mScheduler->updatePhaseConfiguration(activeMode.fps);
    }

    if (pendingModeOpt->emitEvent) {
@@ -1399,7 +1397,7 @@ void SurfaceFlinger::applyActiveMode(const sp<DisplayDevice>& display) {
    mScheduler->setRenderRate(displayId, renderFps);

    if (displayId == mActiveDisplayId) {
        updatePhaseConfiguration(renderFps);
        mScheduler->updatePhaseConfiguration(renderFps);
    }
}

@@ -2756,7 +2754,8 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
    if (!getHwComposer().getComposer()->isSupported(
                Hwc2::Composer::OptionalFeature::ExpectedPresentTime) &&
        pacesetterTarget.wouldPresentEarly(minFramePeriod)) {
        const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration;
        const auto hwcMinWorkDuration =
                mScheduler->getVsyncConfiguration().getCurrentConfigs().hwcMinWorkDuration;

        // TODO(b/255601557): Calculate and pass per-display values for each FrameTarget.
        refreshArgs.earliestPresentTime =
@@ -3064,7 +3063,8 @@ void SurfaceFlinger::onCompositionPresented(PhysicalDisplayId pacesetterId,
    const auto schedule = mScheduler->getVsyncSchedule();
    const TimePoint vsyncDeadline = schedule->vsyncDeadlineAfter(presentTime);
    const Period vsyncPeriod = schedule->period();
    const nsecs_t vsyncPhase = mVsyncConfiguration->getCurrentConfigs().late.sfOffset;
    const nsecs_t vsyncPhase =
            mScheduler->getVsyncConfiguration().getCurrentConfigs().late.sfOffset;

    const CompositorTiming compositorTiming(vsyncDeadline.ns(), vsyncPeriod.ns(), vsyncPhase,
                                            presentLatency.ns());
@@ -3741,7 +3741,7 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,

            // TODO(b/175678251) Call a listener instead.
            if (currentState.physical->hwcDisplayId == getHwComposer().getPrimaryHwcDisplayId()) {
                resetPhaseConfiguration(display->getActiveMode().fps);
                mScheduler->resetPhaseConfiguration(display->getActiveMode().fps);
            }
        }
        return;
@@ -3777,15 +3777,6 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
    }
}

void SurfaceFlinger::resetPhaseConfiguration(Fps refreshRate) {
    // Cancel the pending refresh rate change, if any, before updating the phase configuration.
    mScheduler->vsyncModulator().cancelRefreshRateChange();

    mVsyncConfiguration->reset();
    updatePhaseConfiguration(refreshRate);
    mRefreshRateStats->setRefreshRate(refreshRate);
}

void SurfaceFlinger::processDisplayChangesLocked() {
    // here we take advantage of Vector's copy-on-write semantics to
    // improve performance by skipping the transaction entirely when
@@ -4202,10 +4193,6 @@ void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {

    const auto activeMode = display->refreshRateSelector().getActiveMode();
    const Fps activeRefreshRate = activeMode.fps;
    mRefreshRateStats =
            std::make_unique<RefreshRateStats>(*mTimeStats, activeRefreshRate, hal::PowerMode::OFF);

    mVsyncConfiguration = getFactory().createVsyncConfiguration(activeRefreshRate);

    FeatureFlags features;

@@ -4232,11 +4219,9 @@ void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
        features |= Feature::kBackpressureGpuComposition;
    }

    auto modulatorPtr = sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs());

    mScheduler = std::make_unique<Scheduler>(static_cast<ICompositor&>(*this),
                                             static_cast<ISchedulerCallback&>(*this), features,
                                             std::move(modulatorPtr),
                                             getFactory(), activeRefreshRate, *mTimeStats,
                                             static_cast<IVsyncTrackerCallback&>(*this));
    mScheduler->registerDisplay(display->getPhysicalId(), display->holdRefreshRateSelector());
    if (FlagManager::getInstance().vrr_config()) {
@@ -4244,7 +4229,7 @@ void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
    }
    mScheduler->startTimers();

    const auto configs = mVsyncConfiguration->getCurrentConfigs();
    const auto configs = mScheduler->getVsyncConfiguration().getCurrentConfigs();

    mAppConnectionHandle =
            mScheduler->createEventThread(Scheduler::Cycle::Render,
@@ -4266,12 +4251,6 @@ void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
    mFpsReporter = sp<FpsReporter>::make(*mFrameTimeline, *this);
}

void SurfaceFlinger::updatePhaseConfiguration(Fps refreshRate) {
    mVsyncConfiguration->setRefreshRateFps(refreshRate);
    mScheduler->setVsyncConfigSet(mVsyncConfiguration->getCurrentConfigs(),
                                  refreshRate.getPeriod());
}

void SurfaceFlinger::doCommitTransactions() {
    ATRACE_CALL();

@@ -6026,7 +6005,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal:

    if (displayId == mActiveDisplayId) {
        mTimeStats->setPowerMode(mode);
        mRefreshRateStats->setPowerMode(mode);
        mScheduler->setActiveDisplayPowerModeForRefreshRateStats(mode);
    }

    mScheduler->setDisplayPowerMode(displayId, mode);
@@ -6191,10 +6170,6 @@ void SurfaceFlinger::dumpScheduler(std::string& result) const {
    dumper.dump("debugDisplayModeSetByBackdoor"sv, mDebugDisplayModeSetByBackdoor);
    dumper.eol();

    mRefreshRateStats->dump(result);
    dumper.eol();

    mVsyncConfiguration->dump(result);
    StringAppendF(&result,
                  "         present offset: %9" PRId64 " ns\t        VSYNC period: %9" PRId64
                  " ns\n\n",
@@ -8634,7 +8609,8 @@ uint32_t SurfaceFlinger::getMaxAcquiredBufferCountForCurrentRefreshRate(uid_t ui
}

int SurfaceFlinger::getMaxAcquiredBufferCountForRefreshRate(Fps refreshRate) const {
    const auto vsyncConfig = mVsyncConfiguration->getConfigsForRefreshRate(refreshRate).late;
    const auto vsyncConfig =
            mScheduler->getVsyncConfiguration().getConfigsForRefreshRate(refreshRate).late;
    const auto presentLatency = vsyncConfig.appWorkDuration + vsyncConfig.sfWorkDuration;
    return calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
}
@@ -8727,7 +8703,7 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const DisplayDevice* inactiveD
    mActiveDisplayId = activeDisplay.getPhysicalId();
    activeDisplay.getCompositionDisplay()->setLayerCachingTexturePoolEnabled(true);

    resetPhaseConfiguration(activeDisplay.getActiveMode().fps);
    mScheduler->resetPhaseConfiguration(activeDisplay.getActiveMode().fps);

    // TODO(b/255635711): Check for pending mode changes on other displays.
    mScheduler->setModeChangePending(false);
+0 −8
Original line number Diff line number Diff line
@@ -82,7 +82,6 @@
#include "MutexUtils.h"
#include "Scheduler/ISchedulerCallback.h"
#include "Scheduler/RefreshRateSelector.h"
#include "Scheduler/RefreshRateStats.h"
#include "Scheduler/Scheduler.h"
#include "SurfaceFlingerFactory.h"
#include "ThreadContext.h"
@@ -785,9 +784,6 @@ private:

    void initScheduler(const sp<const DisplayDevice>&) REQUIRES(kMainThreadContext, mStateLock);

    void resetPhaseConfiguration(Fps) REQUIRES(mStateLock, kMainThreadContext);
    void updatePhaseConfiguration(Fps) REQUIRES(mStateLock);

    /*
     * Transactions
     */
@@ -1374,10 +1370,6 @@ private:
    scheduler::ConnectionHandle mAppConnectionHandle;
    scheduler::ConnectionHandle mSfConnectionHandle;

    // Stores phase offsets configured per refresh rate.
    std::unique_ptr<scheduler::VsyncConfiguration> mVsyncConfiguration;

    std::unique_ptr<scheduler::RefreshRateStats> mRefreshRateStats;
    scheduler::PresentLatencyTracker mPresentLatencyTracker GUARDED_BY(kMainThreadContext);

    bool mLumaSampling = true;
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ public:

    void eol() { mOut += '\n'; }

    std::string& out() { return mOut; }

    void dump(std::string_view name, std::string_view value = {}) {
        using namespace std::string_view_literals;

Loading