Prevent windows outside the gui thread in rendercontrol example
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>
Tue, 16 Dec 2014 11:49:08 +0000 (12:49 +0100)
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>
Wed, 7 Jan 2015 12:21:00 +0000 (13:21 +0100)
In the multithreaded case we attempted to create QWindows outside
the gui thread on platforms where QOffscreenSurface is backed by
the hidden QWindow in the absence of a better solution. This has
to be avoided. Therefore, pass a suitable surface from the gui
thread instead.

This will avoid "Attempting to create QWindow-based QOffscreenSurface
outside the gui thread." type of warnings when running on OS X with
--threaded.

Change-Id: Ie3ebeeeaa9e6bdf83e763e40213e2940fbfde667
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>
Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
examples/quick/rendercontrol/cuberenderer.cpp
examples/quick/rendercontrol/cuberenderer.h
examples/quick/rendercontrol/window_multithreaded.cpp
examples/quick/rendercontrol/window_singlethreaded.cpp

index c385d46..02d925b 100644 (file)
@@ -48,8 +48,9 @@
 #include <QOffscreenSurface>
 #include <QWindow>
 
-CubeRenderer::CubeRenderer()
-    : m_context(0),
+CubeRenderer::CubeRenderer(QOffscreenSurface *offscreenSurface)
+    : m_offscreenSurface(offscreenSurface),
+      m_context(0),
       m_program(0),
       m_vbo(0)
 {
@@ -59,10 +60,7 @@ CubeRenderer::~CubeRenderer()
 {
     // Use a temporary offscreen surface to do the cleanup.
     // There may not be a native window surface available anymore at this stage.
-    QScopedPointer<QOffscreenSurface> offscreenSurface(new QOffscreenSurface);
-    offscreenSurface->setFormat(m_context->format());
-    offscreenSurface->create();
-    m_context->makeCurrent(offscreenSurface.data());
+    m_context->makeCurrent(m_offscreenSurface);
 
     delete m_program;
     delete m_vbo;
index 8f98376..1d5400a 100644 (file)
@@ -48,11 +48,12 @@ QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)
 QT_FORWARD_DECLARE_CLASS(QOpenGLBuffer)
 QT_FORWARD_DECLARE_CLASS(QOpenGLVertexArrayObject)
 QT_FORWARD_DECLARE_CLASS(QWindow)
+QT_FORWARD_DECLARE_CLASS(QOffscreenSurface)
 
 class CubeRenderer
 {
 public:
-    CubeRenderer();
+    CubeRenderer(QOffscreenSurface *offscreenSurface);
     ~CubeRenderer();
 
     void resize(int w, int h);
@@ -62,6 +63,7 @@ private:
     void init(QWindow *w, QOpenGLContext *share);
     void setupVertexAttribs();
 
+    QOffscreenSurface *m_offscreenSurface;
     QOpenGLContext *m_context;
     QOpenGLShaderProgram *m_program;
     QOpenGLBuffer *m_vbo;
index ad26184..2248105 100644 (file)
@@ -130,7 +130,11 @@ void QuickRenderer::init()
 {
     m_context->makeCurrent(m_surface);
 
-    m_cubeRenderer = new CubeRenderer;
+    // Pass our offscreen surface to the cube renderer just so that it will
+    // have something is can make current during cleanup. QOffscreenSurface,
+    // just like QWindow, must always be created on the gui thread (as it might
+    // be backed by an actual QWindow).
+    m_cubeRenderer = new CubeRenderer(m_surface);
     m_cubeRenderer->resize(m_window->width(), m_window->height());
 
     m_renderControl->initialize(m_context);
index 454b06f..8ed3f55 100644 (file)
@@ -81,7 +81,7 @@ WindowSingleThreaded::WindowSingleThreaded()
     m_offscreenSurface->setFormat(m_context->format());
     m_offscreenSurface->create();
 
-    m_cubeRenderer = new CubeRenderer;
+    m_cubeRenderer = new CubeRenderer(m_offscreenSurface);
 
     m_renderControl = new QQuickRenderControl(this);
 
@@ -129,10 +129,10 @@ WindowSingleThreaded::~WindowSingleThreaded()
 
     m_context->doneCurrent();
 
+    delete m_cubeRenderer;
+
     delete m_offscreenSurface;
     delete m_context;
-
-    delete m_cubeRenderer;
 }
 
 void WindowSingleThreaded::createFbo()