From db1b1f09b820efeefa60a49684c06d511b70eecb Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Wed, 29 Jul 2020 08:38:52 +0200 Subject: [PATCH] Use a new method to determine when to auto-stop image animations * lisp/image.el (image-animate-timeout): Make the animation auto-stop use a decaying average to determine when to stop (bug#40685). The default stop condition will probably require some tweaking -- the current default may be too aggressive. --- etc/NEWS | 9 +++++++++ lisp/image.el | 10 ++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 4c77162a256..e4d9887480b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -490,6 +490,15 @@ more readable text. Set this variable to nil to get the previous behavior of rendering as wide as the window-width allows. If 'shr-width' is non-nil, it overrides this variable. +** Images + +--- +*** Animated images stop automatically under high CPU pressure sooner. +Previously, an animated image would stop animating if any single image +took more than two seconds to display. The new algorithm maintains a +decaying average of delays, and if this number gets too high, the +animation is stopped. + ** EWW +++ diff --git a/lisp/image.el b/lisp/image.el index 4ea8594a974..4b2faa992fc 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -784,6 +784,7 @@ number, play until that number of seconds has elapsed." (if (setq timer (image-animate-timer image)) (cancel-timer timer)) (plist-put (cdr image) :animate-buffer (current-buffer)) + (plist-put (cdr image) :animate-tardiness 0) (run-with-timer 0.2 nil #'image-animate-timeout image (or index 0) (car animation) 0 limit (+ (float-time) 0.2))))) @@ -848,9 +849,14 @@ The minimum delay between successive frames is `image-minimum-frame-delay'. If the image has a non-nil :speed property, it acts as a multiplier for the animation speed. A negative value means to animate in reverse." + ;; We keep track of "how late" image frames arrive. We decay the + ;; previous cumulative value by 10% and then add the current delay. + (plist-put (cdr image) :animate-tardiness + (+ (* (plist-get (cdr image) :animate-tardiness) 0.9) + (float-time (time-since target-time)))) (when (and (buffer-live-p (plist-get (cdr image) :animate-buffer)) - ;; Delayed more than two seconds more than expected. - (or (time-less-p (time-since target-time) 2) + ;; Cumulatively delayed two seconds more than expected. + (or (< (plist-get (cdr image) :animate-tardiness) 2) (progn (message "Stopping animation; animation possibly too big") nil))) -- 2.39.2