QPixmap and what I did not know

QPixmap and what I did not know

In general QPixmap is the class I dislike the most in the Qt graphics stack. It is not because it did anything wrong, or has annoying bugs. It is merely that painting on a QPixmap can produce a huge slowdown. Maybe it is even the immediate painting model I dislike so much.

In theory the QPixmap should represent the graphics memory and in theory painting this to another piece of graphics memory should be very fast. But reality is different, e.g. with directFB/X it is possible that your graphics memory resides in the host memory because you have allocated too much. X (EXA, UXA…) has migration strategies, directFB will just allocate it in system memory and it will stay there. So your graphics memory class might not be always allocated in graphics memory.

The athur painting capabilities of Qt4 were very nice but Hardware/X/directFB might not be capable of handling all the advanced concepts (perspective transformation, drawing other pixmaps scaled) and the paintengines then need to fallback into the raster path, but the raster path needs to work on a QImage and this is where stuff get terrible. There will be a download of the memory (slow), there might be a change in color (ARGB -> pre multiplied ARGB?), then the fallback, and then uploading of the memory again. So even classes like QGraphicsBlurEffect go through QPixmap -> QImage -> QPixmap (or at least used to).

So the basic problem with QPixmap and the immediate painting model is, only once you are done with painting everything, you know if starting with a QPixmap would have made sense. If Qt5 wouldn’t be all about OpenGL, I would have lobbied hard to make QPixmap an internal class and use it to ‘cache’ QImage that have peen painted a lot.

After all this love/hate with QPixmap there were still things I didn’t know. For Qt5 I am working on the directFB lighthouse plugin and started to work on make more tests pass. The thing I did not know was that by default the QPixmap has no alpha channel, only if either a mask is set or the pixmap is filled with a color that has an alpha channel the QPixmap will end up having an alpha channel and be ARGB. This means that a lighouse plugin providing a QPlatformPixmap implementation needs to be able to provide an ARGB and a RGB based pixmap and switch between them.

Comments are closed.