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

Commit 9c93d60f authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Split Scheduler initialization

Create VsyncSchedule and timers after Scheduler construction, which will
happen on boot rather than initial hotplug in the future.

Remove Scheduler from SF factory.

Bug: 185535769
Test: Boot
Change-Id: I1096987f468a43fa4b6ae39709b44425d026248c
parent a1273194
Loading
Loading
Loading
Loading
+17 −39
Original line number Original line Diff line number Diff line
@@ -117,16 +117,10 @@ private:
    }
    }
};
};


Scheduler::Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>& configs,
Scheduler::Scheduler(ISchedulerCallback& callback, Options options)
                     ISchedulerCallback& callback)
      : mOptions(options), mSchedulerCallback(callback) {}
      : Scheduler(configs, callback,
                  {.useContentDetection = sysprop::use_content_detection_for_refresh_rate(false)}) {
}


Scheduler::Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>& configs,
void Scheduler::startTimers() {
                     ISchedulerCallback& callback, Options options)
      : Scheduler(createVsyncSchedule(configs->supportsKernelIdleTimer()), configs, callback,
                  createLayerHistory(), options) {
    using namespace sysprop;
    using namespace sysprop;


    if (const int64_t millis = set_touch_timer_ms(0); millis > 0) {
    if (const int64_t millis = set_touch_timer_ms(0); millis > 0) {
@@ -147,22 +141,6 @@ Scheduler::Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>& confi
    }
    }
}
}


Scheduler::Scheduler(VsyncSchedule schedule,
                     const std::shared_ptr<scheduler::RefreshRateConfigs>& configs,
                     ISchedulerCallback& schedulerCallback,
                     std::unique_ptr<LayerHistory> layerHistory, Options options)
      : mOptions(options),
        mVsyncSchedule(std::move(schedule)),
        mLayerHistory(std::move(layerHistory)),
        mSchedulerCallback(schedulerCallback),
        mPredictedVsyncTracer(
                base::GetBoolProperty("debug.sf.show_predicted_vsync", false)
                        ? std::make_unique<PredictedVsyncTracer>(*mVsyncSchedule.dispatch)
                        : nullptr) {
    setRefreshRateConfigs(configs);
    mSchedulerCallback.setVsyncEnabled(false);
}

Scheduler::~Scheduler() {
Scheduler::~Scheduler() {
    // Ensure the OneShotTimer threads are joined before we start destroying state.
    // Ensure the OneShotTimer threads are joined before we start destroying state.
    mDisplayPowerTimer.reset();
    mDisplayPowerTimer.reset();
@@ -170,7 +148,7 @@ Scheduler::~Scheduler() {
    mRefreshRateConfigs.reset();
    mRefreshRateConfigs.reset();
}
}


Scheduler::VsyncSchedule Scheduler::createVsyncSchedule(bool supportKernelTimer) {
void Scheduler::createVsyncSchedule(bool supportKernelTimer) {
    auto clock = std::make_unique<scheduler::SystemClock>();
    auto clock = std::make_unique<scheduler::SystemClock>();
    auto tracker = createVSyncTracker();
    auto tracker = createVSyncTracker();
    auto dispatch = createVSyncDispatch(*tracker);
    auto dispatch = createVSyncDispatch(*tracker);
@@ -180,11 +158,11 @@ Scheduler::VsyncSchedule Scheduler::createVsyncSchedule(bool supportKernelTimer)
    auto controller =
    auto controller =
            std::make_unique<scheduler::VSyncReactor>(std::move(clock), *tracker, pendingFenceLimit,
            std::make_unique<scheduler::VSyncReactor>(std::move(clock), *tracker, pendingFenceLimit,
                                                      supportKernelTimer);
                                                      supportKernelTimer);
    return {std::move(controller), std::move(tracker), std::move(dispatch)};
    mVsyncSchedule = {std::move(controller), std::move(tracker), std::move(dispatch)};
}


std::unique_ptr<LayerHistory> Scheduler::createLayerHistory() {
    if (base::GetBoolProperty("debug.sf.show_predicted_vsync", false)) {
    return std::make_unique<scheduler::LayerHistory>();
        mPredictedVsyncTracer = std::make_unique<PredictedVsyncTracer>(*mVsyncSchedule.dispatch);
    }
}
}


std::unique_ptr<VSyncSource> Scheduler::makePrimaryDispSyncSource(
std::unique_ptr<VSyncSource> Scheduler::makePrimaryDispSyncSource(
@@ -594,11 +572,11 @@ void Scheduler::registerLayer(Layer* layer) {
    // If the content detection feature is off, we still keep the layer history,
    // If the content detection feature is off, we still keep the layer history,
    // since we use it for other features (like Frame Rate API), so layers
    // since we use it for other features (like Frame Rate API), so layers
    // still need to be registered.
    // still need to be registered.
    mLayerHistory->registerLayer(layer, voteType);
    mLayerHistory.registerLayer(layer, voteType);
}
}


void Scheduler::deregisterLayer(Layer* layer) {
void Scheduler::deregisterLayer(Layer* layer) {
    mLayerHistory->deregisterLayer(layer);
    mLayerHistory.deregisterLayer(layer);
}
}


void Scheduler::recordLayerHistory(Layer* layer, nsecs_t presentTime,
void Scheduler::recordLayerHistory(Layer* layer, nsecs_t presentTime,
@@ -608,11 +586,11 @@ void Scheduler::recordLayerHistory(Layer* layer, nsecs_t presentTime,
        if (!mRefreshRateConfigs->canSwitch()) return;
        if (!mRefreshRateConfigs->canSwitch()) return;
    }
    }


    mLayerHistory->record(layer, presentTime, systemTime(), updateType);
    mLayerHistory.record(layer, presentTime, systemTime(), updateType);
}
}


void Scheduler::setModeChangePending(bool pending) {
void Scheduler::setModeChangePending(bool pending) {
    mLayerHistory->setModeChangePending(pending);
    mLayerHistory.setModeChangePending(pending);
}
}


void Scheduler::chooseRefreshRateForContent() {
void Scheduler::chooseRefreshRateForContent() {
@@ -625,7 +603,7 @@ void Scheduler::chooseRefreshRateForContent() {


    const auto refreshRateConfigs = holdRefreshRateConfigs();
    const auto refreshRateConfigs = holdRefreshRateConfigs();
    scheduler::LayerHistory::Summary summary =
    scheduler::LayerHistory::Summary summary =
            mLayerHistory->summarize(*refreshRateConfigs, systemTime());
            mLayerHistory.summarize(*refreshRateConfigs, systemTime());
    scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
    scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
    DisplayModePtr newMode;
    DisplayModePtr newMode;
    bool frameRateChanged;
    bool frameRateChanged;
@@ -686,7 +664,7 @@ void Scheduler::setDisplayPowerState(bool normal) {


    // Display Power event will boost the refresh rate to performance.
    // Display Power event will boost the refresh rate to performance.
    // Clear Layer History to get fresh FPS detection
    // Clear Layer History to get fresh FPS detection
    mLayerHistory->clear();
    mLayerHistory.clear();
}
}


void Scheduler::kernelIdleTimerCallback(TimerState state) {
void Scheduler::kernelIdleTimerCallback(TimerState state) {
@@ -730,7 +708,7 @@ void Scheduler::touchTimerCallback(TimerState state) {
    // NOTE: Instead of checking all the layers, we should be checking the layer
    // NOTE: Instead of checking all the layers, we should be checking the layer
    // that is currently on top. b/142507166 will give us this capability.
    // that is currently on top. b/142507166 will give us this capability.
    if (handleTimerStateChanged(&mFeatures.touch, touch)) {
    if (handleTimerStateChanged(&mFeatures.touch, touch)) {
        mLayerHistory->clear();
        mLayerHistory.clear();
    }
    }
    ATRACE_INT("TouchState", static_cast<int>(touch));
    ATRACE_INT("TouchState", static_cast<int>(touch));
}
}
@@ -747,7 +725,7 @@ void Scheduler::dump(std::string& result) const {
                  mTouchTimer ? mTouchTimer->dump().c_str() : "off");
                  mTouchTimer ? mTouchTimer->dump().c_str() : "off");
    StringAppendF(&result, "+  Content detection: %s %s\n\n",
    StringAppendF(&result, "+  Content detection: %s %s\n\n",
                  toContentDetectionString(mOptions.useContentDetection),
                  toContentDetectionString(mOptions.useContentDetection),
                  mLayerHistory ? mLayerHistory->dump().c_str() : "(no layer history)");
                  mLayerHistory.dump().c_str());


    {
    {
        std::lock_guard lock(mFrameRateOverridesLock);
        std::lock_guard lock(mFrameRateOverridesLock);
@@ -911,7 +889,7 @@ void Scheduler::onPostComposition(nsecs_t presentTime) {
}
}


void Scheduler::onActiveDisplayAreaChanged(uint32_t displayArea) {
void Scheduler::onActiveDisplayAreaChanged(uint32_t displayArea) {
    mLayerHistory->setDisplayArea(displayArea);
    mLayerHistory.setDisplayArea(displayArea);
}
}


void Scheduler::setPreferredRefreshRateForUid(FrameRateOverride frameRateOverride) {
void Scheduler::setPreferredRefreshRateForUid(FrameRateOverride frameRateOverride) {
+11 −18
Original line number Original line Diff line number Diff line
@@ -75,9 +75,17 @@ public:
    using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate;
    using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate;
    using ModeEvent = scheduler::RefreshRateConfigEvent;
    using ModeEvent = scheduler::RefreshRateConfigEvent;


    Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&);
    struct Options {
        // Whether to use content detection at all.
        bool useContentDetection = false;
    };

    Scheduler(ISchedulerCallback&, Options);
    ~Scheduler();
    ~Scheduler();


    void createVsyncSchedule(bool supportKernelIdleTimer);
    void startTimers();

    using ConnectionHandle = scheduler::ConnectionHandle;
    using ConnectionHandle = scheduler::ConnectionHandle;
    ConnectionHandle createConnection(const char* connectionName, frametimeline::TokenManager*,
    ConnectionHandle createConnection(const char* connectionName, frametimeline::TokenManager*,
                                      std::chrono::nanoseconds workDuration,
                                      std::chrono::nanoseconds workDuration,
@@ -213,27 +221,12 @@ private:
    enum class TimerState { Reset, Expired };
    enum class TimerState { Reset, Expired };
    enum class TouchState { Inactive, Active };
    enum class TouchState { Inactive, Active };


    struct Options {
        // Whether to use content detection at all.
        bool useContentDetection;
    };

    struct VsyncSchedule {
    struct VsyncSchedule {
        std::unique_ptr<scheduler::VsyncController> controller;
        std::unique_ptr<scheduler::VsyncController> controller;
        std::unique_ptr<scheduler::VSyncTracker> tracker;
        std::unique_ptr<scheduler::VSyncTracker> tracker;
        std::unique_ptr<scheduler::VSyncDispatch> dispatch;
        std::unique_ptr<scheduler::VSyncDispatch> dispatch;
    };
    };


    // Unlike the testing constructor, this creates the VsyncSchedule, LayerHistory, and timers.
    Scheduler(const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&, Options);

    // Used by tests to inject mocks.
    Scheduler(VsyncSchedule, const std::shared_ptr<scheduler::RefreshRateConfigs>&,
              ISchedulerCallback&, std::unique_ptr<LayerHistory>, Options);

    static VsyncSchedule createVsyncSchedule(bool supportKernelIdleTimer);
    static std::unique_ptr<LayerHistory> createLayerHistory();

    // Create a connection on the given EventThread.
    // Create a connection on the given EventThread.
    ConnectionHandle createConnection(std::unique_ptr<EventThread>);
    ConnectionHandle createConnection(std::unique_ptr<EventThread>);
    sp<EventThreadConnection> createConnectionInternal(
    sp<EventThreadConnection> createConnectionInternal(
@@ -297,7 +290,7 @@ private:
    VsyncSchedule mVsyncSchedule;
    VsyncSchedule mVsyncSchedule;


    // Used to choose refresh rate if content detection is enabled.
    // Used to choose refresh rate if content detection is enabled.
    std::unique_ptr<LayerHistory> mLayerHistory;
    LayerHistory mLayerHistory;


    // Timer used to monitor touch events.
    // Timer used to monitor touch events.
    std::optional<scheduler::OneShotTimer> mTouchTimer;
    std::optional<scheduler::OneShotTimer> mTouchTimer;
@@ -338,7 +331,7 @@ private:
            GUARDED_BY(mVsyncTimelineLock);
            GUARDED_BY(mVsyncTimelineLock);
    static constexpr std::chrono::nanoseconds MAX_VSYNC_APPLIED_TIME = 200ms;
    static constexpr std::chrono::nanoseconds MAX_VSYNC_APPLIED_TIME = 200ms;


    const std::unique_ptr<PredictedVsyncTracer> mPredictedVsyncTracer;
    std::unique_ptr<PredictedVsyncTracer> mPredictedVsyncTracer;


    // The frame rate override lists need their own mutex as they are being read
    // The frame rate override lists need their own mutex as they are being read
    // by SurfaceFlinger, Scheduler and EventThread (as a callback) to prevent deadlocks
    // by SurfaceFlinger, Scheduler and EventThread (as a callback) to prevent deadlocks
+13 −2
Original line number Original line Diff line number Diff line
@@ -3149,8 +3149,19 @@ void SurfaceFlinger::initScheduler(const sp<DisplayDevice>& display) {
    mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate);
    mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate);
    mVsyncModulator = sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs());
    mVsyncModulator = sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs());


    // start the EventThread
    const Scheduler::Options options = {
    mScheduler = getFactory().createScheduler(display->holdRefreshRateConfigs(), *this);
            .useContentDetection = sysprop::use_content_detection_for_refresh_rate(false)};

    mScheduler = std::make_unique<Scheduler>(static_cast<ISchedulerCallback&>(*this), options);
    {
        auto configs = display->holdRefreshRateConfigs();
        mScheduler->createVsyncSchedule(configs->supportsKernelIdleTimer());
        mScheduler->setRefreshRateConfigs(std::move(configs));
    }

    setVsyncEnabled(false);
    mScheduler->startTimers();

    const auto configs = mVsyncConfiguration->getCurrentConfigs();
    const auto configs = mVsyncConfiguration->getCurrentConfigs();
    const nsecs_t vsyncPeriod = currRefreshRate.getPeriodNsecs();
    const nsecs_t vsyncPeriod = currRefreshRate.getPeriodNsecs();
    mAppConnectionHandle =
    mAppConnectionHandle =
+0 −6
Original line number Original line Diff line number Diff line
@@ -64,12 +64,6 @@ std::unique_ptr<scheduler::VsyncConfiguration> DefaultFactory::createVsyncConfig
    }
    }
}
}


std::unique_ptr<Scheduler> DefaultFactory::createScheduler(
        const std::shared_ptr<scheduler::RefreshRateConfigs>& refreshRateConfigs,
        ISchedulerCallback& callback) {
    return std::make_unique<Scheduler>(std::move(refreshRateConfigs), callback);
}

sp<SurfaceInterceptor> DefaultFactory::createSurfaceInterceptor() {
sp<SurfaceInterceptor> DefaultFactory::createSurfaceInterceptor() {
    return new android::impl::SurfaceInterceptor();
    return new android::impl::SurfaceInterceptor();
}
}
+0 −2
Original line number Original line Diff line number Diff line
@@ -30,8 +30,6 @@ public:
    std::unique_ptr<MessageQueue> createMessageQueue(ICompositor&) override;
    std::unique_ptr<MessageQueue> createMessageQueue(ICompositor&) override;
    std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration(
    std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration(
            Fps currentRefreshRate) override;
            Fps currentRefreshRate) override;
    std::unique_ptr<Scheduler> createScheduler(
            const std::shared_ptr<scheduler::RefreshRateConfigs>&, ISchedulerCallback&) override;
    sp<SurfaceInterceptor> createSurfaceInterceptor() override;
    sp<SurfaceInterceptor> createSurfaceInterceptor() override;
    sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override;
    sp<StartPropertySetThread> createStartPropertySetThread(bool timestampPropertyValue) override;
    sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&) override;
    sp<DisplayDevice> createDisplayDevice(DisplayDeviceCreationArgs&) override;
Loading