Skip to content

Add some caches for bitmap data in the cairo output device

lbaudin1 requested to merge lbaudin1/poppler-freetextglib:caches into master

When somewhat large bitmaps are present, drawing can be very slow just because images must be loaded at every rendering. This branch brings two things :

  • a generic LRU cache class, which can be used to cache values computed from a Ref from a document
  • cache several bitmaps elements, most notably cairo image surfaces and also jpxstream information (especially useful since image surfaces are cached)

Rendering speeds are very substantially improved: for instance with ClarityOCGs.pdf from the test repository, first rendering takes 0,17 sec with the glib demo app and subsequent rendering is 0,04 (even at a different scale). I have another document (lectures from a colleague I can't share) which goes from 1,7 seconds to 0,07. For the small image.pdf file, first rendering takes 0,017 second, second drawing takes 0,002s.

To be honest, there are some caveats:

  • caches are added to XRef, this is necessary as it is the proper place to invalidate them. I made previous attempts with cache inside Gfx or CairoOutputDev but there is no good way to know when the document has changed. Usually the document should not change much, but images can at least change when custom annotation stamps are added/removed, and probably at some other places I am not aware of. Another direction could be tracking those changes manually (for instance in bindings) and invalidate changes there but that seems very complicated and fragile

  • I set a default cache size of 25MB for cairo surfaces. This may be too much, although probably less than 20% of what an actual pdf gui app actually uses. May be problematic for cli apps. Should this should be configurable via a global parameter with a very low default?

And the pipeline fails but it does not look like it is actually related to my branch.

Edited by lbaudin1

Merge request reports

Loading