views:

566

answers:

1

I'm writing an application for the Maemo platform using pygtk and the rendering speed of the tree view seems to be a problem. Since the application is a media controller I'm using transition animations in the UI. These animations slide the controls into view when moving around the UI. The issue with the tree control is that it is slow.

Just moving the widget around in the middle of the screen is not that slow but if the cells are being exposed the framerate really drops. What makes this more annoying is that if the only area that is being exposed is the title row with the row labels, the framerate remains under control.

Judging by this I'm suspecting the GTK tree view is drawing the full cells again each time a single row of pixels is being exposed. Is there a way to somehow force GTK to draw the whole widget into some buffer even if parts of it are off screen and then use the buffer to draw the widget when animating?

Also is there a difference between using Viewport and scrolling that up and using Layout panel and moving the widgets down? I'd have imagined Viewport is faster but I saw no real difference when I tried both versions.

I understand this isn't necessarily what GTK has been created for. Other alternative I've tried is pygame but I'd prefer some higher level implementaion that has widget based event handling built in. Also pygtk has the benefit of running in Windows and a window so development is easier.

+1  A: 

I never did this myself but you could try to implement the caching yourself. Instead of using the predefined cell renderers, implement your own cell renderer (possibly as a wrapper for the actual one), but cache the pixmaps.

In PyGTK, you can use gtk.GenericCellRenderer. In your decorator cell renderer, do the following when asked to render:

  • keep a cache of off-screen pixmaps (or better, just one large one) and a cache of sizes
  • if asked to predict the size or render, create a key from the relevant properties
  • if the key exists in the cache, use the cached pixmap, blit the cached pixmap on the drawable you are given
  • otherwise, first have the actual cell renderer do the work and then copy it

The last step also implies that caching does incur an overhead during the first time the cell is renderered. This problem can be mitigated a bit by using a caching strategy. You might want to try out different things, based on the distribution of rendered values:

  • if all cells are unique, not much to do than caching everything up to a certain limit, or some MRU strategy
  • if you have some kind of Zipf distribution, i.e. some cells are very common, while others are very rare, you should only cache the cells with high frequency and get rid off the caching overhead for rare cell values.

That being said, I can't say if it's going to make any difference. My experience from a somewhat similar problem is that anything involving text is usually slow enough that caching makes sense---sorry that I can't give simpler advice.

Before you try that, you could also simple write a decorating cell renderer which just counts how often your cells are actually rendered and get some timing information, so that you get an idea where the hot spots are and if caching the values would make any sense at all.

Torsten Marek