diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-11-27 13:50:46 +0100 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2019-11-28 10:55:09 +0100 |
commit | 2d559ec0e1fe9b50747bc648f4a4d3f5c0c8c46a (patch) | |
tree | 27c20334fe0e810948fa9365a5525fd03738f878 /src/quick/scenegraph | |
parent | df0cb0edac85db1fe12442d332bafc1d508bc3ae (diff) |
Prevent infinite rhi init failure in basic render loop
Task-number: QTBUG-80365
Change-Id: Iaa2f97b02c4665f0485226d9aa420993330d78f8
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
Diffstat (limited to 'src/quick/scenegraph')
-rw-r--r-- | src/quick/scenegraph/qsgrenderloop.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index da6e524623..5be7fbefe3 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -195,8 +195,16 @@ public: bool eventFilter(QObject *watched, QEvent *event) override; struct WindowData { + WindowData() + : updatePending(false), + grabOnly(false), + rhiDeviceLost(false), + rhiDoomed(false) + { } bool updatePending : 1; bool grabOnly : 1; + bool rhiDeviceLost : 1; + bool rhiDoomed : 1; }; QHash<QQuickWindow *, WindowData> m_windows; @@ -362,10 +370,7 @@ QSGGuiThreadRenderLoop::~QSGGuiThreadRenderLoop() void QSGGuiThreadRenderLoop::show(QQuickWindow *window) { - WindowData data; - data.updatePending = false; - data.grabOnly = false; - m_windows[window] = data; + m_windows[window] = WindowData(); maybeUpdate(window); } @@ -451,8 +456,10 @@ void QSGGuiThreadRenderLoop::handleDeviceLoss() rc->invalidate(); - for (auto it = m_windows.constBegin(), itEnd = m_windows.constEnd(); it != itEnd; ++it) + for (auto it = m_windows.begin(), itEnd = m_windows.end(); it != itEnd; ++it) { releaseSwapchain(it.key()); + it->rhiDeviceLost = true; + } delete rhi; rhi = nullptr; @@ -508,6 +515,13 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) const bool enableRhi = rhiSupport->isRhiEnabled(); if (enableRhi && !rhi) { + // This block below handles both the initial QRhi initialization and + // also the subsequent reinitialization attempts after a device lost + // (reset) situation. + + if (data.rhiDoomed) // no repeated attempts if the initial attempt failed + return; + if (!offscreenSurface) offscreenSurface = rhiSupport->maybeCreateOffscreenSurface(window); @@ -517,6 +531,8 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) if (rhiSupport->isProfilingRequested()) QSGRhiProfileConnection::instance()->initialize(rhi); + data.rhiDeviceLost = false; + current = true; rhi->makeThreadLocalNativeContextCurrent(); @@ -533,7 +549,11 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) rcParams.maybeSurface = window; cd->context->initialize(&rcParams); } else { - handleContextCreationFailure(window, false); + if (!data.rhiDeviceLost) { + data.rhiDoomed = true; + handleContextCreationFailure(window, false); + } + // otherwise no error, will retry on a subsequent rendering attempt } } else if (!enableRhi && !gl) { gl = new QOpenGLContext(); @@ -619,7 +639,7 @@ void QSGGuiThreadRenderLoop::renderWindow(QQuickWindow *window) i++; } - // Check for context loss. + // Check for context loss. (legacy GL only) if (!current && !rhi && !gl->isValid()) { for (auto it = m_windows.constBegin() ; it != m_windows.constEnd(); it++) { QQuickWindowPrivate *windowPrivate = QQuickWindowPrivate::get(it.key()); |