[Development] Is QGLWidget broken on Qt4/QPA?

Samuel Rødal samuel.rodal at digia.com
Wed Jan 2 09:31:21 CET 2013


On 12/19/2012 05:34 PM, Rafael Roquetto wrote:
> Hello,
>
> I think I might have stumbled upon a bug in QGLWidget affecting QPA platforms.
> This happens at least in BlackBerry, but I suspect it is a general issue.
>
> When a QGLWidget is instantiated, a new native window is created once
> Q[GL]Widget::winId() is called. This ultimately leads to a call to
> QWidgetPrivate::create_sys(). This method tries to acquire a native window and
> a backing store for the newly created QGLWidget. Creating the window by
> calling QPlatformIntegration::createPlatformWindow() works as expected.
> Then, before trying to directly call
> QPlatformIntegration::createWindowSurface(), it first tries to get hold of an
> existent surface, by calling QWidget::windowSurface(); Now if that returned 0,
> it would proceed to create a new surface through
> QPlatformIntegration::createWindowSurface(). But in practice it does not.
> The relevant part of QWidget::windowSurface() tries to get the backing store
> by invoking d->maybeBackingStore(), which in turns calls
> q->window()->d_func()->maybeTopData()*!
>
>      * this is exactly where the problem lies: window() will iterate the widget
>      tree until it reaches the toplevel widget, which effectively has a window
>      associated to it, and then return its backing store.
>
> This means that the backing store being handed to QGLWidget is that of the
> current toplevel window, and not a newly created backing store to be
> associated with the newly created window for QGLWidget. In the case of
> BlackBerry, this is causing QGLWidget to use a raster surface
> (QBBRasterSurface) rather than a gl surface (QBBGLSurface). This may also
> affect the Wayland plugin:
>
> QWindowSurface *QWaylandIntegration::createWindowSurface(QWidget *widget, WId winId) const
> {
>      Q_UNUSED(winId);
>      Q_UNUSED(winId);
> #ifdef QT_WAYLAND_GL_SUPPORT
>      bool useOpenGL = mUseOpenGL || (widget->platformWindowFormat().windowApi() == QPlatformWindowFormat::OpenGL);
>      if (useOpenGL)
>          return new QWaylandGLWindowSurface(widget);
> #endif
>      return new QWaylandShmWindowSurface(widget);
> }
>
> If by default the integration is using QWaylandShmWindowSurface, this will
> cause QGLWidget to use it instead of QWaylandGLWindowSurface.
>
> Now, I am not sure if I got the code right, so I would like to ask: am I
> missing something or could this really be an issue?

You might be missing that a QGLWidget isn't used in combination with the 
backing store :)

Painting happens with raw OpenGL directly to the QGLWidget and is 
flushed when QGLWidget::swapBuffers() is called. It's of course possible 
to use QPainter but in the end that will also get translated to OpenGL.

In Qt 5, QBackingStore and QOpenGLContext are two pretty much separate 
ways of rendering to a QWindow.

--
Samuel



More information about the Development mailing list