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

Commit 156c9feb authored by Dominik Laskowski's avatar Dominik Laskowski Committed by Android (Google) Code Review
Browse files

Merge changes Ieea13661,I05b66a4e

* changes:
  SF: Move ownership of VsyncModulator to Scheduler
  SF: Extract VsyncConfig to its own header
parents 6caf98c5 1c99a001
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -196,7 +196,7 @@ Layer::Layer(const LayerCreationArgs& args)
        mDrawingState.color.b = -1.0_hf;
    }

    mFrameTracker.setDisplayRefreshPeriod(args.flinger->mScheduler->getLeaderVsyncPeriod());
    mFrameTracker.setDisplayRefreshPeriod(args.flinger->mScheduler->getLeaderVsyncPeriod().ns());

    mOwnerUid = args.ownerUid;
    mOwnerPid = args.ownerPid;
+0 −1
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@
namespace android {

class Layer;
class Scheduler;
class SurfaceFlinger;
struct SamplingOffsetCallback;

+33 −13
Original line number Diff line number Diff line
@@ -60,8 +60,12 @@

namespace android::scheduler {

Scheduler::Scheduler(ICompositor& compositor, ISchedulerCallback& callback, FeatureFlags features)
      : impl::MessageQueue(compositor), mFeatures(features), mSchedulerCallback(callback) {}
Scheduler::Scheduler(ICompositor& compositor, ISchedulerCallback& callback, FeatureFlags features,
                     sp<VsyncModulator> modulatorPtr)
      : impl::MessageQueue(compositor),
        mFeatures(features),
        mVsyncModulator(std::move(modulatorPtr)),
        mSchedulerCallback(callback) {}

Scheduler::~Scheduler() {
    // MessageQueue depends on VsyncSchedule, so first destroy it.
@@ -186,17 +190,19 @@ impl::EventThread::GetVsyncPeriodFunction Scheduler::makeGetVsyncPeriodFunction(
    };
}

ConnectionHandle Scheduler::createConnection(const char* connectionName,
ConnectionHandle Scheduler::createEventThread(Cycle cycle,
                                              frametimeline::TokenManager* tokenManager,
                                              std::chrono::nanoseconds workDuration,
                                              std::chrono::nanoseconds readyDuration) {
    auto throttleVsync = makeThrottleVsyncCallback();
    auto getVsyncPeriod = makeGetVsyncPeriodFunction();
    auto eventThread =
            std::make_unique<impl::EventThread>(connectionName, *mVsyncSchedule, tokenManager,
                                                std::move(throttleVsync), std::move(getVsyncPeriod),
    auto eventThread = std::make_unique<impl::EventThread>(cycle == Cycle::Render ? "app" : "appSf",
                                                           *mVsyncSchedule, tokenManager,
                                                           makeThrottleVsyncCallback(),
                                                           makeGetVsyncPeriodFunction(),
                                                           workDuration, readyDuration);
    return createConnection(std::move(eventThread));

    auto& handle = cycle == Cycle::Render ? mAppConnectionHandle : mSfConnectionHandle;
    handle = createConnection(std::move(eventThread));
    return handle;
}

ConnectionHandle Scheduler::createConnection(std::unique_ptr<EventThread> eventThread) {
@@ -356,6 +362,20 @@ 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::setVsyncConfig(const VsyncConfig& config, Period vsyncPeriod) {
    setDuration(mAppConnectionHandle,
                /* workDuration */ config.appWorkDuration,
                /* readyDuration */ config.sfWorkDuration);
    setDuration(mSfConnectionHandle,
                /* workDuration */ vsyncPeriod,
                /* readyDuration */ config.sfWorkDuration);
    setDuration(config.sfWorkDuration);
}

void Scheduler::enableHardwareVsync() {
    std::lock_guard<std::mutex> lock(mHWVsyncLock);
    if (!mPrimaryHWVsyncEnabled && mHWVsyncAvailable) {
+32 −6
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@
#include <ftl/optional.h>
#include <scheduler/Features.h>
#include <scheduler/Time.h>
#include <scheduler/VsyncConfig.h>
#include <ui/DisplayId.h>

#include "Display/DisplayMap.h"
@@ -47,6 +48,7 @@
#include "OneShotTimer.h"
#include "RefreshRateSelector.h"
#include "Utils/Dumper.h"
#include "VsyncModulator.h"
#include "VsyncSchedule.h"

namespace android::scheduler {
@@ -104,7 +106,7 @@ class Scheduler : android::impl::MessageQueue {
    using Impl = android::impl::MessageQueue;

public:
    Scheduler(ICompositor&, ISchedulerCallback&, FeatureFlags);
    Scheduler(ICompositor&, ISchedulerCallback&, FeatureFlags, sp<VsyncModulator>);
    virtual ~Scheduler();

    void startTimers();
@@ -146,7 +148,12 @@ public:
        return std::move(future);
    }

    ConnectionHandle createConnection(const char* connectionName, frametimeline::TokenManager*,
    enum class Cycle {
        Render,       // Surface rendering.
        LastComposite // Ahead of display compositing by one refresh period.
    };

    ConnectionHandle createEventThread(Cycle, frametimeline::TokenManager*,
                                       std::chrono::nanoseconds workDuration,
                                       std::chrono::nanoseconds readyDuration);

@@ -168,6 +175,18 @@ public:
    void setDuration(ConnectionHandle, std::chrono::nanoseconds workDuration,
                     std::chrono::nanoseconds readyDuration);

    const VsyncModulator& vsyncModulator() const { return *mVsyncModulator; }

    template <typename... Args,
              typename Handler = std::optional<VsyncConfig> (VsyncModulator::*)(Args...)>
    void modulateVsync(Handler handler, Args... args) {
        if (const auto config = (*mVsyncModulator.*handler)(args...)) {
            setVsyncConfig(*config, getLeaderVsyncPeriod());
        }
    }

    void setVsyncConfigSet(const VsyncConfigSet&, Period vsyncPeriod);

    // Sets the render rate for the scheduler to run at.
    void setRenderRate(Fps);

@@ -239,8 +258,8 @@ public:
    // Retrieves the overridden refresh rate for a given uid.
    std::optional<Fps> getFrameRateOverride(uid_t) const EXCLUDES(mDisplayLock);

    nsecs_t getLeaderVsyncPeriod() const EXCLUDES(mDisplayLock) {
        return leaderSelectorPtr()->getActiveMode().fps.getPeriodNsecs();
    Period getLeaderVsyncPeriod() const EXCLUDES(mDisplayLock) {
        return leaderSelectorPtr()->getActiveMode().fps.getPeriod();
    }

    // Returns the framerate of the layer with the given sequence ID
@@ -270,6 +289,7 @@ private:
    void displayPowerTimerCallback(TimerState);

    void setVsyncPeriod(nsecs_t period);
    void setVsyncConfig(const VsyncConfig&, Period vsyncPeriod);

    // Chooses a leader among the registered displays, unless `leaderIdOpt` is specified. The new
    // `mLeaderDisplayId` is never `std::nullopt`.
@@ -330,6 +350,9 @@ private:
    mutable std::mutex mConnectionsLock;
    std::unordered_map<ConnectionHandle, Connection> mConnections GUARDED_BY(mConnectionsLock);

    ConnectionHandle mAppConnectionHandle;
    ConnectionHandle mSfConnectionHandle;

    mutable std::mutex mHWVsyncLock;
    bool mPrimaryHWVsyncEnabled GUARDED_BY(mHWVsyncLock) = false;
    bool mHWVsyncAvailable GUARDED_BY(mHWVsyncLock) = false;
@@ -339,6 +362,9 @@ private:
    const FeatureFlags mFeatures;
    std::optional<VsyncSchedule> mVsyncSchedule;

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

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

+6 −6
Original line number Diff line number Diff line
@@ -42,12 +42,12 @@ namespace android::scheduler::impl {

VsyncConfiguration::VsyncConfiguration(Fps currentFps) : mRefreshRateFps(currentFps) {}

PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRate(Fps fps) const {
VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRate(Fps fps) const {
    std::lock_guard lock(mLock);
    return getConfigsForRefreshRateLocked(fps);
}

PhaseOffsets::VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRateLocked(Fps fps) const {
VsyncConfigSet VsyncConfiguration::getConfigsForRefreshRateLocked(Fps fps) const {
    if (const auto offsets = mOffsetsCache.get(fps)) {
        return offsets->get();
    }
@@ -134,7 +134,7 @@ PhaseOffsets::PhaseOffsets(Fps currentFps, nsecs_t vsyncPhaseOffsetNs, nsecs_t s
        mThresholdForNextVsync(thresholdForNextVsync),
        mHwcMinWorkDuration(hwcMinWorkDuration) {}

PhaseOffsets::VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const {
VsyncConfigSet PhaseOffsets::constructOffsets(nsecs_t vsyncDuration) const {
    if (vsyncDuration < std::chrono::nanoseconds(15ms).count()) {
        return getHighFpsOffsets(vsyncDuration);
    } else {
@@ -158,7 +158,7 @@ std::chrono::nanoseconds appOffsetToDuration(nsecs_t appOffset, nsecs_t sfOffset
}
} // namespace

PhaseOffsets::VsyncConfigSet PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDuration) const {
VsyncConfigSet PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDuration) const {
    const auto earlySfOffset =
            mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync

@@ -196,7 +196,7 @@ PhaseOffsets::VsyncConfigSet PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDurati
    };
}

PhaseOffsets::VsyncConfigSet PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDuration) const {
VsyncConfigSet PhaseOffsets::getHighFpsOffsets(nsecs_t vsyncDuration) const {
    const auto earlySfOffset =
            mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
            ? mHighFpsEarlySfOffsetNs.value_or(mHighFpsSfVSyncPhaseOffsetNs)
@@ -286,7 +286,7 @@ nsecs_t appDurationToOffset(std::chrono::nanoseconds appDuration,
}
} // namespace

WorkDuration::VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuration) const {
VsyncConfigSet WorkDuration::constructOffsets(nsecs_t vsyncDuration) const {
    const auto sfDurationFixup = [vsyncDuration](nsecs_t duration) {
        return duration == -1 ? std::chrono::nanoseconds(vsyncDuration) - 1ms
                              : std::chrono::nanoseconds(duration);
Loading