Skip to content

Commit

Permalink
Remove ViewVisibility from UI nodes (#17405)
Browse files Browse the repository at this point in the history
# 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`
<img width="531" alt="reset-view" src="https://github.com/user-attachments/assets/a44b215d-96bf-43ec-8669-31530ff98eae" />

`bevy_render::view::visibility::check_visibility`
<img width="445" alt="view_visibility" src="https://github.com/user-attachments/assets/fa111757-da91-434d-88e4-80bdfa29374f" />
  • Loading branch information
ickshonpe authored Jan 23, 2025
1 parent 68c19de commit dd2d84b
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 38 deletions.
14 changes: 7 additions & 7 deletions crates/bevy_ui/src/focus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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.
///
Expand Down Expand Up @@ -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<State>,
camera_query: Query<(Entity, &Camera)>,
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_ui/src/picking_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
}

Expand Down Expand Up @@ -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;
Expand Down
7 changes: 3 additions & 4 deletions crates/bevy_ui/src/render/box_shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ pub fn extract_shadows(
Entity,
&ComputedNode,
&GlobalTransform,
&ViewVisibility,
&InheritedVisibility,
&BoxShadow,
Option<&CalculatedClip>,
Option<&UiTargetCamera>,
Expand All @@ -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;
Expand All @@ -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;
}

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ui/src/render/debug_overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -63,7 +63,7 @@ pub fn extract_debug_overlay(
Query<(
Entity,
&ComputedNode,
&ViewVisibility,
&InheritedVisibility,
Option<&CalculatedClip>,
&GlobalTransform,
Option<&UiTargetCamera>,
Expand Down
26 changes: 13 additions & 13 deletions crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -285,7 +285,7 @@ pub fn extract_uinode_background_colors(
Entity,
&ComputedNode,
&GlobalTransform,
&ViewVisibility,
&InheritedVisibility,
Option<&CalculatedClip>,
Option<&UiTargetCamera>,
&BackgroundColor,
Expand All @@ -294,7 +294,7 @@ pub fn extract_uinode_background_colors(
mapping: Extract<Query<RenderEntity>>,
) {
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)
Expand All @@ -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;
}

Expand Down Expand Up @@ -348,7 +348,7 @@ pub fn extract_uinode_images(
Entity,
&ComputedNode,
&GlobalTransform,
&ViewVisibility,
&InheritedVisibility,
Option<&CalculatedClip>,
Option<&UiTargetCamera>,
&ImageNode,
Expand All @@ -357,7 +357,7 @@ pub fn extract_uinode_images(
mapping: Extract<Query<RenderEntity>>,
) {
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;
Expand All @@ -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()
Expand Down Expand Up @@ -439,7 +439,7 @@ pub fn extract_uinode_borders(
&Node,
&ComputedNode,
&GlobalTransform,
&ViewVisibility,
&InheritedVisibility,
Option<&CalculatedClip>,
Option<&UiTargetCamera>,
AnyOf<(&BorderColor, &Outline)>,
Expand All @@ -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),
Expand All @@ -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;
}

Expand Down Expand Up @@ -678,7 +678,7 @@ pub fn extract_text_sections(
Entity,
&ComputedNode,
&GlobalTransform,
&ViewVisibility,
&InheritedVisibility,
Option<&CalculatedClip>,
Option<&UiTargetCamera>,
&ComputedTextBlock,
Expand All @@ -696,7 +696,7 @@ pub fn extract_text_sections(
entity,
uinode,
global_transform,
view_visibility,
inherited_visibility,
clip,
camera,
computed_block,
Expand All @@ -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;
}

Expand Down
8 changes: 5 additions & 3 deletions crates/bevy_ui/src/render/ui_material_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ pub fn extract_ui_material_nodes<M: UiMaterial>(
&ComputedNode,
&GlobalTransform,
&MaterialNode<M>,
&ViewVisibility,
&InheritedVisibility,
Option<&CalculatedClip>,
Option<&UiTargetCamera>,
)>,
Expand All @@ -379,7 +379,9 @@ pub fn extract_ui_material_nodes<M: UiMaterial>(
// 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;
Expand All @@ -390,7 +392,7 @@ pub fn extract_ui_material_nodes<M: UiMaterial>(
};

// skip invisible nodes
if !view_visibility.get() {
if !inherited_visibility.get() {
continue;
}

Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ pub fn extract_ui_texture_slices(
Entity,
&ComputedNode,
&GlobalTransform,
&ViewVisibility,
&InheritedVisibility,
Option<&CalculatedClip>,
Option<&UiTargetCamera>,
&ImageNode,
Expand All @@ -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;
Expand All @@ -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()
{
Expand Down
4 changes: 1 addition & 3 deletions crates/bevy_ui/src/ui_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -329,11 +329,9 @@ impl From<Vec2> for ScrollPosition {
ScrollPosition,
Transform,
Visibility,
VisibilityClass,
ZIndex
)]
#[reflect(Component, Default, PartialEq, Debug)]
#[component(on_add = view::add_visibility_class::<Node>)]
#[cfg_attr(
feature = "serialize",
derive(serde::Serialize, serde::Deserialize),
Expand Down

0 comments on commit dd2d84b

Please sign in to comment.