[Bf-blender-cvs] [0499dbc5c16] blender-v2.93-release: PlayAnim: support limiting the cache by memory instead of frames

Campbell Barton noreply at git.blender.org
Thu May 6 03:32:08 CEST 2021


Commit: 0499dbc5c16fe6b276da81d65cade4f5da92a308
Author: Campbell Barton
Date:   Thu May 6 11:22:54 2021 +1000
Branches: blender-v2.93-release
https://developer.blender.org/rB0499dbc5c16fe6b276da81d65cade4f5da92a308

PlayAnim: support limiting the cache by memory instead of frames

Partial fix for T81751 which exposes multiple playback performance
issues. Previously the cache was limited to 30 frames, without a way to
increase the cache for smooth playback with files that are slow to load.

Now the animation plays back smoothly once loaded into cache.

The cache limit from the system preference is used
when the player is launched from Blender.

A new player argument `-c <cache_limit>` was added to support this.

===================================================================

M	release/scripts/startup/bl_operators/screen_play_rendered_anim.py
M	source/blender/windowmanager/intern/wm_playanim.c
M	source/creator/creator_args.c

===================================================================

diff --git a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
index 0946e89a647..6d60c58cc3a 100644
--- a/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
+++ b/release/scripts/startup/bl_operators/screen_play_rendered_anim.py
@@ -130,6 +130,7 @@ class PlayRenderedAnim(Operator):
                 "-s", str(frame_start),
                 "-e", str(frame_end),
                 "-j", str(scene.frame_step),
+                "-c", str(prefs.system.memory_cache_limit),
                 file,
             ]
             cmd.extend(opts)
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 96eeca18b24..0bf6fcd94a0 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -241,6 +241,7 @@ typedef struct PlayAnimPict {
 #ifdef USE_FRAME_CACHE_LIMIT
   /** Back pointer to the #LinkData node for this struct in the #inmempicsbase list. */
   LinkData *frame_cache_node;
+  size_t size_in_memory;
 #endif
 } PlayAnimPict;
 
@@ -254,7 +255,11 @@ static double fps_movie;
 
 #ifdef USE_FRAME_CACHE_LIMIT
 static struct ListBase inmempicsbase = {NULL, NULL};
+/** Keep track of the memory used by #inmempicsbase when `frame_cache_memory_limit != 0`. */
+size_t inmempicsbase_size_in_memory = 0;
 static int added_images = 0;
+/** Limit the amount of memory used for cache (in bytes). */
+static size_t frame_cache_memory_limit = 0;
 #endif
 
 static PlayAnimPict *playanim_step(PlayAnimPict *playanim, int step)
@@ -1227,6 +1232,15 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
           argc--;
           argv++;
           break;
+        case 'c': {
+#ifdef USE_FRAME_CACHE_LIMIT
+          const int memory_in_mb = max_ii(0, atoi(argv[2]));
+          frame_cache_memory_limit = (size_t)memory_in_mb * (1024 * 1024);
+#endif
+          argc--;
+          argv++;
+          break;
+        }
         default:
           printf("unknown option '%c': skipping\n", argv[1][1]);
           break;
@@ -1422,8 +1436,19 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
 #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) {
+        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++;
+
+          if (frame_cache_memory_limit != 0) {
+            BLI_assert(ps.picture->size_in_memory == 0);
+            ps.picture->size_in_memory = IMB_get_size_in_memory(ps.picture->ibuf);
+            inmempicsbase_size_in_memory += ps.picture->size_in_memory;
+          }
+        }
+        else {
+          /* Don't free the current frame by moving it to the head of the list. */
           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);
@@ -1431,14 +1456,20 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
 
         /* Really basic memory conservation scheme. Keep frames in a FIFO queue. */
         LinkData *node = inmempicsbase.last;
-
-        while (node && added_images > PLAY_FRAME_CACHE_MAX) {
+        while (node && (frame_cache_memory_limit ?
+                            (inmempicsbase_size_in_memory > frame_cache_memory_limit) :
+                            (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);
+            if (frame_cache_memory_limit != 0) {
+              BLI_assert(pic->size_in_memory != 0);
+              inmempicsbase_size_in_memory -= pic->size_in_memory;
+              pic->size_in_memory = 0;
+            }
             pic->ibuf = NULL;
             pic->frame_cache_node = NULL;
             node_tmp = node->prev;
@@ -1451,11 +1482,6 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
           }
         }
 
-        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));
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index d7f649b657d..9c7b7dc3f34 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -1189,7 +1189,10 @@ static const char arg_handle_playback_mode_doc[] =
     "\t-s <frame>\n"
     "\t\tPlay from <frame>.\n"
     "\t-e <frame>\n"
-    "\t\tPlay until <frame>.";
+    "\t\tPlay until <frame>.\n"
+    "\t-c <cache_memory>\n"
+    "\t\tAmount of memory in megabytes to allow for caching images during playback.\n"
+    "\t\tZero disables (clamping to a fixed number of frames instead).";
 static int arg_handle_playback_mode(int argc, const char **argv, void *UNUSED(data))
 {
   /* not if -b was given first */



More information about the Bf-blender-cvs mailing list