Fixing Gnometris Performance
I had the pleasure of discussing Cairo and Gnome Games with Carl Worth a few days ago. As many have noted, the new Tango theme in Gnometris will bring even the most powerful systems on the market today to its knees once the playing field is about two-thirds of the way full.
As it stands today with Gnome Games 2.22.1, we invalidate the entire field, and call Render::render to rerasterize the playing field when any animation occurs: a block moving, a line cleared. This worked well when Gnometris was just moving simple pixmaps around. Now, the gradient and tessellation calculations inside Cairo are too hard to stick with this method.
Since I'm rather new to canvas programming, my first inclination was to approach the problem by going back to pixmaps: rasterize the Tango blocks to off-screen pixmaps, then go about the animation using the old, invalidate-and-repaint-everything method. Well, I've been informed that there are cleverer ways of approaching vector animation. I'm sure that anyone with any experience in graphics probably already got this memo; but, it's new to me, so maybe someone else can appreciate the following explanation.
Consider the animation event: a block falling 1U.
Gtk+ (and Cairo) allow us to selectively invalidate-and-rerender a region of a window. In the Gnometris case, calculating the region that needs to be updated is trivial.
So, all I have to do now is find time to modify Render::render to accept a region to update as an argument and do a little math to figure out invalidated region to hand to it. In the case of a line being cleared, (almost) everything moves, so rerendering the whole field is reasonable.
Looking toward the future, I would like to add some explosion-style animation to Gnometris. When a line is cleared, the deleted blocks explode and fade away while the blocks above side down with innertia-like physics and "crunch" with residual vibration on the blocks below. To make this happen with Cairo, I would need very smart, aggressive region invalidation and more efficient manipulation of the vector data on the playing field.
If anyone knows of a library that can help with calculating all the invalidated regions, please let me know or post to the games-list.