[Interest] Utilizing the GPU, how to start?

Thiago Macieira thiago.macieira at intel.com
Wed Jul 6 08:58:48 CEST 2016

On quarta-feira, 6 de julho de 2016 00:56:04 PDT Scott Aron Bloom wrote:
> Stop using QtWidgets, including QtWebView and QLabel, and transition to Qt
> Quick instead. Qt Quick uses the GPU, QtWidgets do not.
> ==========
> That’s a pretty horrible answer... There are MANY of us, who prefer for all
> sorts of reasons, to use C++ as our primary development language.
> Is there no outlook for QtWidgets to start using the GPU?

No. Long story short: the QPainter model is incompatible with OpenGL. We 
tried, we failed. So we created a new one that works as OpenGL expects and 
it's called "Qt Quick 2".

Alternative long story short: we've already done that work and the result is 
Qt Quick 2 and Qt Quick Controls.

Long story: let me take us back 8 years. 

Before Qt 4.5, used the "native" engine for painting on X11 and on Mac, and it 
had a really horrible GDI engine for Windows, so it had a replacement engine 
that used its own internal painting mechanism using QImage. Because of that, 
it was called the "raster" engine.

The XRender engine for X11 was much faster than "raster", but it produced 
subtly different output depnding on the X11 version, the number of bugfixes 
applied (and X.org developers were then invariably GNOME users, which meant 
they never tested Qt) and very different from Mac and Windows.

The best of both worlds would be to make the raster engine as fast as the 
native, of course. But how?

Well, turns out that the GPU is very good at doing graphics. And we have an 
API to access the GPU, it's called OpenGL. So Qt 4.5, in addition optimising 
the raster engine and making the graphics system selectable at runtime, 
introduced a new, experimental graphics system called "opengl". This was 
called "Falcon Project".

Those of you who have tried the opengl graphics system in Qt 4.5-4.8 know how 
buggy it was. We never made it work properly, for many reasons, including some 
that were the same as the native graphics system problems: OpenGL drivers work 
differently from one another.

Most importantly, the imperative painting model that QPainter and, by 
extension, QWidget use, is incompatible with how GPUs operate. You can do it, 
but it's not very efficient. Right around that time, the MeeGo project was 
starting and the Qt developers were comparing notes with the Clutter 
developers. Clutter was around this time developing a backend called "Clutter 
on OpenGL" (COGL), which was like the Qt's opengl graphics system, but with 
one twist: it would defer all painting operations into a journal and then 
reorder them as necessary to be efficient with the GPU.

Qt developers looked at that and decided it was overly complex and didn't go 
far enough, not to mention that all Clutter developers, being employed by 
Intel, were optimising only for the Intel GPUs (yeah, I work for Intel now). 
From what I understand from the developers at this time, the most problematic 
issue with OpenGL was saving state between frames. With an imperative painting 
model, the engine cannot know what's going to happen on the next frame, so it 
cannot know what to cache and what to discard. If you cache too little, you 
spend time re-uploading resources to the GPU and re-rendering things; if you 
cache too much, you're wasting resources.

So around the time that Qt 4.8 was launching, we kicked off a new project that 
tried to use OpenGL the way that it was designed to be used, like games do. 
This project was called "Scene Graph" and is fundamentally different from 
QPainter that it works in *retained* mode instead of imperative mode. The 
graph of that Scene Graph *is* the cache: while the graph node is present, its 
associated GPU resource is kept; when it's removed, the resource is discarded. 
All the engine needs to know is the order in which the OpenGL resources should 
be sent to the GPU when rendering the frame. And note that this can be pre-
calculated and stored, instead of re-calculated in each frame.

This is also the reason why Qt 5.0 came with Qt Quick 1 (based on 
QGraphicsView, which means QPainter) and Qt Quick 2, which is designed around 
OpenGL. That in turn is the reason why there was a requirement of OpenGL for 
Qt Quick 2 and why version 1 was deprecated then.

So what you want isn't QWidget with OpenGL support. We've proven it won't 
work. What you want is a powerful, Scene Graph-based set of widgets with 
native look and feel (that is Qt Quick Controls). 

You're probably also asking for a C++ API instead of a QML one.

Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center

More information about the Interest mailing list