GTK surprises on Maemo


Sometimes the creation of the contact chooser used on the N900 can be slow so, using callgrind and kcachegrind, I tried to understand what is the source of the slowness. This lead me to find some unexpected, and apparently undocumented, differences between upstream GTK and the Maemo version.

The Maemo 5 contact chooser
The Maemo 5 contact chooser

The widget contains a GtkTreeView that uses a model with just one column for the contact objects. How can its creation be so slow? To my surprise most of the time was spent decompressing the avatar images!
The avatars of the contacts are loaded, scaled and cropped in the cell data function of the GtkTreeViewColumn as, for various reasons, we cannot cache on disk the resulting image or generate it before the creation of the widget. Following calls of the cell data function for the same row won’t need to generate the avatar anymore. Doing non-trivial operations in the cell data function is not the nicest thing to do, but this should not be a problem as the cell data function is called only for the visible rows, right? No, at least not on Maemo!
To verify it just try this example program: on Maemo the cell_func() function is called once per item in the model plus once per visible item, elsewhere only once per visible item.

After a bit of investigation together with Claudio, we discovered that on Maemo there is a function called gtk_​tree_​view_​column_​get_​cell_​data_​hint() that returns GTK_​TREE_​CELL_​DATA_​HINT_​KEY_​FOCUS, GTK_​TREE_​CELL_​DATA_​HINT_​SENSITIVITY or GTK_​TREE_​CELL_​DATA_​HINT_​ALL. The hint tells you why the function was called; in the example code the function is called on the hidden rows only to get their sensitivity so there is no need to set the “pixbuf” property of the cell at this point.

Just this tiny change in the address book code makes the contact chooser open much faster if you have a lot of contacts with big avatars, like the ones that Hermes creates. On the other hand the delayed loading made the scrolling become non-smooth :(
To fix the scrolling I had to implement some asynchronous loading of the avatars. The contact chooser now tries to load as many avatars as possible in idle moments and also tries to load first the avatars for the contacts that the user is more likely to see. The results seem quite good; now the contact list is fast, scrolling is smooth and the delayed loading of avatars should not be visible in normal cases.

Information and Links

Join the fray by commenting, tracking what others have to say, or linking to it from your blog.


Other Posts

Reader Comments

Nice hack !
I hope we will see this in a future firmware update.

Would be great if we could get a similar hint in non-Maemo GTK as well. Doing a treeview with many items is likely to be slow with a custom renderer or custom data function. It would be nice to have ways of postponing expensive work.

You don’t really need this particular bits in non-maemo GTK+, as the reason why the celldata function is called for each row in the first load of the treeview is maemo specific.

Nice investigation :)

But compared to nokia release plans it probably means nothing for users as they will rather not get this fix in 2010.

[...] GTK surprises on Maemo Sometimes the creation of the contact chooser used on the N900 can be slow so, using callgrind and kcachegrind, I tried to understand what is the source of the slowness. This lead me to find some unexpected, and apparently undocumented, differences between upstream GTK and the Maemo version. [...]