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.
This commit is contained in:
parent
3d43f8ad93
commit
47ea0c98b1
2 changed files with 55 additions and 31 deletions
76
scene.cpp
76
scene.cpp
|
@ -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()) {
|
||||
|
|
10
scene.h
10
scene.h
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue