Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-05-05 10:57:32 +0300
committerCampbell Barton <ideasman42@gmail.com>2021-05-05 11:07:49 +0300
commit20b6f7abb2f7698460c73809fcdcece1e848f176 (patch)
treec57fce7ab0bc8408247e6fda5c0d90bff5fa1a24 /source
parent736a7dcca9c857e664a2a1db57fb6a05fb742001 (diff)
Fix PlayAnim error applying cache limiter
Each frame display would add an item to the cache limiting list without checking if it was already in the list. Limiting would then free image buffers when the length of the list exceeded USE_FRAME_CACHE_LIMIT (currently 30). In practice this meant short animations would free and reload frames during playback.
Diffstat (limited to 'source')
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 2dda3e3019a..96eeca18b24 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -237,6 +237,11 @@ typedef struct PlayAnimPict {
struct anim *anim;
int frame;
int IB_flags;
+
+#ifdef USE_FRAME_CACHE_LIMIT
+ /** Back pointer to the #LinkData node for this struct in the #inmempicsbase list. */
+ LinkData *frame_cache_node;
+#endif
} PlayAnimPict;
static struct ListBase picsbase = {NULL, NULL};
@@ -1412,25 +1417,30 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
}
if (ibuf) {
-#ifdef USE_FRAME_CACHE_LIMIT
- LinkData *node;
-#endif
-
#ifdef USE_IMB_CACHE
ps.picture->ibuf = ibuf;
#endif
#ifdef USE_FRAME_CACHE_LIMIT
+ /* Don't free the current frame by moving it to the head of the list. */
+ if (ps.picture->frame_cache_node != NULL) {
+ BLI_assert(ps.picture->frame_cache_node->data == ps.picture);
+ BLI_remlink(&inmempicsbase, ps.picture->frame_cache_node);
+ BLI_addhead(&inmempicsbase, ps.picture->frame_cache_node);
+ }
+
/* Really basic memory conservation scheme. Keep frames in a FIFO queue. */
- node = inmempicsbase.last;
+ LinkData *node = inmempicsbase.last;
while (node && added_images > PLAY_FRAME_CACHE_MAX) {
PlayAnimPict *pic = node->data;
+ BLI_assert(pic->frame_cache_node == node);
if (pic->ibuf && pic->ibuf != ibuf) {
LinkData *node_tmp;
IMB_freeImBuf(pic->ibuf);
pic->ibuf = NULL;
+ pic->frame_cache_node = NULL;
node_tmp = node->prev;
BLI_freelinkN(&inmempicsbase, node);
added_images--;
@@ -1441,8 +1451,11 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
}
}
- BLI_addhead(&inmempicsbase, BLI_genericNodeN(ps.picture));
- added_images++;
+ if (ps.picture->frame_cache_node == NULL) {
+ ps.picture->frame_cache_node = BLI_genericNodeN(ps.picture);
+ BLI_addhead(&inmempicsbase, ps.picture->frame_cache_node);
+ added_images++;
+ }
#endif /* USE_FRAME_CACHE_LIMIT */
BLI_strncpy(ibuf->name, ps.picture->name, sizeof(ibuf->name));