Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2017-07-20 18:45:00 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2017-07-20 18:48:36 +0300
commit3ededb19d8bb42c97188a0db027a46fac064f963 (patch)
treee5f469e35e22e983a57caa26585831ad15f22958 /source
parentdfcb568c165913a15679f6b55b0b76e49a747a2e (diff)
Depsgraph: Fix crash when updating materials with copy on write enabled
The code was freeing GPU materials from non-main thread.
Diffstat (limited to 'source')
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc29
1 files changed, 29 insertions, 0 deletions
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index da06cfdf330..46841c3c8a3 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -664,9 +664,38 @@ ID *deg_update_copy_on_write_datablock(/*const*/ Depsgraph *depsgraph,
/* For the rest if datablock types we use simple logic:
* - Free previously expanded data, if any.
* - Perform full datablock copy.
+ *
+ * Note that we never free GPU materials from here since that's not
+ * safe for threading and GPU materials are likely to be re-used.
*/
+ ListBase gpumaterial_backup;
+ ListBase *gpumaterial_ptr = NULL;
+ if (check_datablock_expanded(id_cow)) {
+ switch (GS(id_orig->name)) {
+ case ID_MA:
+ {
+ Material *material = (Material *)id_cow;
+ gpumaterial_ptr = &material->gpumaterial;
+ break;
+ }
+ case ID_WO:
+ {
+ World *world = (World *)id_cow;
+ gpumaterial_ptr = &world->gpumaterial;
+ break;
+ }
+ }
+ if (gpumaterial_ptr != NULL) {
+ gpumaterial_backup = *gpumaterial_ptr;
+ gpumaterial_ptr->first = gpumaterial_ptr->last = NULL;
+ }
+ }
deg_free_copy_on_write_datablock(id_cow);
deg_expand_copy_on_write_datablock(depsgraph, id_node, false);
+ /* Restore GPU materials. */
+ if (gpumaterial_ptr != NULL) {
+ *gpumaterial_ptr = gpumaterial_backup;
+ }
return id_cow;
}