From 8de7ad683388e0373b3687465c153a08e3ccf2e1 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 10 Mar 2015 16:59:08 +0100 Subject: Handle context loss in the threaded render loop Change-Id: I3f9219dd2fed15094c2f7d670a981406e601959b Reviewed-by: Gunnar Sletta --- src/quick/items/qquickwindow.cpp | 3 +++ src/quick/items/qquickwindow_p.h | 4 ++++ src/quick/scenegraph/qsgthreadedrenderloop.cpp | 14 ++++++++++++++ 3 files changed, 21 insertions(+) (limited to 'src/quick') diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index aabeefb317..35f4a84980 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1403,6 +1403,9 @@ bool QQuickWindow::event(QEvent *e) break; } + if (e->type() == QEvent::Type(QQuickWindowPrivate::FullUpdateRequest)) + update(); + return QWindow::event(e); } diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h index c3ae6c054c..a61c0b0346 100644 --- a/src/quick/items/qquickwindow_p.h +++ b/src/quick/items/qquickwindow_p.h @@ -101,6 +101,10 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate : public QWindowPrivate public: Q_DECLARE_PUBLIC(QQuickWindow) + enum CustomEvents { + FullUpdateRequest = QEvent::User + 1 + }; + static inline QQuickWindowPrivate *get(QQuickWindow *c) { return c->d_func(); } QQuickWindowPrivate(); diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 6974271dc7..e1a54810b7 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -490,6 +490,14 @@ void QSGRenderThread::sync(bool inExpose) bool current = false; if (windowSize.width() > 0 && windowSize.height() > 0) current = gl->makeCurrent(window); + // Check for context loss. + if (!current && !gl->isValid()) { + QQuickWindowPrivate::get(window)->cleanupNodesOnShutdown(); + sgrc->invalidate(); + current = gl->create() && gl->makeCurrent(window); + if (current) + sgrc->initialize(gl); + } if (current) { QQuickWindowPrivate *d = QQuickWindowPrivate::get(window); bool hadRenderer = d->renderer != 0; @@ -571,6 +579,12 @@ void QSGRenderThread::syncAndRender() bool current = false; if (d->renderer && windowSize.width() > 0 && windowSize.height() > 0) current = gl->makeCurrent(window); + // Check for context loss. + if (!current && !gl->isValid()) { + // Cannot do anything here because gui is not locked. Request a new + // sync+render round on the gui thread and let the sync handle it. + QCoreApplication::postEvent(window, new QEvent(QEvent::Type(QQuickWindowPrivate::FullUpdateRequest))); + } if (current) { d->renderSceneGraph(windowSize); if (profileFrames) -- cgit v1.2.3