diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2020-03-11 19:25:17 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2020-03-11 19:38:42 +0300 |
commit | e9220d5cd013340bde288c85b5125028c1400499 (patch) | |
tree | 457f7efd7600d4b61bf4639ff0e18349edd9c58b /source/blender/depsgraph/intern/node | |
parent | 19b46b2fca790f00c7da79ecbcf219e772874a2c (diff) |
Depsgraph: Fix crash deleting Viewer image from Outliner
Was happening when having compositor open with Viewer node attached
directly to Render Layers output.
There were two things involved here:
1. The code which was storing CoW-ed versions of IDs was checking all
IDs for whether they are expanded or not. This was causing access
of freed memory for deleted IDs which do not need CoW (such as IM).
Simple fix: store ID type as a scalar and use early check before
doing more elaborate check based on accessing fields of id_cow.
2. The code which was ensuring view layer pointer is doing CoW for
scene. This isn't an issue on its own, but scene might have an
embedded ID such as compositor which was actually traversed by the
ID remap routines. This was causing remapping procedure to go into
non-updated copy of compositor, accessing freed Viewer image ID.
Solved by not recursing into embedded IDs for datablocks as those
are supposed to have own copy-on-write operations which takes care
of re-mapping.
Reported my Bastien, and also pair-coded with him.
Diffstat (limited to 'source/blender/depsgraph/intern/node')
-rw-r--r-- | source/blender/depsgraph/intern/node/deg_node_id.cc | 1 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/node/deg_node_id.h | 5 |
2 files changed, 6 insertions, 0 deletions
diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc index 0fbf658ceb3..cd25cc14069 100644 --- a/source/blender/depsgraph/intern/node/deg_node_id.cc +++ b/source/blender/depsgraph/intern/node/deg_node_id.cc @@ -103,6 +103,7 @@ void IDNode::init(const ID *id, const char *UNUSED(subdata)) { BLI_assert(id != nullptr); /* Store ID-pointer. */ + id_type = GS(id->name); id_orig = (ID *)id; eval_flags = 0; previous_eval_flags = 0; diff --git a/source/blender/depsgraph/intern/node/deg_node_id.h b/source/blender/depsgraph/intern/node/deg_node_id.h index 886c25b5a4e..6eea31ebff9 100644 --- a/source/blender/depsgraph/intern/node/deg_node_id.h +++ b/source/blender/depsgraph/intern/node/deg_node_id.h @@ -25,6 +25,7 @@ #include "intern/node/deg_node.h" #include "BLI_sys_types.h" +#include "DNA_ID.h" struct GHash; @@ -73,6 +74,10 @@ struct IDNode : public Node { IDComponentsMask get_visible_components_mask() const; /* ID Block referenced. */ + /* Type of the ID stored separately, so it's possible to perform check whether CoW is needed + * without de-referencing the id_cow (which is not safe when ID is NOT covered by CoW and has + * been deleted from the main database.) */ + ID_Type id_type; ID *id_orig; ID *id_cow; |