Thursday, April 18, 2013

QUItIndicators: Introduction

Few months ago I wrote a normal mapping series with part I and part II. That was a good experience, so series it is again! This time about implementing dynamic QML components, with an example case being busy&progress indicators. We'll call these specific ones QUItIndicators.

Let's start with obligatory video which demonstrates these components, BusyIndicator and ProgressIndicator, with few examples:

Traditionally indicators like these would be implemented as an animated GIF or a sprite. Cons of that approach are zero customization and memory consumption: 2s animation of 256x256px 32-bit color indicator at 60fps would mean 2*60*256*256*4 = 31.5Mb memory consumption. That's quite a bit for just one indicator, so usually frames are animated slower than 60fps which makes animation less smooth.

Alternative way to implement animated indicator would be using imperative drawing API (QPainter, Cairo, Skia etc.). Drawing freely to a canvas gives a lot of possibilities, but can easily lead to non-optimal performance. Many of these APIs have OpenGL backends which sounds good in theory, but the reality is that they can't take full gains out of modern GPUs. Like wise Tro^H^H^HDigians have said, combining QPainter with OpenGL backend doesn't make a perfect harmony.

So as you probably guessed, our indicators use Qt5+QML+GLSL instead. The pros of this approach compared to sprites or imperative drawing are rendering performance, low memory consumption and customization possibilities. There is also at least one con: Indicator needs to be designed so that required animations can be achieved with vertex & fragment shaders.

Next blog post goes through design thoughts behind these indicators. In the meantime, you can get the sources from here and try yourself!