From dd2d84b342d49d2eee663017e6a892116fad4bd9 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Thu, 23 Jan 2025 05:26:10 +0000 Subject: [PATCH] Remove `ViewVisibility` from UI nodes (#17405) # Objective The UI can only target a single view and doesn't support `RenderLayers`, so there doesn't seem to be any need for UI nodes to require `ViewVisibility` and `VisibilityClass`. Fixes #17400 ## Solution Remove the `ViewVisibility` and `VisibilityClass` component requires from `Node` and change the visibility queries to only query for `InheritedVisibility`. ## Testing ```cargo run --example many_buttons --release --features "trace_tracy"``` Yellow is this PR, red is main. `bevy_render::view::visibility::reset_view_visibility` reset-view `bevy_render::view::visibility::check_visibility` view_visibility --- crates/bevy_ui/src/focus.rs | 14 +++++----- crates/bevy_ui/src/picking_backend.rs | 6 ++--- crates/bevy_ui/src/render/box_shadow.rs | 7 +++-- crates/bevy_ui/src/render/debug_overlay.rs | 4 +-- crates/bevy_ui/src/render/mod.rs | 26 +++++++++---------- .../src/render/ui_material_pipeline.rs | 8 +++--- .../src/render/ui_texture_slice_pipeline.rs | 6 ++--- crates/bevy_ui/src/ui_node.rs | 4 +-- 8 files changed, 37 insertions(+), 38 deletions(-) diff --git a/crates/bevy_ui/src/focus.rs b/crates/bevy_ui/src/focus.rs index 4038936539c76..e207182807de3 100644 --- a/crates/bevy_ui/src/focus.rs +++ b/crates/bevy_ui/src/focus.rs @@ -12,7 +12,7 @@ use bevy_ecs::{ use bevy_input::{mouse::MouseButton, touch::Touches, ButtonInput}; use bevy_math::{Rect, Vec2}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::{camera::NormalizedRenderTarget, prelude::Camera, view::ViewVisibility}; +use bevy_render::{camera::NormalizedRenderTarget, prelude::Camera, view::InheritedVisibility}; use bevy_transform::components::GlobalTransform; use bevy_utils::HashMap; use bevy_window::{PrimaryWindow, Window}; @@ -28,9 +28,9 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; /// /// Updated in [`ui_focus_system`]. /// -/// If a UI node has both [`Interaction`] and [`ViewVisibility`] components, +/// If a UI node has both [`Interaction`] and [`InheritedVisibility`] components, /// [`Interaction`] will always be [`Interaction::None`] -/// when [`ViewVisibility::get()`] is false. +/// when [`InheritedVisibility::get()`] is false. /// This ensures that hidden UI nodes are not interactable, /// and do not end up stuck in an active state if hidden at the wrong time. /// @@ -140,13 +140,13 @@ pub struct NodeQuery { relative_cursor_position: Option<&'static mut RelativeCursorPosition>, focus_policy: Option<&'static FocusPolicy>, calculated_clip: Option<&'static CalculatedClip>, - view_visibility: Option<&'static ViewVisibility>, + inherited_visibility: Option<&'static InheritedVisibility>, target_camera: Option<&'static UiTargetCamera>, } /// The system that sets Interaction for all UI elements based on the mouse cursor activity /// -/// Entities with a hidden [`ViewVisibility`] are always treated as released. +/// Entities with a hidden [`InheritedVisibility`] are always treated as released. pub fn ui_focus_system( mut state: Local, camera_query: Query<(Entity, &Camera)>, @@ -227,9 +227,9 @@ pub fn ui_focus_system( return None; }; - let view_visibility = node.view_visibility?; + let inherited_visibility = node.inherited_visibility?; // Nodes that are not rendered should not be interactable - if !view_visibility.get() { + if !inherited_visibility.get() { // Reset their interaction to None to avoid strange stuck state if let Some(mut interaction) = node.interaction { // We cannot simply set the interaction to None, as that will trigger change detection repeatedly diff --git a/crates/bevy_ui/src/picking_backend.rs b/crates/bevy_ui/src/picking_backend.rs index 209995fcc866e..2ca0c110e4256 100644 --- a/crates/bevy_ui/src/picking_backend.rs +++ b/crates/bevy_ui/src/picking_backend.rs @@ -50,7 +50,7 @@ pub struct NodeQuery { global_transform: &'static GlobalTransform, pickable: Option<&'static Pickable>, calculated_clip: Option<&'static CalculatedClip>, - view_visibility: Option<&'static ViewVisibility>, + inherited_visibility: Option<&'static InheritedVisibility>, target_camera: Option<&'static UiTargetCamera>, } @@ -124,8 +124,8 @@ pub fn ui_picking( // Nodes that are not rendered should not be interactable if node - .view_visibility - .map(|view_visibility| view_visibility.get()) + .inherited_visibility + .map(|inherited_visibility| inherited_visibility.get()) != Some(true) { continue; diff --git a/crates/bevy_ui/src/render/box_shadow.rs b/crates/bevy_ui/src/render/box_shadow.rs index 11cfcf2260a08..16f666835ba29 100644 --- a/crates/bevy_ui/src/render/box_shadow.rs +++ b/crates/bevy_ui/src/render/box_shadow.rs @@ -243,7 +243,7 @@ pub fn extract_shadows( Entity, &ComputedNode, &GlobalTransform, - &ViewVisibility, + &InheritedVisibility, &BoxShadow, Option<&CalculatedClip>, Option<&UiTargetCamera>, @@ -253,8 +253,7 @@ pub fn extract_shadows( ) { let default_camera_entity = default_ui_camera.get(); - for (entity, uinode, transform, view_visibility, box_shadow, clip, camera) in &box_shadow_query - { + for (entity, uinode, transform, visibility, box_shadow, clip, camera) in &box_shadow_query { let Some(camera_entity) = camera.map(UiTargetCamera::entity).or(default_camera_entity) else { continue; @@ -265,7 +264,7 @@ pub fn extract_shadows( }; // Skip if no visible shadows - if !view_visibility.get() || box_shadow.is_empty() || uinode.is_empty() { + if !visibility.get() || box_shadow.is_empty() || uinode.is_empty() { continue; } diff --git a/crates/bevy_ui/src/render/debug_overlay.rs b/crates/bevy_ui/src/render/debug_overlay.rs index 52d5f847fbfa1..ef07002890eda 100644 --- a/crates/bevy_ui/src/render/debug_overlay.rs +++ b/crates/bevy_ui/src/render/debug_overlay.rs @@ -14,7 +14,7 @@ use bevy_math::Rect; use bevy_math::Vec2; use bevy_render::sync_world::RenderEntity; use bevy_render::sync_world::TemporaryRenderEntity; -use bevy_render::view::ViewVisibility; +use bevy_render::view::InheritedVisibility; use bevy_render::Extract; use bevy_sprite::BorderRect; use bevy_transform::components::GlobalTransform; @@ -63,7 +63,7 @@ pub fn extract_debug_overlay( Query<( Entity, &ComputedNode, - &ViewVisibility, + &InheritedVisibility, Option<&CalculatedClip>, &GlobalTransform, Option<&UiTargetCamera>, diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 99927619719dc..bca1f2397df43 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -42,7 +42,7 @@ use bevy_render::{ render_phase::{PhaseItem, PhaseItemExtraIndex}, sync_world::{RenderEntity, TemporaryRenderEntity}, texture::GpuImage, - view::ViewVisibility, + view::InheritedVisibility, ExtractSchedule, Render, }; use bevy_sprite::{BorderRect, SpriteAssetEvents}; @@ -285,7 +285,7 @@ pub fn extract_uinode_background_colors( Entity, &ComputedNode, &GlobalTransform, - &ViewVisibility, + &InheritedVisibility, Option<&CalculatedClip>, Option<&UiTargetCamera>, &BackgroundColor, @@ -294,7 +294,7 @@ pub fn extract_uinode_background_colors( mapping: Extract>, ) { let default_camera_entity = default_ui_camera.get(); - for (entity, uinode, transform, view_visibility, clip, camera, background_color) in + for (entity, uinode, transform, inherited_visibility, clip, camera, background_color) in &uinode_query { let Some(camera_entity) = camera.map(UiTargetCamera::entity).or(default_camera_entity) @@ -307,7 +307,7 @@ pub fn extract_uinode_background_colors( }; // Skip invisible backgrounds - if !view_visibility.get() || background_color.0.is_fully_transparent() { + if !inherited_visibility.get() || background_color.0.is_fully_transparent() { continue; } @@ -348,7 +348,7 @@ pub fn extract_uinode_images( Entity, &ComputedNode, &GlobalTransform, - &ViewVisibility, + &InheritedVisibility, Option<&CalculatedClip>, Option<&UiTargetCamera>, &ImageNode, @@ -357,7 +357,7 @@ pub fn extract_uinode_images( mapping: Extract>, ) { let default_camera_entity = default_ui_camera.get(); - for (entity, uinode, transform, view_visibility, clip, camera, image) in &uinode_query { + for (entity, uinode, transform, inherited_visibility, clip, camera, image) in &uinode_query { let Some(camera_entity) = camera.map(UiTargetCamera::entity).or(default_camera_entity) else { continue; @@ -368,7 +368,7 @@ pub fn extract_uinode_images( }; // Skip invisible images - if !view_visibility.get() + if !inherited_visibility.get() || image.color.is_fully_transparent() || image.image.id() == TRANSPARENT_IMAGE_HANDLE.id() || image.image_mode.uses_slices() @@ -439,7 +439,7 @@ pub fn extract_uinode_borders( &Node, &ComputedNode, &GlobalTransform, - &ViewVisibility, + &InheritedVisibility, Option<&CalculatedClip>, Option<&UiTargetCamera>, AnyOf<(&BorderColor, &Outline)>, @@ -454,7 +454,7 @@ pub fn extract_uinode_borders( node, computed_node, global_transform, - view_visibility, + inherited_visibility, maybe_clip, maybe_camera, (maybe_border_color, maybe_outline), @@ -472,7 +472,7 @@ pub fn extract_uinode_borders( }; // Skip invisible borders and removed nodes - if !view_visibility.get() || node.display == Display::None { + if !inherited_visibility.get() || node.display == Display::None { continue; } @@ -678,7 +678,7 @@ pub fn extract_text_sections( Entity, &ComputedNode, &GlobalTransform, - &ViewVisibility, + &InheritedVisibility, Option<&CalculatedClip>, Option<&UiTargetCamera>, &ComputedTextBlock, @@ -696,7 +696,7 @@ pub fn extract_text_sections( entity, uinode, global_transform, - view_visibility, + inherited_visibility, clip, camera, computed_block, @@ -708,7 +708,7 @@ pub fn extract_text_sections( }; // Skip if not visible or if size is set to zero (e.g. when a parent is set to `Display::None`) - if !view_visibility.get() || uinode.is_empty() { + if !inherited_visibility.get() || uinode.is_empty() { continue; } diff --git a/crates/bevy_ui/src/render/ui_material_pipeline.rs b/crates/bevy_ui/src/render/ui_material_pipeline.rs index 6cc104392e979..1557dad905bf4 100644 --- a/crates/bevy_ui/src/render/ui_material_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_material_pipeline.rs @@ -369,7 +369,7 @@ pub fn extract_ui_material_nodes( &ComputedNode, &GlobalTransform, &MaterialNode, - &ViewVisibility, + &InheritedVisibility, Option<&CalculatedClip>, Option<&UiTargetCamera>, )>, @@ -379,7 +379,9 @@ pub fn extract_ui_material_nodes( // If there is only one camera, we use it as default let default_single_camera = default_ui_camera.get(); - for (entity, uinode, transform, handle, view_visibility, clip, camera) in uinode_query.iter() { + for (entity, uinode, transform, handle, inherited_visibility, clip, camera) in + uinode_query.iter() + { let Some(camera_entity) = camera.map(UiTargetCamera::entity).or(default_single_camera) else { continue; @@ -390,7 +392,7 @@ pub fn extract_ui_material_nodes( }; // skip invisible nodes - if !view_visibility.get() { + if !inherited_visibility.get() { continue; } diff --git a/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs b/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs index 6001dc8b7f6f3..ad4af7642b58d 100644 --- a/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs @@ -254,7 +254,7 @@ pub fn extract_ui_texture_slices( Entity, &ComputedNode, &GlobalTransform, - &ViewVisibility, + &InheritedVisibility, Option<&CalculatedClip>, Option<&UiTargetCamera>, &ImageNode, @@ -264,7 +264,7 @@ pub fn extract_ui_texture_slices( ) { let default_camera_entity = default_ui_camera.get(); - for (entity, uinode, transform, view_visibility, clip, camera, image) in &slicers_query { + for (entity, uinode, transform, inherited_visibility, clip, camera, image) in &slicers_query { let Some(camera_entity) = camera.map(UiTargetCamera::entity).or(default_camera_entity) else { continue; @@ -291,7 +291,7 @@ pub fn extract_ui_texture_slices( }; // Skip invisible images - if !view_visibility.get() + if !inherited_visibility.get() || image.color.is_fully_transparent() || image.image.id() == TRANSPARENT_IMAGE_HANDLE.id() { diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 1954b72ade374..1c764d8470f5f 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -6,7 +6,7 @@ use bevy_math::{vec4, Rect, Vec2, Vec4Swizzles}; use bevy_reflect::prelude::*; use bevy_render::{ camera::{Camera, RenderTarget}, - view::{self, Visibility, VisibilityClass}, + view::Visibility, }; use bevy_sprite::BorderRect; use bevy_transform::components::Transform; @@ -329,11 +329,9 @@ impl From for ScrollPosition { ScrollPosition, Transform, Visibility, - VisibilityClass, ZIndex )] #[reflect(Component, Default, PartialEq, Debug)] -#[component(on_add = view::add_visibility_class::)] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize),