From cacc1d723c763e8ea1f8e616e98b2dc35ed25f26 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Fri, 29 Jan 2021 15:19:01 +0100 Subject: Fix T81169: Grease Pencil Z-depth drawing issue on OSX + AMD Graphic Cards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The grease pencil merge depth shader is designed to only work correctly in octographic mode. The uv coordinates used `noperspective` attribute. Somehow this doesn't lead to render artifacts on most platforms and was only detected on OSX + AMD cards. This fix would calculate the uv coordinate inside the fragment shader and isn't passed along from the vertex shader. Thanks to Sebastián Barschkis for providing the hardware and time and Clément Foucault for helping out with the final fix. --- .../draw/engines/gpencil/shaders/gpencil_depth_merge_frag.glsl | 5 +---- .../draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_frag.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_frag.glsl index 71597197bd8..2f711f6a2c5 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_frag.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_frag.glsl @@ -1,13 +1,10 @@ uniform sampler2D depthBuf; -uniform float strokeDepth2d; uniform bool strokeOrder3d; -noperspective in vec4 uvcoordsvar; - void main() { - float depth = textureLod(depthBuf, uvcoordsvar.xy, 0).r; + float depth = textureLod(depthBuf, gl_FragCoord.xy / vec2(textureSize(depthBuf, 0)), 0).r; if (strokeOrder3d) { gl_FragDepth = depth; } diff --git a/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl b/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl index 1e5a900f486..0c5260a9ec4 100644 --- a/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl +++ b/source/blender/draw/engines/gpencil/shaders/gpencil_depth_merge_vert.glsl @@ -1,8 +1,6 @@ uniform vec4 gpModelMatrix[4]; -noperspective out vec4 uvcoordsvar; - void main() { mat4 model_matrix = mat4(gpModelMatrix[0], gpModelMatrix[1], gpModelMatrix[2], gpModelMatrix[3]); @@ -10,5 +8,4 @@ void main() float x = -1.0 + float((v & 1) << 2); float y = -1.0 + float((v & 2) << 1); gl_Position = ViewProjectionMatrix * (model_matrix * vec4(x, y, 0.0, 1.0)); - uvcoordsvar = vec4((gl_Position.xy / gl_Position.w + 1.0) * 0.5, 0.0, 0.0); } -- cgit v1.2.3 From 087777f2b9b8c7cfc75458c6e6e714e92e2e2851 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Fri, 29 Jan 2021 15:48:14 +0100 Subject: Cleanup: accept const pointer for BKE_scene_get_depsgraph --- source/blender/blenkernel/BKE_scene.h | 3 ++- source/blender/blenkernel/intern/scene.c | 9 ++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index a3d40e093d9..b2726885593 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -223,7 +223,8 @@ void BKE_scene_free_depsgraph_hash(struct Scene *scene); void BKE_scene_free_view_layer_depsgraph(struct Scene *scene, struct ViewLayer *view_layer); /* Do not allocate new depsgraph. */ -struct Depsgraph *BKE_scene_get_depsgraph(struct Scene *scene, struct ViewLayer *view_layer); +struct Depsgraph *BKE_scene_get_depsgraph(const struct Scene *scene, + const struct ViewLayer *view_layer); /* Allocate new depsgraph if necessary. */ struct Depsgraph *BKE_scene_ensure_depsgraph(struct Main *bmain, struct Scene *scene, diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 11cdf67cb82..f16d2ff7619 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -3436,10 +3436,13 @@ static Depsgraph **scene_ensure_depsgraph_p(Main *bmain, Scene *scene, ViewLayer return depsgraph_ptr; } -Depsgraph *BKE_scene_get_depsgraph(Scene *scene, ViewLayer *view_layer) +Depsgraph *BKE_scene_get_depsgraph(const Scene *scene, const ViewLayer *view_layer) { - Depsgraph **depsgraph_ptr = scene_get_depsgraph_p(scene, view_layer, false); - return (depsgraph_ptr != NULL) ? *depsgraph_ptr : NULL; + BLI_assert(BKE_scene_has_view_layer(scene, view_layer)); + + DepsgraphKey key; + key.view_layer = view_layer; + return BLI_ghash_lookup(scene->depsgraph_hash, &key); } Depsgraph *BKE_scene_ensure_depsgraph(Main *bmain, Scene *scene, ViewLayer *view_layer) -- cgit v1.2.3 From 0e37d3efc017151309b272e4562edd901bfbde7a Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Thu, 28 Jan 2021 13:36:23 +0100 Subject: Fix T84717: missing 3D viewport updates when changing shading settings Previously this relied on the dependency graph to detect changes in the screen datablock, which would then notify the renderers. This was rather indirect an not even really by design. Instead use notifiers to tag specific 3D viewports to be updated. Includes changes to BKE_scene_get_depsgraph to accept a const Scene pointer. Testing if this works correctly requires adding back commits 81d444c and 088904d, since those have been temporarily reverted. Differential Revision: https://developer.blender.org/D10235 --- source/blender/blenkernel/intern/scene.c | 2 +- source/blender/depsgraph/DEG_depsgraph.h | 3 +- source/blender/editors/include/ED_render.h | 14 ++- source/blender/editors/render/render_update.c | 133 +++++++++++---------- source/blender/editors/space_view3d/space_view3d.c | 13 +- 5 files changed, 93 insertions(+), 72 deletions(-) diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index f16d2ff7619..6d262d8116d 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -3301,7 +3301,7 @@ int BKE_scene_multiview_num_videos_get(const RenderData *rd) /* This is a key which identifies depsgraph. */ typedef struct DepsgraphKey { - ViewLayer *view_layer; + const ViewLayer *view_layer; /* TODO(sergey): Need to include window somehow (same layer might be in a * different states in different windows). */ diff --git a/source/blender/depsgraph/DEG_depsgraph.h b/source/blender/depsgraph/DEG_depsgraph.h index 0ded511b8f8..567916fdebe 100644 --- a/source/blender/depsgraph/DEG_depsgraph.h +++ b/source/blender/depsgraph/DEG_depsgraph.h @@ -175,7 +175,8 @@ typedef struct DEGEditorUpdateContext { } DEGEditorUpdateContext; typedef void (*DEG_EditorUpdateIDCb)(const DEGEditorUpdateContext *update_ctx, struct ID *id); -typedef void (*DEG_EditorUpdateSceneCb)(const DEGEditorUpdateContext *update_ctx, int updated); +typedef void (*DEG_EditorUpdateSceneCb)(const DEGEditorUpdateContext *update_ctx, + const bool updated); /* Set callbacks which are being called when depsgraph changes. */ void DEG_editors_set_update_cb(DEG_EditorUpdateIDCb id_func, DEG_EditorUpdateSceneCb scene_func); diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h index d580e36d0ce..9cdecc444c8 100644 --- a/source/blender/editors/include/ED_render.h +++ b/source/blender/editors/include/ED_render.h @@ -29,15 +29,17 @@ extern "C" { #endif +struct bContext; +struct bScreen; struct DEGEditorUpdateContext; +struct Depsgraph; struct ID; -struct MTex; struct Main; +struct MTex; struct Render; struct Scene; struct ScrArea; -struct bContext; -struct bScreen; +struct wmWindow; struct wmWindowManager; /* render_ops.c */ @@ -53,7 +55,11 @@ void ED_render_view_layer_changed(struct Main *bmain, struct bScreen *screen); /* Callbacks handling data update events coming from depsgraph. */ void ED_render_id_flush_update(const struct DEGEditorUpdateContext *update_ctx, struct ID *id); -void ED_render_scene_update(const struct DEGEditorUpdateContext *update_ctx, int updated); +void ED_render_scene_update(const struct DEGEditorUpdateContext *update_ctx, const bool updated); +void ED_render_view3d_update(struct Depsgraph *depsgraph, + struct wmWindow *window, + struct ScrArea *area, + const bool updated); struct Scene *ED_render_job_get_scene(const struct bContext *C); struct Scene *ED_render_job_get_current_scene(const struct bContext *C); diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 0968560678b..499ffac6028 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -61,23 +61,79 @@ #include "ED_view3d.h" #include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" #include "WM_api.h" #include "render_intern.h" /* own include */ +#include + /***************************** Render Engines ********************************/ -void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int updated) +/* Update 3D viewport render or draw engine on changes to the scene or view settings . */ +void ED_render_view3d_update(Depsgraph *depsgraph, + wmWindow *window, + ScrArea *area, + const bool updated) +{ + Main *bmain = DEG_get_bmain(depsgraph); + Scene *scene = DEG_get_input_scene(depsgraph); + ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); + + LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + if (region->regiontype != RGN_TYPE_WINDOW) { + continue; + } + + View3D *v3d = area->spacedata.first; + RegionView3D *rv3d = region->regiondata; + RenderEngine *engine = rv3d->render_engine; + + /* call update if the scene changed, or if the render engine + * tagged itself for update (e.g. because it was busy at the + * time of the last update) */ + if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) { + /* Create temporary context to execute callback in. */ + bContext *C = CTX_create(); + CTX_data_main_set(C, bmain); + CTX_data_scene_set(C, scene); + CTX_wm_manager_set(C, bmain->wm.first); + CTX_wm_window_set(C, window); + CTX_wm_screen_set(C, WM_window_get_active_screen(window)); + CTX_wm_area_set(C, area); + CTX_wm_region_set(C, region); + + engine->flag &= ~RE_ENGINE_DO_UPDATE; + /* NOTE: Important to pass non-updated depsgraph, This is because this function is called + * from inside dependency graph evaluation. Additionally, if we pass fully evaluated one + * we will lose updates stored in the graph. */ + engine->type->view_update(engine, C, CTX_data_depsgraph_pointer(C)); + + CTX_free(C); + } + else { + RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); + if (updated) { + DRW_notify_view_update((&(DRWUpdateContext){ + .bmain = bmain, + .depsgraph = depsgraph, + .scene = scene, + .view_layer = view_layer, + .region = region, + .v3d = v3d, + .engine_type = engine_type, + })); + } + } + } +} + +/* Update all 3D viewport render and draw engines on changes to the scene. + * This is called by the dependency graph when it detects changes. */ +void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, const bool updated) { - /* viewport rendering update on data changes, happens after depsgraph - * updates if there was any change. context is set to the 3d view */ Main *bmain = update_ctx->bmain; - Scene *scene = update_ctx->scene; - ViewLayer *view_layer = update_ctx->view_layer; - bContext *C; - wmWindowManager *wm; - wmWindow *win; static bool recursive_check = false; /* don't do this render engine update if we're updating the scene from @@ -98,66 +154,17 @@ void ED_render_scene_update(const DEGEditorUpdateContext *update_ctx, int update recursive_check = true; - C = CTX_create(); - CTX_data_main_set(C, bmain); - CTX_data_scene_set(C, scene); - - CTX_wm_manager_set(C, bmain->wm.first); - wm = bmain->wm.first; - - for (win = wm->windows.first; win; win = win->next) { - bScreen *screen = WM_window_get_active_screen(win); - ScrArea *area; - ARegion *region; - - CTX_wm_window_set(C, win); + wmWindowManager *wm = bmain->wm.first; + LISTBASE_FOREACH (wmWindow *, window, &wm->windows) { + bScreen *screen = WM_window_get_active_screen(window); - for (area = screen->areabase.first; area; area = area->next) { - if (area->spacetype != SPACE_VIEW3D) { - continue; - } - View3D *v3d = area->spacedata.first; - for (region = area->regionbase.first; region; region = region->next) { - if (region->regiontype != RGN_TYPE_WINDOW) { - continue; - } - RegionView3D *rv3d = region->regiondata; - RenderEngine *engine = rv3d->render_engine; - /* call update if the scene changed, or if the render engine - * tagged itself for update (e.g. because it was busy at the - * time of the last update) */ - if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) { - - CTX_wm_screen_set(C, screen); - CTX_wm_area_set(C, area); - CTX_wm_region_set(C, region); - - engine->flag &= ~RE_ENGINE_DO_UPDATE; - /* NOTE: Important to pass non-updated depsgraph, This is because this function is called - * from inside dependency graph evaluation. Additionally, if we pass fully evaluated one - * we will lose updates stored in the graph. */ - engine->type->view_update(engine, C, CTX_data_depsgraph_pointer(C)); - } - else { - RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); - if (updated) { - DRW_notify_view_update((&(DRWUpdateContext){ - .bmain = bmain, - .depsgraph = update_ctx->depsgraph, - .scene = scene, - .view_layer = view_layer, - .region = region, - .v3d = (View3D *)area->spacedata.first, - .engine_type = engine_type, - })); - } - } + LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { + if (area->spacetype == SPACE_VIEW3D) { + ED_render_view3d_update(update_ctx->depsgraph, window, area, updated); } } } - CTX_free(C); - recursive_check = false; } diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 34d342ddd94..4c168c7a243 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -53,6 +53,7 @@ #include "BKE_screen.h" #include "BKE_workspace.h" +#include "ED_render.h" #include "ED_screen.h" #include "ED_space_api.h" #include "ED_transform.h" @@ -784,7 +785,7 @@ static void *view3d_main_region_duplicate(void *poin) } static void view3d_main_region_listener( - wmWindow *UNUSED(win), ScrArea *area, ARegion *region, wmNotifier *wmn, const Scene *scene) + wmWindow *win, ScrArea *area, ARegion *region, wmNotifier *wmn, const Scene *scene) { View3D *v3d = area->spacedata.first; RegionView3D *rv3d = region->regiondata; @@ -1001,11 +1002,17 @@ static void view3d_main_region_listener( if (wmn->subtype == NS_VIEW3D_GPU) { rv3d->rflag |= RV3D_GPULIGHT_UPDATE; } -#ifdef WITH_XR_OPENXR else if (wmn->subtype == NS_VIEW3D_SHADING) { +#ifdef WITH_XR_OPENXR ED_view3d_xr_shading_update(G_MAIN->wm.first, v3d, scene); - } #endif + + ViewLayer *view_layer = WM_window_get_active_view_layer(win); + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer); + if (depsgraph) { + ED_render_view3d_update(depsgraph, win, area, true); + } + } ED_region_tag_redraw(region); WM_gizmomap_tag_refresh(gzmap); } -- cgit v1.2.3 From 876fd40643dfa7b206edabbde30809e6e48e583b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 11 Jan 2021 14:16:10 +0100 Subject: Fix T83411: Crash when using a workspace/layout data path in a driver Building IDs which are not covered by copy-on-write process was not implemented, which was causing parameters block not present, and, hence causing crashes in areas which expected parameters to present. First part of this change is related on making it so Copy-on-Write is optional for ID nodes in the dependency graph. Second part is related on using a generic builder for all ID types which were not covered by Copy-on-Write before. The final part is related on making it so build_id() is properly handling ParticleSettings and Grease Pencil Data. Before they were not covered there at all, and they need special handling because they do have own build functions. Not sure it worth trying to split those parts, as they are related to each other and are not really possible to be tested standalone. Open for a second opinion though. Possible nut-tightening is to re-organize build_id() function so that every branch does return and have an assert at the end, so that missing ID type in the switch statement is easier to spot even when using compilers which do not report missing switch cases. As for question "why not use default" the answer is: to make it more explicit and clear what is a decision when adding new ID types. We do not want to quietly fall-back to a non-copy-on-write case for a newly added ID types. Differential Revision: https://developer.blender.org/D10075 --- .../depsgraph/intern/builder/deg_builder_nodes.cc | 36 ++++++++++++++++++--- .../depsgraph/intern/builder/deg_builder_nodes.h | 3 ++ .../intern/builder/deg_builder_relations.cc | 37 +++++++++++++++++++--- .../intern/builder/deg_builder_relations.h | 3 ++ source/blender/makesdna/DNA_ID.h | 3 +- 5 files changed, 73 insertions(+), 9 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 2edd4ddf853..b0a5f1a34d6 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -388,7 +388,9 @@ void DepsgraphNodeBuilder::build_id(ID *id) if (id == nullptr) { return; } - switch (GS(id->name)) { + + const ID_Type id_type = GS(id->name); + switch (id_type) { case ID_AC: build_action((bAction *)id); break; @@ -478,13 +480,39 @@ void DepsgraphNodeBuilder::build_id(ID *id) case ID_SIM: build_simulation((Simulation *)id); break; - default: - fprintf(stderr, "Unhandled ID %s\n", id->name); - BLI_assert(!"Should never happen"); + case ID_PA: + build_particle_settings((ParticleSettings *)id); + break; + case ID_GD: + build_gpencil((bGPdata *)id); + break; + + case ID_LI: + case ID_IP: + case ID_SCR: + case ID_VF: + case ID_BR: + case ID_WM: + case ID_PAL: + case ID_PC: + case ID_WS: + BLI_assert(!deg_copy_on_write_is_needed(id_type)); + build_generic_id(id); break; } } +void DepsgraphNodeBuilder::build_generic_id(ID *id) +{ + if (built_map_.checkIsBuiltAndTag(id)) { + return; + } + + build_idproperties(id->properties); + build_animdata(id); + build_parameters(id); +} + static void build_idproperties_callback(IDProperty *id_property, void *user_data) { DepsgraphNodeBuilder *builder = reinterpret_cast(user_data); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h index 174f9b129f9..a7033c8c8f3 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h @@ -152,6 +152,9 @@ class DepsgraphNodeBuilder : public DepsgraphBuilder { virtual void build_id(ID *id); + /* Build function for ID types that do not need their own build_xxx() function. */ + virtual void build_generic_id(ID *id); + virtual void build_idproperties(IDProperty *id_property); virtual void build_scene_render(Scene *scene, ViewLayer *view_layer); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index ed78956e548..3c42f0f0612 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -491,7 +491,9 @@ void DepsgraphRelationBuilder::build_id(ID *id) if (id == nullptr) { return; } - switch (GS(id->name)) { + + const ID_Type id_type = GS(id->name); + switch (id_type) { case ID_AC: build_action((bAction *)id); break; @@ -567,13 +569,40 @@ void DepsgraphRelationBuilder::build_id(ID *id) case ID_SIM: build_simulation((Simulation *)id); break; - default: - fprintf(stderr, "Unhandled ID %s\n", id->name); - BLI_assert(!"Should never happen"); + case ID_PA: + build_particle_settings((ParticleSettings *)id); + break; + case ID_GD: + build_gpencil((bGPdata *)id); + break; + + case ID_LI: + case ID_IP: + case ID_SCR: + case ID_VF: + case ID_BR: + case ID_WM: + case ID_PAL: + case ID_PC: + case ID_WS: + BLI_assert(!deg_copy_on_write_is_needed(id_type)); + build_generic_id(id); break; } } +void DepsgraphRelationBuilder::build_generic_id(ID *id) +{ + + if (built_map_.checkIsBuiltAndTag(id)) { + return; + } + + build_idproperties(id->properties); + build_animdata(id); + build_parameters(id); +} + static void build_idproperties_callback(IDProperty *id_property, void *user_data) { DepsgraphRelationBuilder *builder = reinterpret_cast(user_data); diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h index 5587379089c..21d1d4b6268 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h @@ -198,6 +198,9 @@ class DepsgraphRelationBuilder : public DepsgraphBuilder { virtual void build_id(ID *id); + /* Build function for ID types that do not need their own build_xxx() function. */ + virtual void build_generic_id(ID *id); + virtual void build_idproperties(IDProperty *id_property); virtual void build_scene_render(Scene *scene, ViewLayer *view_layer); diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 51c47e917f1..263ce2203e9 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -526,7 +526,8 @@ typedef enum ID_Type { #define ID_IS_ASSET(_id) (((const ID *)(_id))->asset_data != NULL) /* Check whether datablock type is covered by copy-on-write. */ -#define ID_TYPE_IS_COW(_id_type) (!ELEM(_id_type, ID_BR, ID_PAL, ID_IM)) +#define ID_TYPE_IS_COW(_id_type) \ + (!ELEM(_id_type, ID_LI, ID_IP, ID_SCR, ID_VF, ID_BR, ID_WM, ID_PAL, ID_PC, ID_WS, ID_IM)) #ifdef GS # undef GS -- cgit v1.2.3 From b3fc88554468eb91fac3c2afb9387e599e6db507 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 13 Jan 2021 10:17:01 +0100 Subject: Depsgraph: Remove redundant copy-on-write operations This change removes copy-on-write operations from ID nodes which do not need copy-on-write. Should be no functional changes, as before the copy-on-write operation would do nothing for those nodes anyway. --- source/blender/depsgraph/intern/builder/deg_builder_nodes.cc | 7 +++---- source/blender/depsgraph/intern/builder/deg_builder_relations.cc | 6 ++++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index b0a5f1a34d6..c3304cd80ff 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -155,6 +155,7 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id) { BLI_assert(id->session_uuid != MAIN_ID_SESSION_UUID_UNSET); + const ID_Type id_type = GS(id->name); IDNode *id_node = nullptr; ID *id_cow = nullptr; IDComponentsMask previously_visible_components_mask = 0; @@ -173,10 +174,8 @@ IDNode *DepsgraphNodeBuilder::add_id_node(ID *id) id_node->previously_visible_components_mask = previously_visible_components_mask; id_node->previous_eval_flags = previous_eval_flags; id_node->previous_customdata_masks = previous_customdata_masks; - /* Currently all ID nodes are supposed to have copy-on-write logic. - * - * NOTE: Zero number of components indicates that ID node was just created. */ - if (id_node->components.is_empty()) { + /* NOTE: Zero number of components indicates that ID node was just created. */ + if (id_node->components.is_empty() && deg_copy_on_write_is_needed(id_type)) { ComponentNode *comp_cow = id_node->add_component(NodeType::COPY_ON_WRITE); OperationNode *op_cow = comp_cow->add_operation( function_bind(deg_evaluate_copy_on_write, _1, id_node), diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc index 3c42f0f0612..463efe52375 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc @@ -2834,7 +2834,13 @@ void DepsgraphRelationBuilder::build_nested_shapekey(ID *owner, Key *key) void DepsgraphRelationBuilder::build_copy_on_write_relations(IDNode *id_node) { ID *id_orig = id_node->id_orig; + const ID_Type id_type = GS(id_orig->name); + + if (!deg_copy_on_write_is_needed(id_type)) { + return; + } + TimeSourceKey time_source_key; OperationKey copy_on_write_key(id_orig, NodeType::COPY_ON_WRITE, OperationCode::COPY_ON_WRITE); /* XXX: This is a quick hack to make Alt-A to work. */ -- cgit v1.2.3