[Bf-blender-cvs] [e63a1b3d98b] undo-experiments: Merge branch 'id-ensure-unique-memory-address' into undo-experiments

Bastien Montagne noreply at git.blender.org
Fri Feb 21 16:46:34 CET 2020


Commit: e63a1b3d98bf0a87567ebe8041f56fbc4a3c7fc1
Author: Bastien Montagne
Date:   Fri Feb 21 15:54:46 2020 +0100
Branches: undo-experiments
https://developer.blender.org/rBe63a1b3d98bf0a87567ebe8041f56fbc4a3c7fc1

Merge branch 'id-ensure-unique-memory-address' into undo-experiments

Conflicts:
	source/blender/blenloader/intern/readfile.c

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



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

diff --cc source/blender/blenkernel/BKE_main.h
index eb3001233e8,dec142624f2..d48e5a5cec6
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@@ -99,14 -99,10 +99,15 @@@ typedef struct Main 
     * use "needs_flush_to_id" in edit data to flag data which needs updating.
     */
    char is_memfile_undo_flush_needed;
 +  /**
 +   * Indicates that next memfile undo step should not allow to re-use old bmain when re-read, but
 +   * instead do a complete full re-read/update from stored memfile.
 +   */
 +  char use_memfile_full_barrier;
  
-   struct GSet *used_id_memset;
-   short used_id_memset_tag;
+   struct GHash *used_id_memhash;
+   struct LinkNode *used_id_memhash_history_chains;
+   short used_id_memhash_tag;
  
    BlendThumbnail *blen_thumb;
  
diff --cc source/blender/blenloader/intern/readfile.c
index caf1629036d,f9abf557eeb..c2e3caee1c4
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@@ -2299,13 -2246,7 +2301,14 @@@ static void *read_struct(FileData *fd, 
        }
        else {
          /* SDNA_CMP_EQUAL */
 -        temp = MEM_mallocN(bh->len, blockname);
 +        if (fd->memfile != NULL && !ELEM(bh->code, DATA, GLOB, DNA1, TEST, REND, USER, ENDB)) {
 +          Main *bmain = fd->mainlist->first;
-           temp = BKE_main_idmemset_unique_alloc(bmain, MEM_mallocN, (size_t)bh->len, blockname);
++          temp = BKE_main_idmemhash_unique_alloc(
++              bmain, NULL, MEM_mallocN, (size_t)bh->len, blockname);
 +        }
 +        else {
 +          temp = MEM_mallocN(bh->len, blockname);
 +        }
  #ifdef USE_BHEAD_READ_ON_DEMAND
          if (BHEADN_FROM_BHEAD(bh)->has_data) {
            memcpy(temp, (bh + 1), bh->len);
@@@ -9066,93 -9013,10 +9079,93 @@@ static BHead *read_libblock(FileData *f
    }
  
    /* read libblock */
 +  fd->are_memchunks_identical = true;
    id = read_struct(fd, bhead, "lib block");
  
 -  if (id) {
 +  BHead *id_bhead = bhead;
 +
 +  if (id != NULL) {
      const short idcode = GS(id->name);
 +    const bool do_partial_undo = (fd->skip_flags & BLO_READ_SKIP_UNDO_OLD_MAIN) == 0;
 +
 +    if (id_bhead->code != ID_LINK_PLACEHOLDER) {
 +      /* need a name for the mallocN, just for debugging and sane prints on leaks */
 +      allocname = dataname(idcode);
 +
 +      /* read all data into fd->datamap */
 +      /* TODO: instead of building oldnewmap here we could just quickly check the bheads... could
 +       * save some more ticks. Probably not worth it though, bottleneck is full depsgraph rebuild
 +       * and eval, not actual file reading. */
 +      bhead = read_data_into_oldnewmap(fd, id_bhead, allocname);
 +
 +      DEBUG_PRINTF(
 +          "%s: ID %s is unchanged: %d\n", __func__, id->name, fd->are_memchunks_identical);
 +
 +      if (fd->memfile != NULL) {
 +        BLI_assert(fd->old_idmap != NULL || !do_partial_undo);
 +        /* This code should only ever be reached for local data-blocks. */
 +        BLI_assert(main->curlib == NULL);
 +
 +        /* Find the 'current' existing ID we want to reuse instead of the one we would read from
 +         * the undo memfile. */
 +        ID *id_old = do_partial_undo ?
 +                         BKE_main_idmap_lookup(fd->old_idmap, idcode, id->name + 2, NULL) :
 +                         NULL;
 +        bool can_finalize_and_return = false;
 +
 +        if (ELEM(idcode, ID_WM, ID_SCR, ID_WS)) {
 +          /* Read WindowManager, Screen and WorkSpace IDs are never during undo (see
 +           * `setup_app_data()` in `blendfile.c`).
 +           * So we can just abort here, just ensuring libmapping is set accordingly. */
 +          can_finalize_and_return = true;
 +        }
 +        else if (id_old != NULL && fd->are_memchunks_identical) {
 +          /* Do not add LIB_TAG_NEW here, this should not be needed/used in undo case anyway (as
 +           * this is only for do_version-like code), but for sake of consistency, and also because
 +           * it will tell us which ID is re-used from old Main, and which one is actually new. */
 +          id_old->tag = tag | LIB_TAG_NEED_LINK | LIB_TAG_UNDO_OLD_ID_REUSED;
 +          id_old->lib = main->curlib;
 +          id_old->us = ID_FAKE_USERS(id_old);
 +          /* Do not reset id->icon_id here, memory allocated for it remains valid. */
 +          /* Needed because .blend may have been saved with crap value here... */
 +          id_old->newid = NULL;
 +          id_old->orig_id = NULL;
 +
 +          Main *old_bmain = fd->old_mainlist->first;
 +          BLI_assert(old_bmain == BKE_main_idmap_main_get(fd->old_idmap));
 +          ListBase *old_lb = which_libbase(old_bmain, idcode);
 +          ListBase *new_lb = which_libbase(main, idcode);
 +          BLI_remlink(old_lb, id_old);
 +          BLI_addtail(new_lb, id_old);
 +
 +          can_finalize_and_return = true;
 +        }
 +
 +        if (can_finalize_and_return) {
 +          oldnewmap_insert(fd->libmap, id_bhead->old, id_old, id_bhead->code);
 +          if (id_old != NULL) {
 +            oldnewmap_insert(fd->libmap_undo_reused, id_old, id_old, id_bhead->code);
 +          }
 +
 +          if (r_id) {
 +            *r_id = id_old;
 +          }
 +
-           const bool is_id_memaddress_already_registered = !BKE_main_idmemset_register_id(main,
-                                                                                           id_old);
++          const bool is_id_memaddress_already_registered = !BKE_main_idmemhash_register_id(
++              main, NULL, id_old);
 +          /* Should never fail, since we re-used an existing ID it should have already been
 +           * registered. */
 +          BLI_assert(is_id_memaddress_already_registered);
 +
 +          MEM_freeN(id);
 +          oldnewmap_free_unused(fd->datamap);
 +          oldnewmap_clear(fd->datamap);
 +
 +          return bhead;
 +        }
 +      }
 +    }
 +
      /* do after read_struct, for dna reconstruct */
      lb = which_libbase(main, idcode);
      if (lb) {
@@@ -9870,13 -9658,7 +9883,13 @@@ BlendFileData *blo_read_file_internal(F
    bfd = MEM_callocN(sizeof(BlendFileData), "blendfiledata");
  
    bfd->main = BKE_main_new();
 -  BKE_main_idmemhash_ensure(bfd->main);
 +  if (fd->memfile != NULL) {
 +    /* In undo case we want to keep the set of qlreqdy used ID pointers... */
-     BKE_main_idmemset_transfer_ownership(bfd->main, fd->old_mainlist->first);
++    BKE_main_idmemhash_transfer_ownership(bfd->main, fd->old_mainlist->first);
 +  }
 +  else {
-     BKE_main_idmemset_ensure(bfd->main);
++    BKE_main_idmemhash_ensure(bfd->main);
 +  }
    bfd->main->versionfile = fd->fileversion;
  
    bfd->type = BLENFILETYPE_BLEND;



More information about the Bf-blender-cvs mailing list