Nominate our 2022 Qt Champions!

Performance optimizations using Raster backend

  • Hi Everyone,

    I'm trying to optimize a Qt application, but came across a few roadblocks along the way and I'm wondering if you can shed some light on them.

    Some parameters of what we do: raster engine on barebone linux writing to Framebuffer (RGB32 destination I believe, I'm open to changing it if you can tell me how. Documentation is scarce.). Qt 4.7.1 (can't change at this very moment, but it is planned to move on). 400MHz CPU. We only use drawPixmap calls to draw images, and all QImage-s are converted to QPixmap outside of paintevents. There is also a screen update per second.

    I've read these pages:
    and alike, including docs.

    • we use many Pixmaps with alphablending. In order to improve performance I've tried to change our QImage-s (from ARGB32) to all use ARGB32_Premultiplied or RGB16 (which I believe is ARGB4444_Premultiplied in Qt). The problem I have is that my draw times actually increased, instead of decreasing for both cases. When I do callgrind I see /src/gui/painting/qdrawhelper_p.h:void qt_transform_image_rasterize<unsigned int, unsigned int, Blend_ARGB32_on_ARGB32_SourceAlpha> calls outnumbering everything else we do. When I convert an ARGB32 QImage to QPixmap, what is the QPixmap's structure? Is the answer the same when my QImage is ARGB4444_Premultiplied?
    • as I use a raster device, is there a difference between using drawImage vs drawPixmap? I understand that if I'd have OpenGL QPixmap would be in GPU memory, but not in this case. I'm already underway with testing this, but can I reasonably expect anything?
    • I'm wondering about best practices to use masks. When would you get the mask from a pixmap, create a HeuristicMask or AlphaMask? As expected I'm interested in speed. Also when would you a mask?
    • I have a couple of CONFIG options enabled for FB device like CONFIG_FB_CFB_FILLRECT=y, does Qt use those?
    • says: "If this is too expensive an operation, you can use QBitmap::fromImage() instead." What does it mean by that? Why is QBitmap faster and what do I draw where in order to improve speed?
    • when I rotate the canvas I can observe that the time to draw depends on the angle of rotation, 0 & 180 degrees being the fastest and 90&270 being the slowest (5 times slower), is that expected? I can craft a theory that explains it, rows an columns change, which is quite problematic in memory and cache effects screw everything up, but I'm wondering if it is correct.
    • any ideas about potential speed up possible with Qt 4.7.1 -> 5.5 change? (it is a bit of a mission to invest all that time to make the change)

    I don't think it makes a difference whether I'm including code snippets. Ask questions and I can answer those.

    Any help is appreciated!


    PS: I've posted this in general rather than embedded, wasn't sure where would it fit better :)

  • Moderators

    QImage is optimized for manipulation, while QPixmap is better for showing things on the screen. I'd suggest using QImage everywhere, as you seem to have a lot of operations performed on your data. QPixmap's data is platform/system dependent, while QImage is platform independent. I don't know if raw data is available for access for the pixmap class (I was too lazy to check), but it for sure is accessible for the QImage class. As for masks, I wouldn't know, but maybe the composition example might be of use. QBitmap is just a monochrome pixmap, and the note in the documentation relates only to this case. I assume you have full-color images, so this is not useful in your case.
    All in all, I'd suggest not doing explicit conversions and using QImage all the way. For example you modify your image whenever it's needed and in the paint event just issue the appropriate QPainter::drawImage() call.

    Kind regards.

Log in to reply