Commit: 2ac555fe47f575e37d0feb89c6ba23fe684ed44b
Author: Bastien Montagne
Date:   Mon Jan 4 20:17:23 2016 +0100
Branches: master
https://developer.blender.org/rB2ac555fe47f575e37d0feb89c6ba23fe684ed44b

ID: Sanitize handling of 'USER_ONE' (ensure_user) case.

Note that this has little impact on current master - yet it allows to fix the 
'Image Editor' bug
(open image in editor, use same image in texture, delete image from texture, 
image us is 0 and
red in image editor...) and probably a few other similar cases.

But that change is mandatory to get a proper handling of ID 
deletion/reamapping/reloading/etc. as done in id-remap branch.

Instead of just adding a user if none already present, new code use two new ID 
tags to get a three-states status:
  - Normal: nothing changes.
  - Needs extra user: we know that ID needs an extra user, so we take of never 
going down to 0 in 'real' usercount handling.
  - Has extra user: we do have increased that ID usercount to get our needed 
extrauser.

Reviewers: sergey, campbellbarton

Differential Revision: https://developer.blender.org/D1696

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

M       source/blender/blenkernel/intern/library.c
M       source/blender/makesdna/DNA_ID.h

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

diff --git a/source/blender/blenkernel/intern/library.c 
b/source/blender/blenkernel/intern/library.c
index 4403949..9e8d485 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -162,20 +162,38 @@ void id_lib_extern(ID *id)
 }
 
 /* ensure we have a real user */
+/* Note: Now that we have flags, we could get rid of the 'fake_user' special 
case, flags are enough to ensure
+ *       we always have a real user.
+ *       However, ID_REAL_USERS is used in several places outside of core 
library.c, so think we can wait later
+ *       to make this change... */
 void id_us_ensure_real(ID *id)
 {
        if (id) {
                const int limit = ID_FAKE_USERS(id);
+               id->tag |= LIB_TAG_EXTRAUSER;
                if (id->us <= limit) {
-                       if (id->us < limit) {
+                       if (id->us < limit || ((id->us == limit) && (id->tag & 
LIB_TAG_EXTRAUSER_SET))) {
                                printf("ID user count error: %s (from '%s')\n", 
id->name, id->lib ? id->lib->filepath : "[Main]");
                                BLI_assert(0);
                        }
                        id->us = limit + 1;
+                       id->tag |= LIB_TAG_EXTRAUSER_SET;
                }
        }
 }
 
+/* Unused currently... */
+static void UNUSED_FUNCTION(id_us_clear_real)(ID *id)
+{
+       if (id && (id->tag & LIB_TAG_EXTRAUSER)) {
+               if (id->tag & LIB_TAG_EXTRAUSER_SET) {
+                       id->us--;
+                       BLI_assert(id->us >= ID_FAKE_USERS(id));
+               }
+               id->tag &= ~(LIB_TAG_EXTRAUSER | LIB_TAG_EXTRAUSER_SET);
+       }
+}
+
 void id_us_plus(ID *id)
 {
        if (id) {
@@ -190,8 +208,15 @@ void id_us_min(ID *id)
 {
        if (id) {
                const int limit = ID_FAKE_USERS(id);
+
+               if ((id->us == limit) && (id->tag & LIB_TAG_EXTRAUSER) && 
!(id->tag & LIB_TAG_EXTRAUSER_SET)) {
+                       /* We need an extra user here, but never actually 
incremented user count for it so far, do it now. */
+                       id_us_ensure_real(id);
+               }
+
                if (id->us <= limit) {
-                       printf("ID user decrement error: %s (from '%s')\n", 
id->name, id->lib ? id->lib->filepath : "[Main]");
+                       printf("ID user decrement error: %s (from '%s'): %d <= 
%d\n",
+                              id->name, id->lib ? id->lib->filepath : 
"[Main]", id->us, limit);
                        /* We cannot assert here, because of how we 'delete' 
datablocks currently (setting their usercount to zero),
                         * this is weak but it's how it works for now. */
                        /* BLI_assert(0); */
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 74a63be..0bf3c35 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -313,6 +313,11 @@ enum {
        /* RESET_NEVER tag datablock as a place-holder (because the real one 
could not be linked from its library e.g.). */
        LIB_TAG_MISSING         = 1 << 6,
 
+       /* tag datablock has having an extra user. */
+       LIB_TAG_EXTRAUSER       = 1 << 2,
+       /* tag datablock has having actually increased usercount for the extra 
virtual user. */
+       LIB_TAG_EXTRAUSER_SET   = 1 << 7,
+
        /* RESET_AFTER_USE tag newly duplicated/copied IDs. */
        LIB_TAG_NEW             = 1 << 8,
        /* RESET_BEFORE_USE free test flag.

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to