diff --git a/src/quick3d/qquick3dviewport.cpp b/src/quick3d/qquick3dviewport.cpp
index 772cccede851ecce0a3be9e1d5f8d1eaff63fe26..0dc56b8ef51b623b694f652ce6040b0487a1e890 100644
--- a/src/quick3d/qquick3dviewport.cpp
+++ b/src/quick3d/qquick3dviewport.cpp
@@ -111,7 +111,6 @@ QQuick3DViewport::~QQuick3DViewport()
     if (sceneManager)
         sceneManager->setParent(nullptr);
     delete m_sceneRoot;
-    delete m_directRenderer;
 }
 
 static void ssgn_append(QQmlListProperty<QObject> *property, QObject *obj)
@@ -283,11 +282,31 @@ QSGTextureProvider *QQuick3DViewport::textureProvider() const
     return m_node;
 }
 
+class CleanupJob : public QRunnable
+{
+public:
+    CleanupJob(QQuick3DSGDirectRenderer *renderer) : m_renderer(renderer) { }
+    void run() override { delete m_renderer; }
+private:
+    QQuick3DSGDirectRenderer *m_renderer;
+};
+
 void QQuick3DViewport::releaseResources()
 {
+    if (m_directRenderer) {
+        window()->scheduleRenderJob(new CleanupJob(m_directRenderer), QQuickWindow::BeforeSynchronizingStage);
+        m_directRenderer = nullptr;
+    }
+
     m_node = nullptr;
 }
 
+void QQuick3DViewport::cleanupDirectRenderer()
+{
+    delete m_directRenderer;
+    m_directRenderer = nullptr;
+}
+
 void QQuick3DViewport::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
 {
     QQuickItem::geometryChanged(newGeometry, oldGeometry);
@@ -613,8 +632,10 @@ void QQuick3DViewport::setupDirectRenderer(RenderMode mode)
 {
     auto renderMode = (mode == Underlay) ? QQuick3DSGDirectRenderer::Underlay
                                          : QQuick3DSGDirectRenderer::Overlay;
-    if (!m_directRenderer)
+    if (!m_directRenderer) {
         m_directRenderer = new QQuick3DSGDirectRenderer(createRenderer(), window(), renderMode);
+        connect(window(), &QQuickWindow::sceneGraphInvalidated, this, &QQuick3DViewport::cleanupDirectRenderer, Qt::DirectConnection);
+    }
     const QSizeF targetSize = window()->effectiveDevicePixelRatio() * QSizeF(width(), height());
     m_directRenderer->renderer()->synchronize(this, targetSize.toSize(), false);
     m_directRenderer->setViewport(QRectF(window()->effectiveDevicePixelRatio() * mapToScene(QPointF(0, 0)), targetSize));
diff --git a/src/quick3d/qquick3dviewport_p.h b/src/quick3d/qquick3dviewport_p.h
index e569549e8b358c65b541f8dea2004a96fc4a6a57..52dff7fb3efb17516ea58c15ccf94d918bf3f4a1 100644
--- a/src/quick3d/qquick3dviewport_p.h
+++ b/src/quick3d/qquick3dviewport_p.h
@@ -117,6 +117,7 @@ public Q_SLOTS:
     void setEnvironment(QQuick3DSceneEnvironment * environment);
     void setImportScene(QQuick3DNode *inScene);
     void setRenderMode(RenderMode renderMode);
+    void cleanupDirectRenderer();
 
 private Q_SLOTS:
     void invalidateSceneGraph();