diff options
15 files changed, 187 insertions, 95 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/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index e9a141709b5..2fc0caf1a2c 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -139,6 +139,7 @@ typedef struct SpaceType { /* region types are also defined using spacetypes_init, via a callback */ typedef struct wmRegionListenerParams { + struct wmWindow *window; struct ScrArea *area; /* Can be NULL when the region is not part of an area. */ struct ARegion *region; struct wmNotifier *notifier; diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 239e2dc47a0..cb5b17caed2 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -3316,7 +3316,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). */ @@ -3451,10 +3451,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) 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/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index 2edd4ddf853..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), @@ -388,7 +387,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 +479,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<DepsgraphNodeBuilder *>(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 e8cf5c99c37..ffddb196ae4 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,11 +569,38 @@ 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) @@ -2805,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. */ 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/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); } 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 <stdio.h> + /***************************** 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 215166a6158..82cc499c729 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" @@ -799,6 +800,7 @@ static void *view3d_main_region_duplicate(void *poin) static void view3d_main_region_listener(const wmRegionListenerParams *params) { + wmWindow *window = params->window; ScrArea *area = params->area; ARegion *region = params->region; wmNotifier *wmn = params->notifier; @@ -1018,11 +1020,17 @@ static void view3d_main_region_listener(const wmRegionListenerParams *params) 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(window); + Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer); + if (depsgraph) { + ED_render_view3d_update(depsgraph, window, area, true); + } + } ED_region_tag_redraw(region); WM_gizmomap_tag_refresh(gzmap); } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 9ca1c655066..26824216337 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -530,7 +530,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 diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 67372675805..17f4713ff96 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -544,6 +544,7 @@ void wm_event_do_notifiers(bContext *C) LISTBASE_FOREACH (ARegion *, region, &screen->regionbase) { wmRegionListenerParams region_params = { + .window = win, .area = NULL, .region = region, .scene = scene, @@ -562,6 +563,7 @@ void wm_event_do_notifiers(bContext *C) ED_area_do_listen(&area_params); LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { wmRegionListenerParams region_params = { + .window = win, .area = area, .region = region, .scene = scene, |