From fe8fc6f83d3a567b0774b433df011f899f7230d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Thu, 18 Aug 2016 16:03:26 +0200 Subject: [PATCH] Ensure to directly delete old Shadow on update Summary: So far when deleting a Shadow we used deleteLater which caused it to be deleted in the next event cycle. This could in worst case result in the Shadow being deleted after compositing got suspended. Thus the Shadow not getting removed from the DecorationShadowCache which in turn would mess up rendering on resume of compositing as the cache returns a texture created for a different context. BUG: 361154 FIXED-IN: 5.7.4 Reviewers: #kwin, #plasma Subscribers: kwin Tags: #kwin Differential Revision: https://phabricator.kde.org/D2483 --- scene.cpp | 9 +++++++++ scene.h | 6 ------ shadow.cpp | 7 ++++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/scene.cpp b/scene.cpp index 834a731e60..3415ed73e4 100644 --- a/scene.cpp +++ b/scene.cpp @@ -928,6 +928,15 @@ WindowQuadList Scene::Window::makeQuads(WindowQuadType type, const QRegion& reg, return ret; } +void Scene::Window::updateShadow(Shadow* shadow) +{ + if (m_shadow == shadow) { + return; + } + delete m_shadow; + m_shadow = shadow; +} + //**************************************** // WindowPixmap //**************************************** diff --git a/scene.h b/scene.h index 3cdafc28f0..1ce7b18faa 100644 --- a/scene.h +++ b/scene.h @@ -537,12 +537,6 @@ void Scene::Window::suspendUnredirect(bool suspend) toplevel->suspendUnredirect(suspend); } -inline -void Scene::Window::updateShadow(Shadow* shadow) -{ - m_shadow = shadow; -} - inline const Shadow* Scene::Window::shadow() const { diff --git a/shadow.cpp b/shadow.cpp index 405ca064e7..0f647c7744 100644 --- a/shadow.cpp +++ b/shadow.cpp @@ -337,10 +337,11 @@ bool Shadow::updateShadow() auto clear = [this]() { if (m_topLevel && m_topLevel->effectWindow() && m_topLevel->effectWindow()->sceneWindow() && m_topLevel->effectWindow()->sceneWindow()->shadow()) { - m_topLevel->effectWindow()->sceneWindow()->updateShadow(0); - m_topLevel->effectWindow()->buildQuads(true); + auto w = m_topLevel->effectWindow(); + // this also deletes the shadow + w->sceneWindow()->updateShadow(nullptr); + w->buildQuads(true); } - deleteLater(); }; if (m_decorationShadow) { if (AbstractClient *c = qobject_cast(m_topLevel)) {