aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2019-03-15 11:13:05 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2019-03-15 11:16:12 +0100
commitc61a75cd6a4a9cd7b3594b205fcac8fc1208d493 (patch)
treef44126af3d0fa566d33e207a8fa2e94d63403022
parent869b89bde8b0149a875e6e23466820f573e4a73c (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.cpp10
-rw-r--r--src/quick/scenegraph/qsgthreadedrenderloop_p.h3
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;