From 3f362cdf9304afeed06081cd5abfcaf6aaabe19e Mon Sep 17 00:00:00 2001 From: Gunnar Sletta <gunnar.sletta@jollamobile.com> Date: Fri, 14 Mar 2014 15:15:26 +0100 Subject: [PATCH] Fix potential crash during shutdown for QQuickWindows The cleanup() function would deregister the render loop from all windows the render loop had seen, but the render loop doesn't see windows until the window gets a showEvent and for some implementations it was removed as a result of hideEvent. So add explicit tracking to QSGRenderLoop which is managed by QQuickWindow's constructor and destructor. With this, we no longer need the lists from the subclasses, so these functions are removed again. Change-Id: I05e5507ad57e23c80bacd99752654cc7d0890dc1 Reviewed-by: Paul Olav Tvete <paul.tvete@digia.com> --- src/quick/designer/designerwindowmanager_p.h | 2 -- src/quick/items/qquickwindow.cpp | 7 +++++-- src/quick/scenegraph/qsgrenderloop.cpp | 2 -- src/quick/scenegraph/qsgrenderloop_p.h | 7 ++++++- src/quick/scenegraph/qsgthreadedrenderloop.cpp | 8 -------- src/quick/scenegraph/qsgthreadedrenderloop_p.h | 2 -- src/quick/scenegraph/qsgwindowsrenderloop.cpp | 9 --------- src/quick/scenegraph/qsgwindowsrenderloop_p.h | 2 -- 8 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/quick/designer/designerwindowmanager_p.h b/src/quick/designer/designerwindowmanager_p.h index 17a227d212..7414f4e3ba 100644 --- a/src/quick/designer/designerwindowmanager_p.h +++ b/src/quick/designer/designerwindowmanager_p.h @@ -93,8 +93,6 @@ public: QSGContext *sceneGraphContext() const; QSGRenderContext *createRenderContext(QSGContext *) const { return m_renderContext.data(); } - QList<QQuickWindow *> windows() const { return QList<QQuickWindow *>(); }; - static void createOpenGLContext(QQuickWindow *window); private: diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index b55761ba85..81001e19fa 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -452,6 +452,7 @@ void QQuickWindowPrivate::init(QQuickWindow *c, QQuickRenderControl *control) sg = renderControl->sceneGraphContext(); context = renderControl->renderContext(sg); } else { + windowManager->addWindow(q); sg = windowManager->sceneGraphContext(); context = windowManager->createRenderContext(sg); } @@ -1077,10 +1078,12 @@ QQuickWindow::~QQuickWindow() Q_D(QQuickWindow); d->animationController->deleteLater(); - if (d->renderControl) + if (d->renderControl) { d->renderControl->windowDestroyed(); - else if (d->windowManager) + } else if (d->windowManager) { + d->windowManager->removeWindow(this); d->windowManager->windowDestroyed(this); + } QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); delete d->incubationController; d->incubationController = 0; diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index bd9c7609ad..f3e879c354 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -126,8 +126,6 @@ public: QSGContext *sceneGraphContext() const; QSGRenderContext *createRenderContext(QSGContext *) const { return rc; } - QList<QQuickWindow *> windows() const { return m_windows.keys(); } - bool event(QEvent *); struct WindowData { diff --git a/src/quick/scenegraph/qsgrenderloop_p.h b/src/quick/scenegraph/qsgrenderloop_p.h index 47b59992e2..4a22fd60e7 100644 --- a/src/quick/scenegraph/qsgrenderloop_p.h +++ b/src/quick/scenegraph/qsgrenderloop_p.h @@ -44,6 +44,7 @@ #include <QtGui/QImage> #include <private/qtquickglobal_p.h> +#include <QtCore/QSet> QT_BEGIN_NAMESPACE @@ -78,7 +79,9 @@ public: virtual void releaseResources(QQuickWindow *window) = 0; - virtual QList<QQuickWindow *> windows() const = 0; + void addWindow(QQuickWindow *win) { m_windows.insert(win); } + void removeWindow(QQuickWindow *win) { m_windows.remove(win); } + QSet<QQuickWindow *> windows() const { return m_windows; } // ### make this less of a singleton static QSGRenderLoop *instance(); @@ -99,6 +102,8 @@ public Q_SLOTS: private: static QSGRenderLoop *s_instance; + + QSet<QQuickWindow *> m_windows; }; QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 3dc2a50542..ba8c3a7fce 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -738,14 +738,6 @@ QSGThreadedRenderLoop::QSGThreadedRenderLoop() QSG_GUI_DEBUG((void *) 0, "QSGThreadedRenderLoop() created"); } -QList<QQuickWindow *> QSGThreadedRenderLoop::windows() const -{ - QList<QQuickWindow *> list; - foreach (const Window &w, m_windows) - list << w.window; - return list; -} - QSGRenderContext *QSGThreadedRenderLoop::createRenderContext(QSGContext *sg) const { return sg->createRenderContext(); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index 3997ef92b7..e142f7f2c8 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -79,8 +79,6 @@ public: bool interleaveIncubation() const; - QList<QQuickWindow *> windows() const; - public Q_SLOTS: void animationStarted(); void animationStopped(); diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index cbe9ea384b..913b737798 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -111,15 +111,6 @@ QSGWindowsRenderLoop::~QSGWindowsRenderLoop() delete m_sg; } -QList<QQuickWindow *> QSGWindowsRenderLoop::windows() const -{ - QList<QQuickWindow *> list; - foreach (const WindowData &w, m_windows) - list << w.window; - return list; -} - - bool QSGWindowsRenderLoop::interleaveIncubation() const { return m_animationDriver->isRunning() && anyoneShowing(); diff --git a/src/quick/scenegraph/qsgwindowsrenderloop_p.h b/src/quick/scenegraph/qsgwindowsrenderloop_p.h index 6c26e728da..e4ee688c9f 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop_p.h +++ b/src/quick/scenegraph/qsgwindowsrenderloop_p.h @@ -86,8 +86,6 @@ public: bool interleaveIncubation() const; - QList<QQuickWindow *> windows() const; - public Q_SLOTS: void started(); void stopped(); -- GitLab