Skip to content

Optimize image viewer redraw: Reuse source surface

Depends on !25 (merged), partially addresses #64.

Except in the case of an animated image, where we are always juggling with two frames, and once the creation of the source surface from the original image is over, we should only have in memory one "copy" of this image (in the broad sense, i.e. in one format or another).

This is the first objective of this MR. It allows, once an image has been displayed for the first time, to keep a constant memory occupation for any other operation requiring a redrawing of this same image (in particular zoom, rotation, change of window size).

This also has the appreciable side effect of improving - more or less significantly depending on the case - the performance during these operations, since the manipulations around the source surface prior to redrawing are only done once.

Here are some tests made with the image of #62 (closed), i.e. extracted from that of #60 (closed) by convert input.jpg -shave 3000x3000 output.jpg (unfortunately not uploadable here).

After !25 (merged) Ristretto occupied 651 MiB in memory once this image was displayed (with a peak at 1,4 GiB). After the present change, it occupies 856 MiB (with the same peak), but in a stable way (whereas before it went up to 1,4 GiB at each zoom, resizing, etc.).

The extra weight is due to the fact that the image is no longer kept as a GdkPixbuf, but as a cairo_pattern_t (directly passable as a source surface to the Cairo context for redrawing). In comparison, Geeqie takes up 725 MiB (with a peak at 1,2 GiB), so I think it's ok.

Regarding the loading time of this image (from the launch of the application until it is completely idle), I get similar times between Geeqie and Ristretto, namely about 18 seconds (it's an old and small laptop! ^^')

As for operations on an already loaded image, the gain may depend somewhat on the operation in question:

  • For a zoom, where you redraw the whole view, I get a decrease of about 30% compared to before (10 seconds -> 7 seconds).
  • To switch between a maximized and a non-maximized window, where everything is redrawn as well, I get a gain of 20-25% (10 seconds -> 8 seconds and 4 seconds -> 3 seconds)
  • For a background color change it's almost instantaneous, while it used to take about 2-3 seconds before (just before, because before 9e8df0b5, everything was redrawn in such a case).

This is more approximate than the memory usage and is given only as an indication. Let's say that in any case we don't lose out.

Edited by Gaël Bonithon

Merge request reports