From c61a75cd6a4a9cd7b3594b205fcac8fc1208d493 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 15 Mar 2019 11:13:05 +0100 Subject: 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 Reviewed-by: Ulf Hermann --- src/quick/scenegraph/qsgthreadedrenderloop.cpp | 10 ++++++++-- 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 pendingRenderContexts; QAnimationDriver *m_animation_driver; QList m_windows; -- cgit v1.2.3