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 @@ -400,7 +400,7 @@ it = m_outputs.erase(it); m_enabledOutputs.removeOne(removed); emit outputRemoved(removed); - delete removed; + removed->teardown(); } // now check new connections diff --git a/plugins/platforms/drm/drm_output.h b/plugins/platforms/drm/drm_output.h --- a/plugins/platforms/drm/drm_output.h +++ b/plugins/platforms/drm/drm_output.h @@ -64,7 +64,10 @@ QByteArray serialNumber; QSize physicalSize; }; - virtual ~DrmOutput(); + ///deletes the output, calling this whilst a page flip is pending will result in an error + ~DrmOutput() override; + ///queues deleting the output after a page flip has completed. + void teardown(); void releaseGbm(); bool showCursor(DrmDumbBuffer *buffer); bool showCursor(); @@ -144,6 +147,7 @@ friend class DrmCrtc; // TODO: For use of setModeLegacy. Remove later when we allow multiple connectors per crtc // and save the connector ids in the DrmCrtc instance. DrmOutput(DrmBackend *backend); + bool presentAtomically(DrmBuffer *buffer); enum class AtomicCommitMode { @@ -212,6 +216,7 @@ int m_cursorIndex = 0; bool m_hasNewCursor = false; bool m_internal = false; + bool m_deleted = false; }; } 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 @@ -64,6 +64,15 @@ DrmOutput::~DrmOutput() { + Q_ASSERT(!m_pageFlipPending); + if (!m_deleted) { + teardown(); + } +} + +void DrmOutput::teardown() +{ + m_deleted = true; hideCursor(); m_crtc->blank(); @@ -84,6 +93,10 @@ delete m_waylandOutputDevice.data(); delete m_cursor[0]; delete m_cursor[1]; + if (!m_pageFlipPending) { + deleteLater(); + } //else will be deleted in the page flip handler + //this is needed so that the pageflipcallback handle isn't deleted } void DrmOutput::releaseGbm() @@ -930,6 +943,10 @@ void DrmOutput::pageFlipped() { m_pageFlipPending = false; + if (m_deleted) { + deleteLater(); + return; + } if (!m_crtc) { return;