diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2019-03-15 11:13:05 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2019-03-15 11:16:12 +0100 |
commit | c61a75cd6a4a9cd7b3594b205fcac8fc1208d493 (patch) | |
tree | f44126af3d0fa566d33e207a8fa2e94d63403022 | |
parent | 869b89bde8b0149a875e6e23466820f573e4a73c (diff) |
Fix leaking scene graph rendering contexts
When using the threaded render loop, the rendering thread assumes
ownership of the rendering context. If the rendering thread is never
started, that context is leaked. This happens in tests sometimes when we
create and destroy a window without waiting for exposure.
So this patch maintains the ownership in the render loop for created
contexts until the per-window thread is started.
Task-number: QTBUG-74348
Change-Id: Ifa397fab0833c82110ac4571c1e3790351c43afd
Reviewed-by: BogDan Vatra <bogdan@kdab.com>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop.cpp | 10 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgthreadedrenderloop_p.h | 3 |
2 files changed, 11 insertions, 2 deletions
diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index c18ba4226c..232ef77324 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -770,12 +770,15 @@ QSGThreadedRenderLoop::QSGThreadedRenderLoop() QSGThreadedRenderLoop::~QSGThreadedRenderLoop() { + qDeleteAll(pendingRenderContexts); delete sg; } QSGRenderContext *QSGThreadedRenderLoop::createRenderContext(QSGContext *sg) const { - return sg->createRenderContext(); + auto context = sg->createRenderContext(); + pendingRenderContexts.insert(context); + return context; } void QSGThreadedRenderLoop::maybePostPolishRequest(Window *w) @@ -935,7 +938,10 @@ void QSGThreadedRenderLoop::handleExposure(QQuickWindow *window) Window win; win.window = window; win.actualWindowFormat = window->format(); - win.thread = new QSGRenderThread(this, QQuickWindowPrivate::get(window)->context); + auto renderContext = QQuickWindowPrivate::get(window)->context; + // The thread assumes ownership, so we don't need to delete it later. + pendingRenderContexts.remove(renderContext); + win.thread = new QSGRenderThread(this, renderContext); win.updateDuringSync = false; win.forceRenderPass = true; // also covered by polishAndSync(inExpose=true), but doesn't hurt m_windows << win; diff --git a/src/quick/scenegraph/qsgthreadedrenderloop_p.h b/src/quick/scenegraph/qsgthreadedrenderloop_p.h index 32bfcb7148..b8fae8e8da 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop_p.h +++ b/src/quick/scenegraph/qsgthreadedrenderloop_p.h @@ -124,6 +124,9 @@ private: QSGContext *sg; + // Set of contexts that have been created but are now owned by + // a rendering thread yet, as the window has never been exposed. + mutable QSet<QSGRenderContext*> pendingRenderContexts; QAnimationDriver *m_animation_driver; QList<Window> m_windows; |