Qt Graphics and Performance - Whats Hot and whats Not

On friday I added the following to the QPainter documentation:


section1 Performance

QPainter is a rich framework that allows developers to do a great
variety of graphical operations, such as gradients, composition
modes and vector graphics. And QPainter can do this across a
variety of different hardware and software stacks. Naturally the
underlying combination of hardware and software has some
implications for performance, and ensuring that every single
operation is fast in combination with all the various combinations
of composition modes, brushes, clipping, transformation, etc, is
close to an impossible task because of the number of
permutations. As a compromise we have selected a subset of the
QPainter API and backends, where performance is guaranteed to be as
good as we can sensibly get it for the given combination of
hardware and software.

The backends we focus on as high-performance engines are:

list

o Raster - This backend implements all rendering in pure software
and is always used to render into QImages. For optimal performance
only use the format types QImage::Format_ARGB32_Premultiplied,
QImage::Format_RGB32 or QImage::Format_RGB16. Any other format,
including QImage::Format_ARGB32, has significantly worse
performance. This engine is also used by default on Windows and on
QWS. It can be used as default graphics system on any
OS/hardware/software combination by passing c {-graphicssystem
raster} on the command line

o OpenGL 2.0 (ES) - This backend is the primary backend for
hardware accelerated graphics. It can be run on desktop machines
and embedded devices supporting the OpenGL 2.0 or OpenGL/ES 2.0
specification. This includes most graphics chips produced in the
last couple of years. The engine can be enabled by using QPainter
onto a QGLWidget or by passing c {-graphicssystem opengl} on the
command line when the underlying system supports it.

o OpenVG - This backend implements the Khronos standard for 2D
and Vector Graphics. It is primarily for embedded devices with
hardware support for OpenVG. The engine can be enabled by
passing c {-graphicssystem openvg} on the command line when
the underlying system supports it.

endlist

These operations are:

list

o Simple transformations, meaning translation and scaling, plus
0, 90, 180, 270 degree rotations.

o c drawPixmap() in combination with simple transformations and
opacity with non-smooth transformation mode
(c QPainter::SmoothPixmapTransform not enabled as a render hint).

o Text drawing with regular font sizes with simple
transformations with solid colors using no or 8-bit antialiasing.

o Rectangle fills with solid color, two-color linear gradients
and simple transforms.

o Rectangular clipping with simple transformations and intersect
clip.

o Composition Modes c QPainter::CompositionMode_Source and
QPainter::CompositionMode_SourceOver

o Rounded rectangle filling using solid color and two-color
linear gradients fills.

o 3x3 patched pixmaps, via qDrawBorderPixmap.

endlist

This list gives an indication of which features to safely use in
an application where performance is critical. For certain setups,
other operations may be fast too, but before making extensive use
of them, it is recommended to benchmark and verify them on the
system where the software will run in the end. There are also
cases where expensive operations are ok to use, for instance when
the result is cached in a QPixmap.

I suspect it's a piece of documentation many of you have been lacking for a while, and its something we should have put in a long time ago, but I can only say "sorry for not doing it sooner". At least its getting done now. Note: Patch is not visible in public repository at the time of publishing. Should be there shortly

The urge to get these things into the docs have spun out from a number of dialogues I've had recently which all went pretty much like this:

  • TheOtherGirlOrGuy: My application is running slow... What do I do?
  • Me: What is it doing?
  • TheOtherGirlOrGuy: Well, its using QGraphicsView and QPainter and is doing this and that...
  • Me: That doesn't sound too bad.
  • TheOtherGirlOrGuy: And then its really slow when doing this...
  • Me: Yeah... That doesn't work very well. What you should be doing is this...
  • TheOtherGirlOrGuy:Is that written down someplace? How am I suppose to know that?
  • Me: Eh...

To remedy this, I'm going to put into action something I've had at the back of my head for a while now, a blog series on Qt Graphics and Performance. Along the way, I'll also try to get parts of this into the documentation or into examples/demos as best practice use-cases.

I just have to point out, that this blog series is not a request for more features. It is about us sharing with you what we consider best practises and what our priorities are. Of course if you think our focus is way off, then let us know, but my primary intent with this blog series is to share some thoughts.

With the help of some of my co-workers, we plan to go through some Qt Graphics fundamentals, the "high-performance" engines, and usecases for graphicsview and widgets. If you have special usecases that you find interesting, then by all means let me know and maybe I can cover those too.

I need to add a small comment to the "drawText" case. It is currently not super optimal, because we have to do layout on the text for each time you call it. Because there is no "handle" in the function we don't have the ability to cache the layout either. If we started caching based on a qHash of all the strings that were passed to drawText() then we end up caching a lot of single-shot text drawing... The option that we provide today to work around this is to use a QTextLayout with caching enabled, which is memory-wise quite hungry... I think in the range of 100-300 bytes pr character! So as an alternative, we are working on an API for static text which encapsulates the layout work with very little memory overhead. Its currently called QStaticText and we're aiming for it to go into 4.7. Once it is in place, we'll update the drawText comment in the performance documentation to be for these static texts...

As time permits we plan to push out blogs on the following topics:

  • An overview of the various components involved
  • The raster paint engine in detail
  • The OpenGL paint engine in detail
  • The OpenVG paint engine in detail
  • QGraphicsView optimization flags and cache modes

Blog Topics:

Comments