Lars Ingebrigtsen writes: > Madhavan Krishnan writes: > >> Thank you for investigating this issue, I am not entirely sure of what >> the next step would be. Is there a sample code that I can refer to for >> the ImageMagic version you are referring to? (to get some idea about how >> it can be patched) > > imagemagick_get_animation_cache and friends in src/image.c. I've been looking into this a bit, and here are my preliminary conclusions. I hope it is clear, and appreciate any feedback! The first part of the problem is making sure that we can cache animated images, which currently never happens. Once that is in place, the second part is to cache all animated images up-front. I only discuss the first part below. Besides the special cache for ImageMagick we also have tho one used for *all* images. So my thinking is: why not use the "real" cache also for animated images? Why implement a specialized cache just for that? I believe it is possible.[1] And actually, the first question is: why aren't they already cached? The reason is this: in search_image_cache (image.c:1599), we use sxhash and Fequal to compare the Lisp image descriptor (or "image specification" or "spec" as its called in image.c) to the one we have in cache. But in an animated gif the image spec is changed in image.el: (image :type gif :file "/some/file.gif" :scale 1 :max-width 1248 :max-height 1321 :format nil :transform-smoothing t :animate-buffer "file.gif" :animate-tardiness 0.9810895737588246 :animate-multi-frame-data (62 . 0.04) :index 61) The value of :animate-tardiness is updated in image.el on every iteration. When image.el updates :animate-tardiness, it will never be equal to something in the cache and we always get a cache miss! I have attached a patch that will demonstrate how we get back caching by simply disabling the updating of the image spec in image.el. This is completely the wrong thing to do, but demonstrates what is going on. With that patch, caching will be enabled, and you can see it the second time you try to run an animated gif. (Use RET to start the animation.) The correct fix here is to somehow *only* compare the relevant attributes above, and ignore or leave out e.g. :animate-tardiness. I have experimented with different approaches. My first idea was to create a new comparison function "image_cache_equal" that basically only compares the attributes we are interested. But then the problem was that we use the "sxhash" function to find which hash bucket to find the list in, so that didn't help much. We would also need to replace the sxhash with something else. Perhaps sxhash_equal? Hmm. So I thought of two other ways to go about this: A) We create a new stripped down Lisp plist containing only the attributes we are interested in and use that to compare against the cache. We obviously need to make sure the cache also contains only stripped down list. This means we can keep using Fequal and sxhash, but we also need to create a new list for *every cache lookup*! B) We parse the relevant parts of the image spec into a C struct and then use that struct for comparisons. It turns out we already have most of the code in place to do this, see parse_image_spec (image.c:898), so most of it should be some restructuring, and then writing up a comparison function. With that in place, we would just need to . Option A) seems ugly to me: why would we be consing up Lisp lists on such a low level, which also makes me worry about creating a lot of unnecessary garbage. So I prefer Option B). The struct also seems more clean to me. Perhaps there are some performance implications I'm not thinking of? Or perhaps there is some even better way to do the cache check than a new struct, such as using the "image struct" directly? A third alternative is to somehow change image.el to put this information outside the image specifier, but that leaves unfixed a rather subtle issue with caching. That issue may or may not bite someone later. Comments about all this is very welcome! I'm basically at the point where any approach I choose means investing a bunch of work, and it would be useful with some feedback before I rush ahead and attempt any of them. Perhaps someone here has an idea or hunch about which approach might prove more fruitful. Footnotes: [1] There is a comment in the ImageMagick cache saying: "We have to maintain a cache separate from the image cache, because the images may be scaled before display." However, this was written before we had native image scaling, and actually it seems to me either incorrect, based on the above, or correct but only applicable to ImageMagick, or, perhaps more likely, I am missing something important.