Commit 47ea0c98 authored by Vlad Zahorodnii's avatar Vlad Zahorodnii
Browse files

scene: Stop monitoring changes for unmapped surfaces

Once the main surface has been unmapped, we are no longer interested in
any changes that indicate that the window quads cache should be discarded

This also fixes a bug where the scene holds a subsurface monitor object
even after the associated window has been destroyed.
parent 3d43f8ad
......@@ -422,30 +422,6 @@ void Scene::addToplevel(Toplevel *c)
m_windows[ c ] = w;
connect(c, &Toplevel::windowClosed, this, &Scene::windowClosed);
if (c->surface()) {
// We generate window quads for sub-surfaces so it's quite important to discard
// the pixmap tree and cached window quads when the sub-surface tree is changed.
SubSurfaceMonitor *monitor = new SubSurfaceMonitor(c->surface(), this);
// TODO(vlad): Is there a more efficient way to manage window pixmap trees?
connect(monitor, &SubSurfaceMonitor::subSurfaceAdded, w, &Window::discardPixmap);
connect(monitor, &SubSurfaceMonitor::subSurfaceRemoved, w, &Window::discardPixmap);
connect(monitor, &SubSurfaceMonitor::subSurfaceMapped, w, &Window::discardPixmap);
connect(monitor, &SubSurfaceMonitor::subSurfaceUnmapped, w, &Window::discardPixmap);
connect(monitor, &SubSurfaceMonitor::subSurfaceBufferSizeChanged, w, &Window::discardPixmap);
connect(monitor, &SubSurfaceMonitor::subSurfaceAdded, w, &Window::discardQuads);
connect(monitor, &SubSurfaceMonitor::subSurfaceRemoved, w, &Window::discardQuads);
connect(monitor, &SubSurfaceMonitor::subSurfaceMoved, w, &Window::discardQuads);
connect(monitor, &SubSurfaceMonitor::subSurfaceResized, w, &Window::discardQuads);
connect(monitor, &SubSurfaceMonitor::subSurfaceMapped, w, &Window::discardQuads);
connect(monitor, &SubSurfaceMonitor::subSurfaceUnmapped, w, &Window::discardQuads);
connect(monitor, &SubSurfaceMonitor::subSurfaceSurfaceToBufferMatrixChanged, w, &Window::discardQuads);
connect(c->surface(), &KWaylandServer::SurfaceInterface::bufferSizeChanged, w, &Window::discardPixmap);
connect(c->surface(), &KWaylandServer::SurfaceInterface::surfaceToBufferMatrixChanged, w, &Window::discardQuads);
}
connect(c, &Toplevel::screenScaleChanged, w, &Window::discardQuads);
connect(c, &Toplevel::shadowChanged, w, &Window::discardQuads);
connect(c, &Toplevel::geometryShapeChanged, w, &Window::discardShape);
......@@ -749,6 +725,45 @@ Scene::Window::Window(Toplevel *client, QObject *parent)
connect(screens(), &Screens::countChanged, this, &Window::reallocRepaints);
}
reallocRepaints();
KWaylandServer::SurfaceInterface *surface = toplevel->surface();
if (surface) {
// We generate window quads for sub-surfaces so it's quite important to discard
// the pixmap tree and cached window quads when the sub-surface tree is changed.
m_subsurfaceMonitor = new SubSurfaceMonitor(surface, this);
// TODO(vlad): Is there a more efficient way to manage window pixmap trees?
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceAdded,
this, &Window::discardPixmap);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceRemoved,
this, &Window::discardPixmap);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceMapped,
this, &Window::discardPixmap);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceUnmapped,
this, &Window::discardPixmap);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceBufferSizeChanged,
this, &Window::discardPixmap);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceAdded,
this, &Window::discardQuads);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceRemoved,
this, &Window::discardQuads);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceMoved,
this, &Window::discardQuads);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceResized,
this, &Window::discardQuads);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceMapped,
this, &Window::discardQuads);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceUnmapped,
this, &Window::discardQuads);
connect(m_subsurfaceMonitor, &SubSurfaceMonitor::subSurfaceSurfaceToBufferMatrixChanged,
this, &Window::discardQuads);
connect(surface, &KWaylandServer::SurfaceInterface::bufferSizeChanged,
this, &Window::discardPixmap);
connect(surface, &KWaylandServer::SurfaceInterface::surfaceToBufferMatrixChanged,
this, &Window::discardQuads);
}
}
Scene::Window::~Window()
......@@ -763,6 +778,19 @@ Scene::Window::~Window()
delete m_shadow;
}
void Scene::Window::updateToplevel(Deleted *deleted)
{
delete m_subsurfaceMonitor;
m_subsurfaceMonitor = nullptr;
KWaylandServer::SurfaceInterface *surface = toplevel->surface();
if (surface) {
disconnect(surface, nullptr, this, nullptr);
}
toplevel = deleted;
}
void Scene::Window::referencePreviousPixmap()
{
if (!m_previousPixmap.isNull() && m_previousPixmap->isDiscarded()) {
......
......@@ -43,6 +43,7 @@ class Shadow;
class WindowPixmap;
class GLTexture;
class AbstractOutput;
class SubSurfaceMonitor;
// The base class for compositing backends.
class KWIN_EXPORT Scene : public QObject
......@@ -349,7 +350,7 @@ public:
QRegion decorationShape() const;
QPoint bufferOffset() const;
void discardShape();
void updateToplevel(Toplevel* c);
void updateToplevel(Deleted *deleted);
// creates initial quad list for the window
virtual WindowQuadList buildQuads(bool force = false) const;
void updateShadow(Shadow* shadow);
......@@ -407,6 +408,7 @@ private:
QScopedPointer<WindowPixmap> m_previousPixmap;
QVector<QRegion> m_repaints;
QVector<QRegion> m_layerRepaints;
SubSurfaceMonitor *m_subsurfaceMonitor = nullptr;
int m_referencePixmapCounter;
int disable_painting;
mutable QRegion m_bufferShape;
......@@ -677,12 +679,6 @@ Toplevel* Scene::Window::window() const
return toplevel;
}
inline
void Scene::Window::updateToplevel(Toplevel* c)
{
toplevel = c;
}
inline
const Shadow* Scene::Window::shadow() const
{
......
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