diff --git a/main_wayland.cpp b/main_wayland.cpp --- a/main_wayland.cpp +++ b/main_wayland.cpp @@ -121,8 +121,8 @@ return; } - if (kwinApp()->platform()) { - kwinApp()->platform()->setOutputsEnabled(false); + if (auto *platform = kwinApp()->platform()) { + platform->prepareShutdown(); } // need to unload all effects prior to destroying X connection as they might do X calls if (effects) { diff --git a/platform.h b/platform.h --- a/platform.h +++ b/platform.h @@ -86,6 +86,14 @@ virtual Screens *createScreens(QObject *parent = nullptr); virtual OpenGLBackend *createOpenGLBackend(); virtual QPainterBackend *createQPainterBackend(); + + /** + * Informs the Platform that it is about to go down and shall do appropriate cleanup. + * Child classes can override this function but must call the parent implementation in + * the end. + */ + virtual void prepareShutdown(); + /** * Allows the platform to create a platform specific screen edge. * The default implementation creates a Edge. @@ -390,6 +398,7 @@ * Default implementation creates an EffectsHandlerImp; */ virtual void createEffectsHandler(Compositor *compositor, Scene *scene); + /** * The CompositingTypes supported by the Platform. * The first item should be the most preferred one. diff --git a/platform.cpp b/platform.cpp --- a/platform.cpp +++ b/platform.cpp @@ -106,6 +106,11 @@ return nullptr; } +void Platform::prepareShutdown() +{ + setOutputsEnabled(false); +} + Edge *Platform::createScreenEdge(ScreenEdges *edges) { return new Edge(edges); diff --git a/plugins/platforms/drm/drm_backend.h b/plugins/platforms/drm/drm_backend.h --- a/plugins/platforms/drm/drm_backend.h +++ b/plugins/platforms/drm/drm_backend.h @@ -81,6 +81,8 @@ OpenGLBackend* createOpenGLBackend() override; void init() override; + void prepareShutdown() override; + DrmDumbBuffer *createBuffer(const QSize &size); #if HAVE_GBM DrmSurfaceBuffer *createBuffer(const std::shared_ptr &surface); diff --git a/plugins/platforms/drm/drm_backend.cpp b/plugins/platforms/drm/drm_backend.cpp --- a/plugins/platforms/drm/drm_backend.cpp +++ b/plugins/platforms/drm/drm_backend.cpp @@ -87,7 +87,6 @@ DrmBackend::~DrmBackend() { - writeOutputsConfiguration(); #if HAVE_GBM if (m_gbmDevice) { gbm_device_destroy(m_gbmDevice); @@ -98,10 +97,6 @@ while (m_pageFlipsPending != 0) { QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); } - // we need to first remove all outputs - qDeleteAll(m_outputs); - m_outputs.clear(); - m_enabledOutputs.clear(); qDeleteAll(m_planes); qDeleteAll(m_crtcs); @@ -128,6 +123,15 @@ } } +void DrmBackend::prepareShutdown() +{ + writeOutputsConfiguration(); + for (DrmOutput *output : m_outputs) { + output->teardown(); + } + Platform::prepareShutdown(); +} + Outputs DrmBackend::outputs() const { return m_outputs; diff --git a/plugins/platforms/drm/drm_output.cpp b/plugins/platforms/drm/drm_output.cpp --- a/plugins/platforms/drm/drm_output.cpp +++ b/plugins/platforms/drm/drm_output.cpp @@ -59,13 +59,14 @@ DrmOutput::~DrmOutput() { Q_ASSERT(!m_pageFlipPending); - if (!m_deleted) { - teardown(); - } + teardown(); } void DrmOutput::teardown() { + if (m_deleted) { + return; + } m_deleted = true; hideCursor(); m_crtc->blank();