Don't destroy DecorationRenderer in setup/finish compositing

Summary:
Currently, KWin/Wayland crashes when the compositor is reinitialized.
The reason for that is ShellClient's DecorationRenderer gets destroyed
when the scene is already gone, thus there is no current OpenGL context.
Client works around that issue by destroying scene-specific DecorationRender
in finishCompositing. Such a workaround could be applied to ShellClient
as well, but it would make code more confusing because DecoratedClientImpl
also tries to destroy DecorationRenderer.

A better approach would be to notify DecoratedClientImpl that
compositing is about to be finished, so it can destroy the decoration
renderer when the scene is still alive. This not only fixes the
previously mentioned issue in ShellClient, but also makes code a little
bit tidier.

Test Plan:
Start Plasma on Wayland session, change any compositor settings (e.g.
animation speed).

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: davidedmundson, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D18921
This commit is contained in:
Vlad Zagorodniy 2019-02-20 15:09:37 +02:00
parent 0f514e94a5
commit 9a68cbd9b1
4 changed files with 7 additions and 11 deletions

View file

@ -201,6 +201,8 @@ void Compositor::slotCompositingOptionsInitialized()
}
}
emit aboutToToggleCompositing();
auto supportedCompositors = kwinApp()->platform()->supportedCompositors();
const auto userConfigIt = std::find(supportedCompositors.begin(), supportedCompositors.end(), options->compositingMode());
if (userConfigIt != supportedCompositors.end()) {
@ -373,6 +375,8 @@ void Compositor::finish()
m_finishing = true;
m_releaseSelectionTimer.start();
emit aboutToToggleCompositing();
// Some effects might need access to effect windows when they are about to
// be destroyed, for example to unreference deleted windows, so we have to
// make sure that effect windows outlive effects.
@ -1192,9 +1196,6 @@ bool Client::setupCompositing()
if (!Toplevel::setupCompositing()){
return false;
}
if (isDecorated()) {
decoratedClient()->destroyRenderer();
}
updateVisibility(); // for internalKeep()
return true;
}
@ -1203,11 +1204,6 @@ void Client::finishCompositing(ReleaseReason releaseReason)
{
Toplevel::finishCompositing(releaseReason);
updateVisibility();
if (!deleting) {
if (isDecorated()) {
decoratedClient()->destroyRenderer();
}
}
// for safety in case KWin is just resizing the window
resetHaveResizeEffect();
}

View file

@ -176,6 +176,7 @@ public Q_SLOTS:
Q_SIGNALS:
void compositingToggled(bool active);
void aboutToDestroy();
void aboutToToggleCompositing();
void sceneCreated();
protected:

View file

@ -87,10 +87,9 @@ DecoratedClientImpl::DecoratedClientImpl(AbstractClient *client, KDecoration2::D
&Decoration::DecoratedClientImpl::signalShadeChange);
connect(client, &AbstractClient::keepAboveChanged, decoratedClient, &KDecoration2::DecoratedClient::keepAboveChanged);
connect(client, &AbstractClient::keepBelowChanged, decoratedClient, &KDecoration2::DecoratedClient::keepBelowChanged);
connect(Compositor::self(), &Compositor::aboutToToggleCompositing, this, &DecoratedClientImpl::destroyRenderer);
m_compositorToggledConnection = connect(Compositor::self(), &Compositor::compositingToggled, this,
[this, decoration]() {
delete m_renderer;
m_renderer = nullptr;
createRenderer();
decoration->update();
}

View file

@ -95,7 +95,6 @@ public:
Renderer *renderer() {
return m_renderer;
}
void destroyRenderer();
KDecoration2::DecoratedClient *decoratedClient() {
return KDecoration2::DecoratedClientPrivate::client();
}
@ -107,6 +106,7 @@ private Q_SLOTS:
private:
void createRenderer();
void destroyRenderer();
AbstractClient *m_client;
QSize m_clientSize;
Renderer *m_renderer;