Back to Blog home

bnilsen.flush();

Published on Friday February 13, 2009 by Bjørn Erik Nilsen in Qt Painting Graphics View KDE Rants | Comments

Hi fellow hackers,

I have found a bug in my brain, it does not emit the readyRead signal properly which means all the public information that was meant to be published at appropriate intervals is not processed. Here follows a manual flush of what I've been doing since last time. Talking about everything is too much, so I'll give you a brief overview.

Last year was pretty much spent on optimizing/re-factoring code related to the Qt Falcon project where the goal was to make Qt 4.5 fly. I mainly focused on painting performance for widgets, i.e. the backing store / window surface infrastructure. After spending a fair amount of time profiling different painting scenarios, I found out the backing store infrastructure was too poor to improve. It simply had to be re-factored in order to make it fly. I finally had an excuse to wear my latex laboratory gloves and white coat in public (I usually only wear this kind of equipment behind closed doors when lobotomizing colleagues). With all the equipment in place--including liters of coffee--the time had come. I was about to replace our platform dependent beast with something new and shiny--preferably cross-platform. After some tough work and patching throughout 2008 I ended up with something useful. Let me remind you that there are no problems, only solutions. I basically removed a lot of QRegion operations and made the update mechanism a whole lot smarter, in addition to many cut-offs for opaque widgets. I will leave out the details and let these numbers speak for themselves:

Qt 4.4 Qt 4.5 Boost (2.0x means twice as fast)
Full update (transparent widgets) 4330 ms 2446 ms 1.8x
Full update (opaque widgets) 3352 ms 1464 ms 2.3x
Scroll (opaque widgets) 50231 ms 3746 ms 13.4x
Partial update (opaque widgets) 4246 ms 1567 ms 2.7x
Complex update (opaque widgets) 4966 ms 2265 ms 2.2x
Full update (opaque children) 3376 ms 1464 ms 2.3x
Move (opaque widgets) 50293 ms 4188 ms 12.0x
Mass update (opaque widgets) 9560 ms 1679 ms 5.7x

Download the sources from here.

With a new and optimized backing store, we were one step closer the goal. While I was working on the new backing store, the other falcon guys were working on a brand new graphics system whose goal was to make it possible to switch the rendering back-end. In order to achieve that, all the painting had to go through our backing store. We had never used the backing store on the Mac before, so my next action point was to put the pieces together and make it happen. Voila, "-graphicssystem raster" on the Mac was no longer just a wet dream. And yes, it was a little bit harder than it sounds.

During all this hacking I also decided to go to DevDays in Munich and Redwood, which implied that I had to prepare two presentations; "Advanced Visualization, Widgets On Graphics View" and "Alien Widgets & Widget Rendering". I spent quite some time making these presentations the best since sliced bread, and I really hope they were entertaining and interesting. Dev Days 2008 was such a great event and I really enjoyed my stay.

Few days later, back in business here in Oslo with turbo charged batteries, I felt a bit disappointed that I couldn't show off a graphics view embedded inside graphics view embedded inside another graphics view etc. I knew it wasn't going to work, so I didn't even try. However, I made an example having exactly two redirections and that seemed to be more than enough for the hackers in the room, based on the applause it received. This limitation was made on purpose to ease and simplify the shared painter and QWidget::render. However, I was not satisfied with it and thought it would be cool to remove it without adding overhead, so I sat down and did some brain work. And as usual there was a solution to my problem. The shared painter, and hence QWidget::render, now supports an arbitrary number of redirections. Have a look at WolfenQt to see it in action, there's no limitation of how many times you can "walk into" another graphics view. HTML-5 video in QWebView is another example. Pretty cool.

With that out of my way, I found time to look into a very annoying issue that has followed us since Qt 4.0: "Qt::WA_StaticContents does not work". Well, it worked for Qt::WA_PaintOnScreen top-levels, but not in general which is really bad since the attribute can have an incredible impact on the performance on resize. It basically means "Dear Qt, do not repaint my entire rect on resize and only repaint newly exposed areas instead". Just think of it next time you expose yourself for the sun; does it make sense to wear off all the clothes and put on sun lotion on the entire body just because parts of it is exposed? I hope not. I therefore decided to implement the Qt::WA_StaticContents attribute for all widgets in Qt 4.5.0 and here's the result:

Download the sources from here (run with "QT_FLUSH_PAINT=10" in debug mode to flush repainted areas with yellow).

I have done several other things too, like fixing lots of bugs, reviewed patches, fixed auto tests, helped out with recruitment, promoted Qt Software at various events and so on. All in all very exciting stuff, and I look forward to new challenges and exciting stuff in the months to come.

OK, that's it for now. I promise to blog more often in the future, or even write a QQ article (mostly to give back something to Kavindra who has provided me with an unknown number of delicious muffins).

Have a nice weekend and happy hacking!

Subscribe to Our Blog

Stay up to date with the latest marketing, sales and service tips and news.

The blog comment system has been migrated to a new platform. If you face any issues, please let us know via feedback@qt.io.