Reinitialize in QQuickWidget properly after hide and show
authorLaszlo Agocs <laszlo.agocs@digia.com>
Tue, 12 Aug 2014 08:10:30 +0000 (10:10 +0200)
committerLaszlo Agocs <laszlo.agocs@digia.com>
Thu, 14 Aug 2014 09:02:37 +0000 (11:02 +0200)
hide() followed by a show() results in totally broken QQuickWidgets due
to not initializing scenegraph again.

Task-number: QTBUG-40710
Change-Id: Id3cded2917d20c165b5885f3f2195d5c4566de89
Reviewed-by: Gunnar Sletta <gunnar.sletta@jollamobile.com>
src/quickwidgets/qquickwidget.cpp

index 0a52198..7aef165 100644 (file)
@@ -218,7 +218,7 @@ void QQuickWidgetPrivate::renderSceneGraph()
 
     QOpenGLContext *context = offscreenWindow->openglContext();
     if (!context) {
-        qWarning("QQuickWidget: render scenegraph with no context");
+        qWarning("QQuickWidget: Attempted to render scene with no context");
         return;
     }
 
@@ -634,33 +634,40 @@ void QQuickWidgetPrivate::handleContextCreationFailure(const QSurfaceFormat &for
 
 void QQuickWidgetPrivate::createContext()
 {
-    if (context)
-        return;
-
-    context = new QOpenGLContext;
-    context->setFormat(offscreenWindow->requestedFormat());
+    // On hide-show we invalidate() but our context is kept.
+    // We nonetheless need to initialize() again.
+    const bool reinit = context && !offscreenWindow->openglContext();
+
+    if (!reinit) {
+        if (context)
+            return;
+
+        context = new QOpenGLContext;
+        context->setFormat(offscreenWindow->requestedFormat());
+
+        if (qt_gl_global_share_context())
+            context->setShareContext(qt_gl_global_share_context());
+
+        if (!context->create()) {
+            const bool isEs = context->isOpenGLES();
+            delete context;
+            context = 0;
+            handleContextCreationFailure(offscreenWindow->requestedFormat(), isEs);
+            return;
+        }
 
-    if (qt_gl_global_share_context())
-        context->setShareContext(qt_gl_global_share_context());
-    if (!context->create()) {
-        const bool isEs = context->isOpenGLES();
-        delete context;
-        context = 0;
-        handleContextCreationFailure(offscreenWindow->requestedFormat(), isEs);
-        return;
+        offscreenSurface = new QOffscreenSurface;
+        // Pass the context's format(), which, now that the underlying platform context is created,
+        // contains a QSurfaceFormat representing the _actual_ format of the underlying
+        // configuration. This is essential to get a surface that is compatible with the context.
+        offscreenSurface->setFormat(context->format());
+        offscreenSurface->create();
     }
 
-    offscreenSurface = new QOffscreenSurface;
-    // Pass the context's format(), which, now that the underlying platform context is created,
-    // contains a QSurfaceFormat representing the _actual_ format of the underlying
-    // configuration. This is essential to get a surface that is compatible with the context.
-    offscreenSurface->setFormat(context->format());
-    offscreenSurface->create();
-
     if (context->makeCurrent(offscreenSurface))
         renderControl->initialize(context);
     else
-        qWarning("QQuickWidget: failed to make window surface current");
+        qWarning("QQuickWidget: Failed to make context current");
 }
 
 void QQuickWidgetPrivate::destroyContext()