Commit 638f5482 authored by Xaver Hugl's avatar Xaver Hugl
Browse files

RenderLoop: restrict repaint scheduling with fullscreen windows

With an opaque fullscreen window we can be sure that items under it don't
actually require us to repaint. This should yield some small efficiency
improvements and resolves stutter with adaptive sync.

BUG: 443872
FIXED-IN: 5.23.3


(cherry picked from commit 75863454)
parent ceec4e50
......@@ -261,12 +261,12 @@ void Item::scheduleRepaintInternal(const QRegion &region)
const QRegion dirtyRegion = globalRegion & output->geometry();
if (!dirtyRegion.isEmpty()) {
m_repaints[output] += dirtyRegion;
output->renderLoop()->scheduleRepaint();
output->renderLoop()->scheduleRepaint(this);
}
}
} else {
m_repaints[nullptr] += globalRegion;
kwinApp()->platform()->renderLoop()->scheduleRepaint();
kwinApp()->platform()->renderLoop()->scheduleRepaint(this);
}
}
......@@ -280,11 +280,11 @@ void Item::scheduleFrame()
const QVector<AbstractOutput *> outputs = kwinApp()->platform()->enabledOutputs();
for (const AbstractOutput *output : outputs) {
if (output->geometry().intersects(geometry)) {
output->renderLoop()->scheduleRepaint();
output->renderLoop()->scheduleRepaint(this);
}
}
} else {
kwinApp()->platform()->renderLoop()->scheduleRepaint();
kwinApp()->platform()->renderLoop()->scheduleRepaint(this);
}
}
......
......@@ -36,7 +36,7 @@ void RenderLoopPrivate::scheduleRepaint()
if (kwinApp()->isTerminating() || compositeTimer.isActive()) {
return;
}
if (vrrPolicy == RenderLoop::VrrPolicy::Always || (vrrPolicy == RenderLoop::VrrPolicy::Automatic && hasFullscreenSurface)) {
if (vrrPolicy == RenderLoop::VrrPolicy::Always || (vrrPolicy == RenderLoop::VrrPolicy::Automatic && fullscreenItem != nullptr)) {
presentMode = SyncMode::Adaptive;
} else {
presentMode = SyncMode::Fixed;
......@@ -214,9 +214,9 @@ void RenderLoop::setRefreshRate(int refreshRate)
Q_EMIT refreshRateChanged();
}
void RenderLoop::scheduleRepaint()
void RenderLoop::scheduleRepaint(Item *item)
{
if (d->pendingRepaint) {
if (d->pendingRepaint || (d->fullscreenItem != nullptr && item != nullptr && item != d->fullscreenItem)) {
return;
}
if (!d->pendingFrameCount && !d->inhibitCount) {
......@@ -236,9 +236,9 @@ std::chrono::nanoseconds RenderLoop::nextPresentationTimestamp() const
return d->nextPresentationTimestamp;
}
void RenderLoop::setFullscreenSurface(SurfaceItem *surfaceItem)
void RenderLoop::setFullscreenSurface(Item *surfaceItem)
{
d->hasFullscreenSurface = surfaceItem != nullptr;
d->fullscreenItem = surfaceItem;
}
RenderLoop::VrrPolicy RenderLoop::vrrPolicy() const
......
......@@ -14,7 +14,7 @@ namespace KWin
{
class RenderLoopPrivate;
class SurfaceItem;
class Item;
/**
* The RenderLoop class represents the compositing scheduler on a particular output.
......@@ -71,7 +71,7 @@ public:
/**
* Schedules a compositing cycle at the next available moment.
*/
void scheduleRepaint();
void scheduleRepaint(Item *item = nullptr);
/**
* Returns the timestamp of the last frame that has been presented on the screen.
......@@ -90,7 +90,7 @@ public:
* Sets the surface that currently gets scanned out,
* so that this RenderLoop can adjust its timing behavior to that surface
*/
void setFullscreenSurface(SurfaceItem *surface);
void setFullscreenSurface(Item *surface);
enum class VrrPolicy : uint32_t {
Never = 0,
......
......@@ -41,7 +41,7 @@ public:
bool pendingReschedule = false;
bool pendingRepaint = false;
RenderLoop::VrrPolicy vrrPolicy = RenderLoop::VrrPolicy::Never;
bool hasFullscreenSurface = false;
Item *fullscreenItem = nullptr;
enum class SyncMode {
Fixed,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment