[Bf-blender-cvs] [8e0f8bb3e15] master: New undo cache management: Add Image IDs.

Bastien Montagne noreply at git.blender.org
Fri Jul 3 12:56:36 CEST 2020


Commit: 8e0f8bb3e153d5cae0050ceb90e6b561069fe05b
Author: Bastien Montagne
Date:   Fri Jul 3 12:34:20 2020 +0200
Branches: master
https://developer.blender.org/rB8e0f8bb3e153d5cae0050ceb90e6b561069fe05b

New undo cache management: Add Image IDs.

Some notes:
* `Image.cache` acts as some kind of 'main' cache, when it is NULL
  (could not be restored), other caches should also be cleared. Oddly
  enough, previous code was not clearing **all** caches, could not find
  any reason for that behavior, so new code does a full clear.
* `imamap` is still used for Node previews from scenes' compositor,
  however this is actually fully disabled in `direct_link_node()`.
* For render slots we cannot use offsetof as third part of the cache
  key, so we are using a hash of the slot's name instead.

As far as I can tell, this fixes T76989: Visual glitches when undo after
reload multiple images by script (in Material Preview).

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

M	source/blender/blenkernel/intern/image.c
M	source/blender/blenloader/intern/readfile.c

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

diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index bb793b58a1d..e1d055512f0 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -185,6 +185,37 @@ static void image_free_data(ID *id)
   BLI_freelistN(&image->tiles);
 }
 
+static void image_foreach_cache(ID *id,
+                                IDTypeForeachCacheFunctionCallback function_callback,
+                                void *user_data)
+{
+  Image *image = (Image *)id;
+  IDCacheKey key = {
+      .id_session_uuid = id->session_uuid,
+      .offset_in_ID = offsetof(Image, cache),
+      .cache_v = image->cache,
+  };
+  function_callback(id, &key, (void **)&image->cache, user_data);
+
+  for (int eye = 0; eye < 2; eye++) {
+    for (int a = 0; a < TEXTARGET_COUNT; a++) {
+      key.offset_in_ID = offsetof(Image, gputexture[a][eye]);
+      key.cache_v = image->gputexture[a][eye];
+      function_callback(id, &key, (void **)&image->gputexture[a][eye], user_data);
+    }
+  }
+
+  key.offset_in_ID = offsetof(Image, rr);
+  key.cache_v = image->rr;
+  function_callback(id, &key, (void **)&image->rr, user_data);
+
+  LISTBASE_FOREACH (RenderSlot *, slot, &image->renderslots) {
+    key.offset_in_ID = (size_t)BLI_ghashutil_strhash_p(slot->name);
+    key.cache_v = slot->render;
+    function_callback(id, &key, (void **)&slot->render, user_data);
+  }
+}
+
 IDTypeInfo IDType_ID_IM = {
     .id_code = ID_IM,
     .id_filter = FILTER_ID_IM,
@@ -200,6 +231,7 @@ IDTypeInfo IDType_ID_IM = {
     .free_data = image_free_data,
     .make_local = NULL,
     .foreach_id = NULL,
+    .foreach_cache = image_foreach_cache,
 };
 
 /* prototypes */
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index db530b749ad..28bab96cc6d 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1959,32 +1959,9 @@ void blo_end_scene_pointer_map(FileData *fd, Main *oldmain)
 
 void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
 {
-  Image *ima = oldmain->images.first;
   Scene *sce = oldmain->scenes.first;
-  int a;
-
   fd->imamap = oldnewmap_new();
 
-  for (; ima; ima = ima->id.next) {
-    if (ima->cache) {
-      oldnewmap_insert(fd->imamap, ima->cache, ima->cache, 0);
-    }
-    for (int eye = 0; eye < 2; eye++) {
-      for (a = 0; a < TEXTARGET_COUNT; a++) {
-        if (ima->gputexture[a][eye] != NULL) {
-          oldnewmap_insert(fd->imamap, ima->gputexture[a][eye], ima->gputexture[a][eye], 0);
-        }
-      }
-    }
-    if (ima->rr) {
-      oldnewmap_insert(fd->imamap, ima->rr, ima->rr, 0);
-    }
-    LISTBASE_FOREACH (RenderSlot *, slot, &ima->renderslots) {
-      if (slot->render) {
-        oldnewmap_insert(fd->imamap, slot->render, slot->render, 0);
-      }
-    }
-  }
   for (; sce; sce = sce->id.next) {
     if (sce->nodetree && sce->nodetree->previews) {
       bNodeInstanceHashIterator iter;
@@ -2001,7 +1978,6 @@ void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
 void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
 {
   OldNew *entry = fd->imamap->entries;
-  Image *ima = oldmain->images.first;
   Scene *sce = oldmain->scenes.first;
   int i;
 
@@ -2012,29 +1988,6 @@ void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
     }
   }
 
-  for (; ima; ima = ima->id.next) {
-    ima->cache = newimaadr(fd, ima->cache);
-    if (ima->cache == NULL) {
-      ima->gpuflag = 0;
-      ima->gpuframenr = INT_MAX;
-      for (int eye = 0; eye < 2; eye++) {
-        for (i = 0; i < TEXTARGET_COUNT; i++) {
-          ima->gputexture[i][eye] = NULL;
-        }
-      }
-      ima->rr = NULL;
-    }
-    LISTBASE_FOREACH (RenderSlot *, slot, &ima->renderslots) {
-      slot->render = newimaadr(fd, slot->render);
-    }
-
-    for (int eye = 0; eye < 2; eye++) {
-      for (i = 0; i < TEXTARGET_COUNT; i++) {
-        ima->gputexture[i][eye] = newimaadr(fd, ima->gputexture[i][eye]);
-      }
-    }
-    ima->rr = newimaadr(fd, ima->rr);
-  }
   for (; sce; sce = sce->id.next) {
     if (sce->nodetree && sce->nodetree->previews) {
       bNodeInstanceHash *new_previews = BKE_node_instance_hash_new("node previews");
@@ -4404,55 +4357,25 @@ static void direct_link_text(BlendDataReader *reader, Text *text)
 /** \name Read ID: Image
  * \{ */
 
-static void lib_link_image(BlendLibReader *UNUSED(reader), Image *UNUSED(ima))
+static void lib_link_image(BlendLibReader *UNUSED(reader), Image *ima)
 {
+  /* Images have some kind of 'main' cache, when NULL we should also clear all others.
+   * XXX It is not ideal to do that from here, but for now it will do. We have to do it after all
+   * cache pointers have been potentially remapped (in undo case) or NULL-ified. */
+  if (ima->cache == NULL) {
+    BKE_image_free_buffers(ima);
+  }
 }
 
 static void direct_link_image(BlendDataReader *reader, Image *ima)
 {
   ImagePackedFile *imapf;
 
-  /* for undo system, pointers could be restored */
-  if (reader->fd->imamap) {
-    ima->cache = newimaadr(reader->fd, ima->cache);
-  }
-  else {
-    ima->cache = NULL;
-  }
-
   BLO_read_list(reader, &ima->tiles);
 
-  /* if not restored, we keep the binded opengl index */
-  if (!ima->cache) {
-    ima->gpuflag = 0;
-    ima->gpuframenr = INT_MAX;
-    for (int eye = 0; eye < 2; eye++) {
-      for (int i = 0; i < TEXTARGET_COUNT; i++) {
-        ima->gputexture[i][eye] = NULL;
-      }
-    }
-    ima->rr = NULL;
-  }
-  else {
-    for (int eye = 0; eye < 2; eye++) {
-      for (int i = 0; i < TEXTARGET_COUNT; i++) {
-        ima->gputexture[i][eye] = newimaadr(reader->fd, ima->gputexture[i][eye]);
-      }
-    }
-    ima->rr = newimaadr(reader->fd, ima->rr);
-  }
-
-  /* undo system, try to restore render buffers */
   BLO_read_list(reader, &(ima->renderslots));
-  if (reader->fd->imamap) {
-    LISTBASE_FOREACH (RenderSlot *, slot, &ima->renderslots) {
-      slot->render = newimaadr(reader->fd, slot->render);
-    }
-  }
-  else {
-    LISTBASE_FOREACH (RenderSlot *, slot, &ima->renderslots) {
-      slot->render = NULL;
-    }
+  if (reader->fd->memfile == NULL) {
+    /* We reset this last render slot index only when actually reading a file, not for undo. */
     ima->last_render_slot = ima->render_slot;
   }



More information about the Bf-blender-cvs mailing list