core/renderloop: take the output of the active window into account for vrr scheduling

If the active window is on a different output than the one the renderloop is for,
the scheduling logic would otherwise never schedule a repaint while adaptive sync
is active.

BUG: 480252
This commit is contained in:
Xaver Hugl 2024-01-24 20:40:45 +01:00 committed by Vlad Zahorodnii
parent bb2391133d
commit bbc833baa6
9 changed files with 17 additions and 14 deletions

View file

@ -17,7 +17,7 @@ namespace KWin
DrmAbstractOutput::DrmAbstractOutput(DrmGpu *gpu)
: Output(gpu->platform())
, m_renderLoop(std::make_unique<RenderLoop>())
, m_renderLoop(std::make_unique<RenderLoop>(this))
, m_gpu(gpu)
{
}

View file

@ -21,7 +21,7 @@ namespace KWin
VirtualOutput::VirtualOutput(VirtualBackend *parent, bool internal)
: Output(parent)
, m_backend(parent)
, m_renderLoop(std::make_unique<RenderLoop>())
, m_renderLoop(std::make_unique<RenderLoop>(this))
, m_vsyncMonitor(SoftwareVsyncMonitor::create())
{
connect(m_vsyncMonitor.get(), &VsyncMonitor::vblankOccurred, this, &VirtualOutput::vblank);

View file

@ -95,7 +95,7 @@ void WaylandCursor::sync()
WaylandOutput::WaylandOutput(const QString &name, WaylandBackend *backend)
: Output(backend)
, m_renderLoop(std::make_unique<RenderLoop>())
, m_renderLoop(std::make_unique<RenderLoop>(this))
, m_surface(backend->display()->compositor()->createSurface())
, m_xdgShellSurface(backend->display()->xdgShell()->createSurface(m_surface.get()))
, m_backend(backend)

View file

@ -98,7 +98,7 @@ X11StandaloneBackend::X11StandaloneBackend(QObject *parent)
: OutputBackend(parent)
, m_updateOutputsTimer(std::make_unique<QTimer>())
, m_x11Display(QX11Info::display())
, m_renderLoop(std::make_unique<RenderLoop>())
, m_renderLoop(std::make_unique<RenderLoop>(nullptr))
{
#if HAVE_X11_XINPUT
if (!qEnvironmentVariableIsSet("KWIN_NO_XI2")) {

View file

@ -135,7 +135,7 @@ void X11WindowedCursor::update(const QImage &image, const QPointF &hotspot)
X11WindowedOutput::X11WindowedOutput(X11WindowedBackend *backend)
: Output(backend)
, m_renderLoop(std::make_unique<RenderLoop>())
, m_renderLoop(std::make_unique<RenderLoop>(this))
, m_backend(backend)
{
m_window = xcb_generate_id(m_backend->connection());

View file

@ -26,8 +26,9 @@ RenderLoopPrivate *RenderLoopPrivate::get(RenderLoop *loop)
return loop->d.get();
}
RenderLoopPrivate::RenderLoopPrivate(RenderLoop *q)
RenderLoopPrivate::RenderLoopPrivate(RenderLoop *q, Output *output)
: q(q)
, output(output)
{
compositeTimer.setSingleShot(true);
QObject::connect(&compositeTimer, &QTimer::timeout, q, [this]() {
@ -138,8 +139,8 @@ void RenderLoopPrivate::invalidate()
compositeTimer.stop();
}
RenderLoop::RenderLoop()
: d(std::make_unique<RenderLoopPrivate>(this))
RenderLoop::RenderLoop(Output *output)
: d(std::make_unique<RenderLoopPrivate>(this, output))
{
}
@ -201,9 +202,9 @@ void RenderLoop::scheduleRepaint(Item *item)
return;
}
const bool vrr = d->presentationMode == PresentationMode::AdaptiveSync || d->presentationMode == PresentationMode::AdaptiveAsync;
if (vrr && workspace()->activeWindow()) {
if (vrr && workspace()->activeWindow() && d->output) {
Window *const activeWindow = workspace()->activeWindow();
if (activeWindow->surfaceItem() && item != activeWindow->surfaceItem() && activeWindow->surfaceItem()->refreshRateEstimation() >= 30) {
if (activeWindow->isOnOutput(d->output) && activeWindow->surfaceItem() && item != activeWindow->surfaceItem() && activeWindow->surfaceItem()->refreshRateEstimation() >= 30) {
return;
}
}

View file

@ -16,6 +16,7 @@ namespace KWin
class RenderLoopPrivate;
class SurfaceItem;
class Item;
class Output;
/**
* The RenderLoop class represents the compositing scheduler on a particular output.
@ -30,7 +31,7 @@ class KWIN_EXPORT RenderLoop : public QObject
Q_OBJECT
public:
explicit RenderLoop();
explicit RenderLoop(Output *output);
~RenderLoop() override;
/**

View file

@ -22,7 +22,7 @@ class KWIN_EXPORT RenderLoopPrivate
{
public:
static RenderLoopPrivate *get(RenderLoop *loop);
explicit RenderLoopPrivate(RenderLoop *q);
explicit RenderLoopPrivate(RenderLoop *q, Output *output);
void dispatch();
void invalidate();
@ -35,7 +35,8 @@ public:
void notifyFrameCompleted(std::chrono::nanoseconds timestamp, std::chrono::nanoseconds renderTime, PresentationMode mode = PresentationMode::VSync);
void notifyVblank(std::chrono::nanoseconds timestamp);
RenderLoop *q;
RenderLoop *const q;
Output *const output;
std::chrono::nanoseconds lastPresentationTimestamp = std::chrono::nanoseconds::zero();
std::chrono::nanoseconds nextPresentationTimestamp = std::chrono::nanoseconds::zero();
QTimer compositeTimer;

View file

@ -13,7 +13,7 @@ PlaceholderOutput::PlaceholderOutput(const QSize &size, qreal scale)
{
auto mode = std::make_shared<OutputMode>(size, 60000);
m_renderLoop = std::make_unique<RenderLoop>();
m_renderLoop = std::make_unique<RenderLoop>(this);
m_renderLoop->setRefreshRate(mode->refreshRate());
m_renderLoop->inhibit();