diff options
-rw-r--r-- | source/blender/depsgraph/DEG_depsgraph_query.h | 3 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph.cc | 4 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph.h | 3 | ||||
-rw-r--r-- | source/blender/depsgraph/intern/depsgraph_query.cc | 6 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 78 | ||||
-rw-r--r-- | source/blender/render/intern/source/external_engine.c | 2 |
6 files changed, 60 insertions, 36 deletions
diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h index b9cbd75ce1e..48a62a69f30 100644 --- a/source/blender/depsgraph/DEG_depsgraph_query.h +++ b/source/blender/depsgraph/DEG_depsgraph_query.h @@ -67,6 +67,9 @@ float DEG_get_ctime(const Depsgraph *graph); bool DEG_id_type_updated(const struct Depsgraph *depsgraph, short id_type); bool DEG_id_type_any_updated(const struct Depsgraph *depsgraph); +/* Check if given ID type is present in the depsgraph */ +bool DEG_id_type_any_exists(const struct Depsgraph *depsgraph, short id_type); + /* Get additional evaluation flags for the given ID. */ uint32_t DEG_get_eval_flags_for_id(const struct Depsgraph *graph, struct ID *id); diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc index 5d96bfad95e..d8a9b41206b 100644 --- a/source/blender/depsgraph/intern/depsgraph.cc +++ b/source/blender/depsgraph/intern/depsgraph.cc @@ -38,6 +38,7 @@ extern "C" { #include "BKE_scene.h" #include "BKE_global.h" +#include "BKE_idcode.h" } #include "DEG_depsgraph.h" @@ -81,6 +82,7 @@ Depsgraph::Depsgraph(Scene *scene, ViewLayer *view_layer, eEvaluationMode mode) entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags"); debug_flags = G.debug; memset(id_type_updated, 0, sizeof(id_type_updated)); + memset(id_type_exist, 0, sizeof(id_type_exist)); memset(physics_relations, 0, sizeof(physics_relations)); } @@ -130,6 +132,8 @@ IDNode *Depsgraph::add_id_node(ID *id, ID *id_cow_hint) * referencing to. */ BLI_ghash_insert(id_hash, id, id_node); id_nodes.push_back(id_node); + + id_type_exist[BKE_idcode_to_index(GS(id->name))] = 1; } return id_node; } diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h index 073ec99b3aa..f194a44346b 100644 --- a/source/blender/depsgraph/intern/depsgraph.h +++ b/source/blender/depsgraph/intern/depsgraph.h @@ -152,6 +152,9 @@ struct Depsgraph { /* Indicates which ID types were updated. */ char id_type_updated[MAX_LIBARRAY]; + /* Indicates type of IDs present in the depsgraph. */ + char id_type_exist[MAX_LIBARRAY]; + /* Quick-Access Temp Data ............. */ /* Nodes which have been tagged as "directly modified". */ diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc index 326d852b1e1..0345f294860 100644 --- a/source/blender/depsgraph/intern/depsgraph_query.cc +++ b/source/blender/depsgraph/intern/depsgraph_query.cc @@ -95,6 +95,12 @@ bool DEG_id_type_any_updated(const Depsgraph *graph) return false; } +bool DEG_id_type_any_exists(const Depsgraph *depsgraph, short id_type) +{ + const DEG::Depsgraph *deg_graph = reinterpret_cast<const DEG::Depsgraph *>(depsgraph); + return deg_graph->id_type_exist[BKE_idcode_to_index(id_type)] != 0; +} + uint32_t DEG_get_eval_flags_for_id(const Depsgraph *graph, ID *id) { if (graph == NULL) { diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 47d0e97d34b..8897d14c5fd 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -999,13 +999,10 @@ void DRW_cache_free_old_batches(Main *bmain) /* TODO(fclem): This is not optimal since it iter over all dupli instances. * In this case only the source object should be tagged. */ - int iter_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | - DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_DUPLI; - - DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flags) { + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) { DRW_batch_cache_free_old(ob, ctime); } - DEG_OBJECT_ITER_END; + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END; } } } @@ -1366,7 +1363,9 @@ static void drw_engines_enable_basic(void) use_drw_engine(DRW_engine_viewport_basic_type.draw_engine); } -static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_type) +static void drw_engines_enable(ViewLayer *view_layer, + RenderEngineType *engine_type, + bool gpencil_engine_needed) { Object *obact = OBACT(view_layer); const enum eContextObjectMode mode = CTX_data_mode_enum_ex( @@ -1377,7 +1376,9 @@ static void drw_engines_enable(ViewLayer *view_layer, RenderEngineType *engine_t drw_engines_enable_from_engine(engine_type, drawtype, use_xray); /* grease pencil */ - use_drw_engine(&draw_engine_gpencil_type); + if (gpencil_engine_needed) { + use_drw_engine(&draw_engine_gpencil_type); + } if (DRW_state_draw_support()) { /* Draw paint modes first so that they are drawn below the wireframes. */ @@ -1414,6 +1415,16 @@ static void drw_engines_data_validate(void) GPU_viewport_engines_data_validate(DST.viewport, engine_handle_array); } +/* Fast check to see if gpencil drawing engine is needed. + * For slow exact check use `DRW_render_check_grease_pencil` */ +static bool drw_gpencil_engine_needed(Depsgraph *depsgraph, View3D *v3d) +{ + const bool exclude_gpencil_rendering = v3d ? (v3d->object_type_exclude_viewport & + (1 << OB_GPENCIL)) != 0 : + false; + return (!exclude_gpencil_rendering) || DEG_id_type_any_exists(depsgraph, ID_GD); +} + /* -------------------------------------------------------------------- */ /** \name View Update * \{ */ @@ -1428,6 +1439,8 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx) Scene *scene = update_ctx->scene; ViewLayer *view_layer = update_ctx->view_layer; + const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d); + /* Separate update for each stereo view. */ for (int view = 0; view < 2; view++) { GPUViewport *viewport = WM_draw_region_get_viewport(ar, view); @@ -1456,7 +1469,7 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx) .object_mode = OB_MODE_OBJECT, }; - drw_engines_enable(view_layer, engine_type); + drw_engines_enable(view_layer, engine_type, gpencil_engine_needed); for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { DrawEngineType *draw_engine = link->data; @@ -1541,8 +1554,17 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, drw_context_state_init(); drw_viewport_var_init(); + const int object_type_exclude_viewport = v3d->object_type_exclude_viewport; + /* Check if scene needs to perform the populate loop */ + const bool internal_engine = (engine_type->flag & RE_INTERNAL) != 0; + const bool draw_type_render = v3d->shading.type == OB_RENDER; + const bool overlays_on = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0; + const bool gpencil_engine_needed = drw_gpencil_engine_needed(depsgraph, v3d); + const bool do_populate_loop = internal_engine || overlays_on || !draw_type_render || + gpencil_engine_needed; + /* Get list of enabled engines */ - drw_engines_enable(view_layer, engine_type); + drw_engines_enable(view_layer, engine_type, gpencil_engine_needed); drw_engines_data_validate(); @@ -1565,15 +1587,8 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, drw_engines_world_update(scene); /* Only iterate over objects for internal engines or when overlays are enabled */ - const bool internal_engine = (engine_type->flag & RE_INTERNAL) != 0; - const bool draw_type_render = v3d->shading.type == OB_RENDER; - const bool overlays_on = (v3d->flag2 & V3D_HIDE_OVERLAYS) == 0; - if (internal_engine || overlays_on || !draw_type_render) { - const int object_type_exclude_viewport = v3d->object_type_exclude_viewport; - const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | - DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE | - DEG_ITER_OBJECT_FLAG_DUPLI; - DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flag) { + if (do_populate_loop) { + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) { if ((object_type_exclude_viewport & (1 << ob->type)) != 0) { continue; } @@ -1585,7 +1600,7 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph, drw_duplidata_load(DST.dupli_source); drw_engines_cache_populate(ob); } - DEG_OBJECT_ITER_END; + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END; } drw_duplidata_free(); @@ -1778,6 +1793,10 @@ void DRW_draw_render_loop_offscreen(struct Depsgraph *depsgraph, /* Helper to check if exit object type to render. */ bool DRW_render_check_grease_pencil(Depsgraph *depsgraph) { + if (!drw_gpencil_engine_needed(depsgraph, NULL)) { + return false; + } + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) { if (ob->type == OB_GPENCIL) { if (DRW_object_visibility_in_active_context(ob) & OB_VISIBLE_SELF) { @@ -2025,10 +2044,7 @@ void DRW_render_object_iter( const int object_type_exclude_viewport = draw_ctx->v3d ? draw_ctx->v3d->object_type_exclude_viewport : 0; - const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | - DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE | - DEG_ITER_OBJECT_FLAG_DUPLI; - DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flag) { + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) { if ((object_type_exclude_viewport & (1 << ob->type)) == 0) { DST.dupli_parent = data_.dupli_parent; DST.dupli_source = data_.dupli_object_current; @@ -2044,7 +2060,7 @@ void DRW_render_object_iter( } } } - DEG_OBJECT_ITER_END; + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END; drw_duplidata_free(); } @@ -2282,13 +2298,10 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, FOREACH_OBJECT_IN_MODE_END; } else { - const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | - DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE | - DEG_ITER_OBJECT_FLAG_DUPLI; const int object_type_exclude_select = (v3d->object_type_exclude_viewport | v3d->object_type_exclude_select); bool filter_exclude = false; - DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flag) { + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (depsgraph, ob) { if (v3d->localvd && ((v3d->local_view_uuid & ob->base_local_view_bits) == 0)) { continue; } @@ -2318,7 +2331,7 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph, drw_engines_cache_populate(ob); } } - DEG_OBJECT_ITER_END; + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END; } drw_duplidata_free(); @@ -2400,10 +2413,7 @@ static void drw_draw_depth_loop_imp(void) View3D *v3d = DST.draw_ctx.v3d; const int object_type_exclude_viewport = v3d->object_type_exclude_viewport; - const int iter_flag = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | - DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET | DEG_ITER_OBJECT_FLAG_VISIBLE | - DEG_ITER_OBJECT_FLAG_DUPLI; - DEG_OBJECT_ITER_BEGIN (DST.draw_ctx.depsgraph, ob, iter_flag) { + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN (DST.draw_ctx.depsgraph, ob) { if ((object_type_exclude_viewport & (1 << ob->type)) != 0) { continue; } @@ -2417,7 +2427,7 @@ static void drw_draw_depth_loop_imp(void) drw_duplidata_load(DST.dupli_source); drw_engines_cache_populate(ob); } - DEG_OBJECT_ITER_END; + DEG_OBJECT_ITER_FOR_RENDER_ENGINE_END; drw_duplidata_free(); drw_engines_cache_finish(); diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c index a5bf5adc243..a41f7bbe5fc 100644 --- a/source/blender/render/intern/source/external_engine.c +++ b/source/blender/render/intern/source/external_engine.c @@ -867,8 +867,6 @@ void RE_engine_free_blender_memory(RenderEngine *engine) /* Weak way to save memory, but not crash grease pencil. * * TODO(sergey): Find better solution for this. - * TODO(sergey): Try to find solution which does not involve looping over - * all the objects. */ if (DRW_render_check_grease_pencil(engine->depsgraph)) { return; |