wayland: Schedule repaints even on empty commits

If only frame callbacks have been committed, the compositor must still
schedule compositing.

BUG: 428499
icc-effect-5.26.4
Vlad Zahorodnii 2021-02-02 15:16:33 +02:00
parent e30b1a0f92
commit 72fda78cf6
6 changed files with 43 additions and 20 deletions

View File

@ -778,6 +778,13 @@ Scene::Window::Window(Toplevel *client, QObject *parent)
this, &Window::discardPixmap);
connect(surface, &KWaylandServer::SurfaceInterface::surfaceToBufferMatrixChanged,
this, &Window::discardQuads);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceCommitted, this, [this](KWaylandServer::SubSurfaceInterface *subsurface) {
handleSurfaceCommitted(subsurface->surface());
});
connect(surface, &KWaylandServer::SurfaceInterface::committed, this, [this, surface]() {
handleSurfaceCommitted(surface);
});
}
connect(toplevel, &Toplevel::screenScaleChanged, this, &Window::discardQuads);
@ -1218,6 +1225,27 @@ void Scene::Window::reallocRepaints()
m_repaints.fill(infiniteRegion());
}
void Scene::Window::scheduleRepaint()
{
if (kwinApp()->platform()->isPerScreenRenderingEnabled()) {
const QVector<AbstractOutput *> outputs = kwinApp()->platform()->enabledOutputs();
for (AbstractOutput *output : outputs) {
if (window()->isOnOutput(output)) {
output->renderLoop()->scheduleRepaint();
}
}
} else {
kwinApp()->platform()->renderLoop()->scheduleRepaint();
}
}
void Scene::Window::handleSurfaceCommitted(KWaylandServer::SurfaceInterface *surface)
{
if (surface->hasFrameCallbacks()) {
scheduleRepaint();
}
}
//****************************************
// WindowPixmap
//****************************************

View File

@ -400,6 +400,8 @@ protected:
ImageFilterType filter;
Shadow *m_shadow;
private:
void scheduleRepaint();
void handleSurfaceCommitted(KWaylandServer::SurfaceInterface *surface);
void reallocRepaints();
QScopedPointer<WindowPixmap> m_currentPixmap;

View File

@ -39,6 +39,8 @@ void SubSurfaceMonitor::registerSubSurface(SubSurfaceInterface *subSurface)
this, &SubSurfaceMonitor::subSurfaceSurfaceToBufferMatrixChanged);
connect(surface, &SurfaceInterface::bufferSizeChanged,
this, &SubSurfaceMonitor::subSurfaceBufferSizeChanged);
connect(surface, &SurfaceInterface::committed,
this, [this, subSurface]() { emit subSurfaceCommitted(subSurface); });
registerSurface(surface);
}
@ -49,18 +51,7 @@ void SubSurfaceMonitor::unregisterSubSurface(SubSurfaceInterface *subSurface)
if (!surface)
return;
disconnect(subSurface, &SubSurfaceInterface::positionChanged,
this, &SubSurfaceMonitor::subSurfaceMoved);
disconnect(surface, &SurfaceInterface::sizeChanged,
this, &SubSurfaceMonitor::subSurfaceResized);
disconnect(surface, &SurfaceInterface::mapped,
this, &SubSurfaceMonitor::subSurfaceMapped);
disconnect(surface, &SurfaceInterface::unmapped,
this, &SubSurfaceMonitor::subSurfaceUnmapped);
disconnect(surface, &SurfaceInterface::surfaceToBufferMatrixChanged,
this, &SubSurfaceMonitor::subSurfaceSurfaceToBufferMatrixChanged);
disconnect(surface, &SurfaceInterface::bufferSizeChanged,
this, &SubSurfaceMonitor::subSurfaceBufferSizeChanged);
disconnect(subSurface, nullptr, this, nullptr);
unregisterSurface(surface);
}
@ -79,14 +70,7 @@ void SubSurfaceMonitor::registerSurface(SurfaceInterface *surface)
void SubSurfaceMonitor::unregisterSurface(SurfaceInterface *surface)
{
disconnect(surface, &SurfaceInterface::childSubSurfaceAdded,
this, &SubSurfaceMonitor::subSurfaceAdded);
disconnect(surface, &SurfaceInterface::childSubSurfaceRemoved,
this, &SubSurfaceMonitor::subSurfaceRemoved);
disconnect(surface, &SurfaceInterface::childSubSurfaceAdded,
this, &SubSurfaceMonitor::registerSubSurface);
disconnect(surface, &SurfaceInterface::childSubSurfaceRemoved,
this, &SubSurfaceMonitor::unregisterSubSurface);
disconnect(surface, nullptr, this, nullptr);
}
} // namespace KWin

View File

@ -68,6 +68,7 @@ Q_SIGNALS:
* This signal is emitted when the buffer size of a subsurface has changed.
*/
void subSurfaceBufferSizeChanged();
void subSurfaceCommitted(KWaylandServer::SubSurfaceInterface *subSurface);
private:
void registerSubSurface(KWaylandServer::SubSurfaceInterface *subSurface);

View File

@ -9,6 +9,7 @@
#include "toplevel.h"
#include "abstract_client.h"
#include "abstract_output.h"
#ifdef KWIN_BUILD_ACTIVITIES
#include "activities.h"
#endif
@ -563,6 +564,11 @@ bool Toplevel::isOnActiveScreen() const
return isOnScreen(screens()->current());
}
bool Toplevel::isOnOutput(AbstractOutput *output) const
{
return output->geometry().intersects(frameGeometry());
}
void Toplevel::updateShadow()
{
QRect dirtyRect; // old & new shadow region

View File

@ -37,6 +37,7 @@ class SurfaceInterface;
namespace KWin
{
class AbstractOutput;
class ClientMachine;
class Deleted;
class EffectWindowImpl;
@ -347,6 +348,7 @@ public:
int width() const;
int height() const;
bool isOnScreen(int screen) const; // true if it's at least partially there
bool isOnOutput(AbstractOutput *output) const;
bool isOnActiveScreen() const;
int screen() const; // the screen where the center is
/**