A QML rendering performance trick so simple that it hurts

I haven’t feeling like writing much since two-eleven for obvious reasons, but my friend Tuukka (he’s the goatee (pull it and say hi from me) guy giving the course you might be attending when you’re reading this) gave me a proverbial kick in the butt. To get going again I’ll start with something easy, but which is a true gem. This is so simple that it truly hurts.

Most mobile QML UIs (at least the stuff I’ve done and seen other people doing) explicitly paint every pixel on the screen. By that I mean that the QML scene has a set of elements which cover all of the pixels inside the QDeclarativeView in all situations. For example if your root element is a Rectangle, you’re painting every pixel.

Guess what? You’re likely painting them twice (or maybe even three times) and I’m not talking about overlapping elements. Before the QDeclarativeView (which is a QWidget) paints all of your QML elements in back to front order, it also paints the whole area with a background brush! In Symbian this is the active theme’s backround wallpaper. This useless painting is simply wasting precious GPU processing power. If the user has a fancy theme which has a image as the wallpaper, it’s even worse because blitting an image needs even more memory bandwidth. A while ago I saw some MeeGo demo video on Youtube, which demonstrated the rotation of homescreen or something. During the rotation animation you could see a white background peeking behind the actual UI. I’m pretty sure that the white background gets painted also during normal operation when it’s not needed. I hope someone comes and tells me I’m wrong.

I haven’t made any measurements how much the extra painting takes on current Symbian^3 hardware, but in my own project it was enough to bump some of the views from the ‘okayish framerate’ to 60fps (well not exactly 60fps before Qt 4.8 and screen refresh synchronized animation driver, but anyway).

So how do you get rid of the extra background painting when you know that you’re painting everything by yourself and don’t need it? It’s a oneliner: w.setAttribute(Qt::WA_NoSystemBackground); (w being the widget you’re using to display your scene).

Now there’s one but on Symbian (there always is on Symbian). Setting that attribute completely kills the performance on devices which don’t have the NGA (new graphics architecture). Generally this means anything pre-S^3. I’m not sure what causes it. Might be a bug that could be fixed. On S^3 it works as expected – if you don’t draw a pixel, it will contain whatever was drawn there previously. Personally I think everyone should just forget those devices without a GPU, but Nokia seems to be hellbent on making modern phones with five penny hardware (C6-00 for example) and people buying those are your customers too.

So if the same executable needs to run on both the new and the older devices, you need to decide runtime if you want to set the attribute or not. I couldn’t come up with any better way than using QDeviceInfo::version(QDeviceInfo::OS). You should be fine setting the attribute on 5.2 and newer.

One more thing. When I said earlier that you might be painting even three times, I meant the case where your root element is a Rectangle and on top of that you stack elements that cover the whole rectangle. The graphics scene doesn’t know that the elements stacked on top will cover the whole root element and just obeys your command and draws it. So if that’s the case (it’s easy to miss if you started out with a Rectangle and started developing on top of that), just change it to an Item. If you still need to draw some type of background, but have static items covering part of the screen (like a titlebar or some navigation bar at the bottom), still use an Item as the root element and anchor a Rectangle between those static items that you don’t do useless painting.

Ok, that’s it for now (more practical tips later). Have fun QMLing.

This entry was posted in Programming and tagged , , , . Bookmark the permalink.

20 Responses to A QML rendering performance trick so simple that it hurts

  1. Nice post, tanks for your information.

  2. Wade Shull says:

    that is some good stuff. I have places I could change a rectangle to item. Thanks for the tip.

  3. Federico Lorenzi says:

    Same here – thanks for the tips :)

  4. Tuukka Ahoniemi says:

    Yeah, a good one! Keep’em’coming, Juha! I’m still proverbially kicking you, but for a good reason–these are diamonds :)

  5. Stev says:

    Ohhhh, great post..

  6. Sergey says:

    Hey, thanks for the great post

    How exactly the line is added?
    Is it for the main.cpp file I presume?

    Would be good if you could share an example for noobs like me;)
    Promise to post framerate results!

  7. Alessandro Portale says:

    Great tip, thanks! Perhaps Qt Creator’s Qt Quick app wizard should add that code (with Symbian version check).

    The kittyapp is really sweet :) Two small tips if you do not mind:
    - Qt 4.7.2+ has official API for locking the screen orientation on Symbian via QWidget::setAttribute(Qt::WA_LockPortraitOrientation)
    - Font loading custom .ttf fonts via QFontDatabase::addApplicationFontFromData, or alternatively QML FontLoader or css3 web fonts is now supported on Symbian. Qt 4.7.2+. Even from .qrc.

    • Juha Turunen says:

      Definitely don’t mind. I should update the example and get rid of those hacks from the dark days :)

  8. Michael Sandberger says:

    Hi!

    Funny thing: In my qml-application, which runs on an embedded Linux Board with QWS-Server, adding this line had the exact opposite result. After I set the attribute, the performance of animations or any screen updates dropped significantly.

    • Juha Turunen says:

      Weird. I have to admit that I know nothing about QWS, but my guess why it slows down on earlier versions of Symbian is that setting that flag hints the windowing system that because this window doesn’t have a system background also the window behind it needs to be drawn => disaster. Would be really nice to hear from some real experts on the subject.

    • Thomas McGuire says:

      The reason why the performance in QWS drops is that setting Qt::WA_NoSystemBackground causes the painting surface of QDeclarativeView to add an alpha channel, since we are not drawing a background and might want to draw transparent stuff over what is already there.
      Now, having an alpha channel in the surface causes a lot of conversions from RGB565 to ARGB8565 and back, since the surface is ARGB8565, the QWS screen surface is RGB565 and many images loaded are RGB565 as well. These conversions are a performance killer.

  9. Siva says:

    Hi Juha.. Gr8 post. Just a curious question, is having a Rectangle element with color set as “#00000000″ (ie,. transparent), same as using an Item?

  10. Sami Merilä says:

    Great post.

    This should be fixed for Qt 4.7.4 – it should no longer try to create and paint the theme background for Symbian style, unless it is actually needed.

    Keep up the good work!

  11. Awesome issues here. I’m very satisfied to peer your article. Thanks so much and I’m having a look ahead to contact you. Will you please drop me a mail?

  12. traxx says:

    I never use Rectangular element as i always started with Item element.I wonder if Rctangular element is bad to performance,why anyone still want to use it.The case i can think of for Rectangular element is for background.Even then you can still do it with Item element and put whatever you want in Item element.

  13. Stefan Monov says:

    Hi.
    Nice post!
    I noticed you’re using QDeclarativeView which means Qt 4.x.
    I’m using Qt 5 and instead of QDeclarativeView I’m using QQmlApplicationEngine, which is not a QWidget and so I can’t set WA_NoSystemBackground on it. Do you know how things stand with Qt 5′s QQmlApplicationEngine (and QQuickView, as an alternative), as compared with the Qt 4 way? Do they still benefit from disabling the system background?

  14. Web Scripts says:

    Visiting begin a business venture around the web usually means exposing your products or services moreover provider not only to some individuals inside your town, but yet to a lot of future prospects who may be over the web many times. easy internet business

  15. Manushree says:

    Audio began playing any time I opened up this blog, so frustrating!

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>