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
This commit is contained in:
Martin Gräßlin 2016-08-18 16:03:26 +02:00
parent 71c996fe33
commit fe8fc6f83d
3 changed files with 13 additions and 9 deletions

View file

@ -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
//****************************************

View file

@ -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
{

View file

@ -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<AbstractClient*>(m_topLevel)) {