diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-07-20 18:45:00 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-07-20 18:48:36 +0300 |
commit | 3ededb19d8bb42c97188a0db027a46fac064f963 (patch) | |
tree | e5f469e35e22e983a57caa26585831ad15f22958 /source | |
parent | dfcb568c165913a15679f6b55b0b76e49a747a2e (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.cc | 29 |
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; } |