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.