From c0d6675c84b8043f1a90a5fbf7fb2ec7278f083a Mon Sep 17 00:00:00 2001 From: Miguel Pozo Date: Tue, 6 May 2025 16:09:12 +0200 Subject: [PATCH] Overlay: Skip passes not needed Avoid initializing passes (and requesting their shaders) unless they're actually needed. Reduces the number of compiled Overlay shaders at startup from 70 to 22. Improves startup times. Pull Request: https://projects.blender.org/blender/blender/pulls/138457 --- .../draw/engines/overlay/overlay_armature.hh | 2 +- .../overlay/overlay_attribute_viewer.hh | 23 +++++++++++++++---- .../draw/engines/overlay/overlay_curve.hh | 4 +++- .../draw/engines/overlay/overlay_fluid.hh | 19 +++++++++++++++ .../draw/engines/overlay/overlay_instance.cc | 10 ++++++++ .../draw/engines/overlay/overlay_lattice.hh | 2 +- .../draw/engines/overlay/overlay_mesh.hh | 2 +- .../draw/engines/overlay/overlay_outline.hh | 18 ++++++++++----- .../draw/engines/overlay/overlay_particle.hh | 2 +- .../draw/engines/overlay/overlay_prepass.hh | 23 +++++++++++++------ .../draw/engines/overlay/overlay_private.hh | 9 ++++++++ .../draw/engines/overlay/overlay_wireframe.hh | 20 ++++++++++++---- 12 files changed, 107 insertions(+), 27 deletions(-) diff --git a/source/blender/draw/engines/overlay/overlay_armature.hh b/source/blender/draw/engines/overlay/overlay_armature.hh index 27fdc0af4f6..0fc011fb3a9 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.hh +++ b/source/blender/draw/engines/overlay/overlay_armature.hh @@ -146,7 +146,7 @@ class Armatures : Overlay { void begin_sync(Resources &res, const State &state) final { - enabled_ = state.is_space_v3d() && state.show_bones(); + enabled_ = state.is_space_v3d() && state.show_bones() && state.has_armature; if (!enabled_) { return; diff --git a/source/blender/draw/engines/overlay/overlay_attribute_viewer.hh b/source/blender/draw/engines/overlay/overlay_attribute_viewer.hh index cd42e69754a..4139dafee3c 100644 --- a/source/blender/draw/engines/overlay/overlay_attribute_viewer.hh +++ b/source/blender/draw/engines/overlay/overlay_attribute_viewer.hh @@ -53,11 +53,24 @@ class AttributeViewer : Overlay { return ⊂ }; - mesh_sub_ = create_sub("mesh", res.shaders->attribute_viewer_mesh.get()); - pointcloud_sub_ = create_sub("pointcloud", res.shaders->attribute_viewer_pointcloud.get()); - curve_sub_ = create_sub("curve", res.shaders->attribute_viewer_curve.get()); - curves_sub_ = create_sub("curves", res.shaders->attribute_viewer_curves.get()); - instance_sub_ = create_sub("instance", res.shaders->uniform_color.get()); + mesh_sub_ = nullptr; + if (state.has_mesh) { + mesh_sub_ = create_sub("mesh", res.shaders->attribute_viewer_mesh.get()); + } + pointcloud_sub_ = nullptr; + if (state.has_ptcloud) { + pointcloud_sub_ = create_sub("pointcloud", res.shaders->attribute_viewer_pointcloud.get()); + } + curve_sub_ = nullptr; + curves_sub_ = nullptr; + if (state.has_curve) { + curve_sub_ = create_sub("curve", res.shaders->attribute_viewer_curve.get()); + curves_sub_ = create_sub("curves", res.shaders->attribute_viewer_curves.get()); + } + instance_sub_ = nullptr; + if (state.has_mesh || state.has_curve) { + instance_sub_ = create_sub("instance", res.shaders->uniform_color.get()); + } } void object_sync(Manager &manager, diff --git a/source/blender/draw/engines/overlay/overlay_curve.hh b/source/blender/draw/engines/overlay/overlay_curve.hh index ee088626907..93859ddd985 100644 --- a/source/blender/draw/engines/overlay/overlay_curve.hh +++ b/source/blender/draw/engines/overlay/overlay_curve.hh @@ -50,7 +50,9 @@ class Curves : Overlay { public: void begin_sync(Resources &res, const State &state) final { - enabled_ = state.is_space_v3d(); + enabled_ = + state.is_space_v3d() && state.has_curve && + ELEM(state.ctx_mode, CTX_MODE_EDIT_CURVE, CTX_MODE_EDIT_CURVES, CTX_MODE_EDIT_SURFACE); if (!enabled_) { return; diff --git a/source/blender/draw/engines/overlay/overlay_fluid.hh b/source/blender/draw/engines/overlay/overlay_fluid.hh index ab163ded714..3709e9251c4 100644 --- a/source/blender/draw/engines/overlay/overlay_fluid.hh +++ b/source/blender/draw/engines/overlay/overlay_fluid.hh @@ -36,11 +36,18 @@ class Fluids : Overlay { int dominant_axis = -1; + bool enabled_ = false; + public: Fluids(const SelectionType selection_type) : selection_type_(selection_type){}; void begin_sync(Resources &res, const State &state) final { + enabled_ = state.has_volume; + if (!enabled_) { + return; + } + /* Against design. Should not sync depending on view. */ float3 camera_direction = blender::draw::View::default_get().viewinv().z_axis(); dominant_axis = math::dominant_axis(camera_direction); @@ -81,6 +88,10 @@ class Fluids : Overlay { Resources &res, const State &state) final { + if (!enabled_) { + return; + } + Object *ob = ob_ref.object; /* Do not show for dupli objects as the fluid is baked for the original object. */ @@ -236,6 +247,10 @@ class Fluids : Overlay { void end_sync(Resources &res, const State & /*state*/) final { + if (!enabled_) { + return; + } + fluid_ps_.shader_set(res.shaders->extra_shape.get()); fluid_ps_.bind_ubo(OVERLAY_GLOBALS_SLOT, &res.globals_buf); fluid_ps_.bind_ubo(DRW_CLIPPING_UBO_SLOT, &res.clip_planes_buf); @@ -245,6 +260,10 @@ class Fluids : Overlay { void draw_line(Framebuffer &framebuffer, Manager &manager, View &view) final { + if (!enabled_) { + return; + } + GPU_framebuffer_bind(framebuffer); manager.submit(fluid_ps_, view); } diff --git a/source/blender/draw/engines/overlay/overlay_instance.cc b/source/blender/draw/engines/overlay/overlay_instance.cc index aaa7c687110..2b806e9d3ea 100644 --- a/source/blender/draw/engines/overlay/overlay_instance.cc +++ b/source/blender/draw/engines/overlay/overlay_instance.cc @@ -122,6 +122,16 @@ void Instance::init() ED_space_image_get_aspect(space_image, &state.image_aspect.x, &state.image_aspect.y); } + state.has_mesh = DEG_id_type_any_exists(state.depsgraph, ID_ME); + state.has_curve = DEG_id_type_any_exists(state.depsgraph, ID_CV) || + DEG_id_type_any_exists(state.depsgraph, ID_CU_LEGACY); + state.has_volume = DEG_id_type_any_exists(state.depsgraph, ID_VO); + state.has_gpencil = DEG_id_type_any_exists(state.depsgraph, ID_GP); + state.has_armature = DEG_id_type_any_exists(state.depsgraph, ID_AR); + state.has_particles = DEG_id_type_any_exists(state.depsgraph, ID_PA); + state.has_lattice = DEG_id_type_any_exists(state.depsgraph, ID_LT); + state.has_ptcloud = DEG_id_type_any_exists(state.depsgraph, ID_PT); + resources.update_theme_settings(ctx, state); resources.update_clip_planes(state); diff --git a/source/blender/draw/engines/overlay/overlay_lattice.hh b/source/blender/draw/engines/overlay/overlay_lattice.hh index c8c4810e6fe..272c3ff29ab 100644 --- a/source/blender/draw/engines/overlay/overlay_lattice.hh +++ b/source/blender/draw/engines/overlay/overlay_lattice.hh @@ -29,7 +29,7 @@ class Lattices : Overlay { public: void begin_sync(Resources &res, const State &state) final { - enabled_ = state.is_space_v3d(); + enabled_ = state.is_space_v3d() && state.has_lattice; if (!enabled_) { return; } diff --git a/source/blender/draw/engines/overlay/overlay_mesh.hh b/source/blender/draw/engines/overlay/overlay_mesh.hh index 12de9223d2f..f4925b25590 100644 --- a/source/blender/draw/engines/overlay/overlay_mesh.hh +++ b/source/blender/draw/engines/overlay/overlay_mesh.hh @@ -94,7 +94,7 @@ class Meshes : Overlay { public: void begin_sync(Resources &res, const State &state) final { - enabled_ = state.is_space_v3d(); + enabled_ = state.is_space_v3d() && state.has_mesh && state.ctx_mode == CTX_MODE_EDIT_MESH; if (!enabled_) { return; diff --git a/source/blender/draw/engines/overlay/overlay_outline.hh b/source/blender/draw/engines/overlay/overlay_outline.hh index d412a76ba39..564a6d1f9f0 100644 --- a/source/blender/draw/engines/overlay/overlay_outline.hh +++ b/source/blender/draw/engines/overlay/overlay_outline.hh @@ -69,37 +69,43 @@ class Outline : Overlay { pass.clear_color_depth_stencil(float4(0.0f), 1.0f, 0x0); pass.state_set(DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL, state.clipping_plane_count); - { + prepass_curves_ps_ = nullptr; + if (state.has_curve) { auto &sub = pass.sub("Curves"); sub.shader_set(res.shaders->outline_prepass_curves.get()); sub.push_constant("is_transform", is_transform); prepass_curves_ps_ = ⊂ } - { + prepass_pointcloud_ps_ = nullptr; + if (state.has_ptcloud) { auto &sub = pass.sub("PointCloud"); sub.shader_set(res.shaders->outline_prepass_pointcloud.get()); sub.push_constant("is_transform", is_transform); prepass_pointcloud_ps_ = ⊂ } - { + prepass_gpencil_ps_ = nullptr; + if (state.has_gpencil) { auto &sub = pass.sub("GreasePencil"); sub.shader_set(res.shaders->outline_prepass_gpencil.get()); sub.push_constant("is_transform", is_transform); prepass_gpencil_ps_ = ⊂ } - { + prepass_mesh_ps_ = nullptr; + if (state.has_mesh) { auto &sub = pass.sub("Mesh"); sub.shader_set(res.shaders->outline_prepass_mesh.get()); sub.push_constant("is_transform", is_transform); prepass_mesh_ps_ = ⊂ } - { + prepass_volume_ps_ = nullptr; + if (state.has_volume) { auto &sub = pass.sub("Volume"); sub.shader_set(res.shaders->outline_prepass_mesh.get()); sub.push_constant("is_transform", is_transform); prepass_volume_ps_ = ⊂ } - { + prepass_wire_ps_ = nullptr; + if (state.has_mesh) { auto &sub = pass.sub("Wire"); sub.shader_set(res.shaders->outline_prepass_wire.get()); sub.push_constant("is_transform", is_transform); diff --git a/source/blender/draw/engines/overlay/overlay_particle.hh b/source/blender/draw/engines/overlay/overlay_particle.hh index 0d061cd0ca9..1433db895ee 100644 --- a/source/blender/draw/engines/overlay/overlay_particle.hh +++ b/source/blender/draw/engines/overlay/overlay_particle.hh @@ -43,7 +43,7 @@ class Particles : Overlay { public: void begin_sync(Resources &res, const State &state) final { - enabled_ = state.is_space_v3d(); + enabled_ = state.is_space_v3d() && state.has_particles; if (!enabled_) { return; diff --git a/source/blender/draw/engines/overlay/overlay_prepass.hh b/source/blender/draw/engines/overlay/overlay_prepass.hh index 2b4af70e2cd..f15ac2e9135 100644 --- a/source/blender/draw/engines/overlay/overlay_prepass.hh +++ b/source/blender/draw/engines/overlay/overlay_prepass.hh @@ -78,8 +78,11 @@ class Prepass : Overlay { /* Not used. But release the data. */ ps_.init(); mesh_ps_ = nullptr; + mesh_flat_ps_ = nullptr; + hair_ps_ = nullptr; curves_ps_ = nullptr; pointcloud_ps_ = nullptr; + grease_pencil_ps_ = nullptr; return; } @@ -94,33 +97,39 @@ class Prepass : Overlay { ps_.state_set(DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | backface_cull_state, state.clipping_plane_count); res.select_bind(ps_); - { + mesh_ps_ = nullptr; + if (state.has_mesh || state.has_volume) { auto &sub = ps_.sub("Mesh"); sub.shader_set(res.is_selection() ? res.shaders->depth_mesh_conservative.get() : res.shaders->depth_mesh.get()); mesh_ps_ = ⊂ } - { + mesh_flat_ps_ = nullptr; + if (state.has_mesh) { auto &sub = ps_.sub("MeshFlat"); sub.shader_set(res.shaders->depth_mesh.get()); mesh_flat_ps_ = ⊂ } - { + hair_ps_ = nullptr; + if (state.has_particles) { auto &sub = ps_.sub("Hair"); sub.shader_set(res.shaders->depth_mesh.get()); hair_ps_ = ⊂ } - { + curves_ps_ = nullptr; + if (state.has_curve) { auto &sub = ps_.sub("Curves"); sub.shader_set(res.shaders->depth_curves.get()); curves_ps_ = ⊂ } - { + pointcloud_ps_ = nullptr; + if (state.has_ptcloud) { auto &sub = ps_.sub("PointCloud"); sub.shader_set(res.shaders->depth_pointcloud.get()); pointcloud_ps_ = ⊂ } - { + grease_pencil_ps_ = nullptr; + if (state.has_gpencil) { auto &sub = ps_.sub("GreasePencil"); sub.shader_set(res.shaders->depth_grease_pencil.get()); grease_pencil_ps_ = ⊂ @@ -155,7 +164,7 @@ class Prepass : Overlay { res.select_id(ob_ref); gpu::Batch *geom = DRW_cache_particles_get_hair(ob, psys, nullptr); - mesh_ps_->draw(geom, handle, select_id.get()); + hair_ps_->draw(geom, handle, select_id.get()); break; } break; diff --git a/source/blender/draw/engines/overlay/overlay_private.hh b/source/blender/draw/engines/overlay/overlay_private.hh index 343dee0584c..8a66184329a 100644 --- a/source/blender/draw/engines/overlay/overlay_private.hh +++ b/source/blender/draw/engines/overlay/overlay_private.hh @@ -169,6 +169,15 @@ struct State { float2 image_uv_aspect = float2(0.0f); float2 image_aspect = float2(0.0f); + bool has_mesh; + bool has_curve; + bool has_volume; + bool has_gpencil; + bool has_armature; + bool has_particles; + bool has_lattice; + bool has_ptcloud; + View::OffsetData offset_data_get() const { if (rv3d == nullptr) { diff --git a/source/blender/draw/engines/overlay/overlay_wireframe.hh b/source/blender/draw/engines/overlay/overlay_wireframe.hh index 50e15464494..a49a12b7416 100644 --- a/source/blender/draw/engines/overlay/overlay_wireframe.hh +++ b/source/blender/draw/engines/overlay/overlay_wireframe.hh @@ -100,10 +100,22 @@ class Wireframe : Overlay { auto coloring_pass = [&](ColoringPass &ps, bool use_color) { overlay::ShaderModule &sh = *res.shaders; - ps.mesh_ps_ = shader_pass(sh.wireframe_mesh.get(), "Mesh", use_color, wire_threshold); - ps.mesh_all_edges_ps_ = shader_pass(sh.wireframe_mesh.get(), "Wire", use_color, 1.0f); - ps.pointcloud_ps_ = shader_pass(sh.wireframe_points.get(), "PtCloud", use_color, 1.0f); - ps.curves_ps_ = shader_pass(sh.wireframe_curve.get(), "Curve", use_color, 1.0f); + ps.mesh_ps_ = nullptr; + if (state.has_mesh) { + ps.mesh_ps_ = shader_pass(sh.wireframe_mesh.get(), "Mesh", use_color, wire_threshold); + } + ps.mesh_all_edges_ps_ = nullptr; + if (state.has_mesh || state.has_volume) { + ps.mesh_all_edges_ps_ = shader_pass(sh.wireframe_mesh.get(), "Wire", use_color, 1.0f); + } + ps.pointcloud_ps_ = nullptr; + if (state.has_ptcloud || state.has_volume || state.has_mesh) { + ps.pointcloud_ps_ = shader_pass(sh.wireframe_points.get(), "PtCloud", use_color, 1.0f); + } + ps.curves_ps_ = nullptr; + if (state.has_curve) { + ps.curves_ps_ = shader_pass(sh.wireframe_curve.get(), "Curve", use_color, 1.0f); + } }; coloring_pass(non_colored, false);