Skip to content

Commit

Permalink
Squash pr bevyengine#4402
Browse files Browse the repository at this point in the history
Setup infrastructure for render app owns extract

Commit 'progress'

Finish API

Cleverly avoid needing the param to be 'static

This same trick can't work for `StaticSystemParam` fwiw
This is because `StaticSystemParam`'s item needs to exactly
reference the original param, whereas this just stores it

Migrate to the new pattern

Remove `spawn_and_forget`

It's unused, and was only ever needed for the weird extract logic

Fix clippy errors

Remove the trick because it's actually stupid

Add some docs

Fixup docs
  • Loading branch information
DJMcNab authored and TethysSvensson committed Apr 5, 2022
1 parent 5eebde7 commit a74211c
Show file tree
Hide file tree
Showing 24 changed files with 308 additions and 193 deletions.
22 changes: 12 additions & 10 deletions crates/bevy_core_pipeline/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ use bevy_render::{
renderer::RenderDevice,
texture::TextureCache,
view::{ExtractedView, Msaa, ViewDepthTexture},
RenderApp, RenderStage, RenderWorld,
Extract, RenderApp, RenderStage,
};

/// When used as a resource, sets the color that is used to clear the screen between frames.
Expand Down Expand Up @@ -348,34 +348,36 @@ impl CachedRenderPipelinePhaseItem for Transparent3d {
}

pub fn extract_clear_color(
clear_color: Res<ClearColor>,
clear_colors: Res<RenderTargetClearColors>,
mut render_world: ResMut<RenderWorld>,
mut clear_color: Extract<Res<ClearColor>>,
mut clear_colors: Extract<Res<RenderTargetClearColors>>,
mut commands: Commands,
) {
let clear_color = clear_color.value();
// If the clear color has changed
if clear_color.is_changed() {
// Update the clear color resource in the render world
render_world.insert_resource(clear_color.clone());
commands.insert_resource(clear_color.clone());
}

let clear_colors = clear_colors.value();
// If the clear color has changed
if clear_colors.is_changed() {
// Update the clear color resource in the render world
render_world.insert_resource(clear_colors.clone());
commands.insert_resource(clear_colors.clone());
}
}

pub fn extract_core_pipeline_camera_phases(
mut commands: Commands,
active_2d: Res<ActiveCamera<Camera2d>>,
active_3d: Res<ActiveCamera<Camera3d>>,
mut active_2d: Extract<Res<ActiveCamera<Camera2d>>>,
mut active_3d: Extract<Res<ActiveCamera<Camera3d>>>,
) {
if let Some(entity) = active_2d.get() {
if let Some(entity) = active_2d.value().get() {
commands
.get_or_spawn(entity)
.insert(RenderPhase::<Transparent2d>::default());
}
if let Some(entity) = active_3d.get() {
if let Some(entity) = active_3d.value().get() {
commands.get_or_spawn(entity).insert_bundle((
RenderPhase::<Opaque3d>::default(),
RenderPhase::<AlphaMask3d>::default(),
Expand Down
4 changes: 3 additions & 1 deletion crates/bevy_ecs/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Event handling types.

use crate::system::{Local, Res, ResMut, SystemParam};
use crate::system::{Local, ReadOnlySystemParamFetch, Res, ResMut, SystemParam};
use crate::{self as bevy_ecs, system::Resource};
use bevy_utils::tracing::trace;
use std::{
Expand Down Expand Up @@ -164,6 +164,8 @@ pub struct EventReader<'w, 's, T: Resource> {
events: Res<'w, Events<T>>,
}

unsafe impl<A, T: Resource> ReadOnlySystemParamFetch for EventReaderState<A, T> {}

/// Sends events of type `T`.
#[derive(SystemParam)]
pub struct EventWriter<'w, 's, T: Resource> {
Expand Down
6 changes: 0 additions & 6 deletions crates/bevy_ecs/src/system/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,6 @@ impl<'w, 's> Commands<'w, 's> {
}
}

/// Spawns a [`Bundle`] without pre-allocating an [`Entity`]. The [`Entity`] will be allocated
/// when this [`Command`] is applied.
pub fn spawn_and_forget(&mut self, bundle: impl Bundle) {
self.queue.push(Spawn { bundle });
}

/// Creates a new entity with the components contained in `bundle`.
///
/// This returns an [`EntityCommands`] builder, which enables inserting more components and
Expand Down
56 changes: 35 additions & 21 deletions crates/bevy_pbr/src/render/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ use bevy_render::{
view::{
ExtractedView, ViewUniform, ViewUniformOffset, ViewUniforms, Visibility, VisibleEntities,
},
Extract,
};
use bevy_transform::components::GlobalTransform;
use bevy_utils::{
Expand Down Expand Up @@ -331,8 +332,11 @@ pub struct ExtractedClustersPointLights {
data: Vec<VisiblePointLights>,
}

pub fn extract_clusters(mut commands: Commands, views: Query<(Entity, &Clusters), With<Camera>>) {
for (entity, clusters) in views.iter() {
pub fn extract_clusters(
mut commands: Commands,
mut views: Extract<Query<(Entity, &Clusters), With<Camera>>>,
) {
for (entity, clusters) in views.value().iter() {
commands.get_or_spawn(entity).insert_bundle((
ExtractedClustersPointLights {
data: clusters.lights.clone(),
Expand All @@ -348,20 +352,25 @@ pub fn extract_clusters(mut commands: Commands, views: Query<(Entity, &Clusters)

pub fn extract_lights(
mut commands: Commands,
ambient_light: Res<AmbientLight>,
point_light_shadow_map: Res<PointLightShadowMap>,
directional_light_shadow_map: Res<DirectionalLightShadowMap>,
global_point_lights: Res<GlobalVisiblePointLights>,
mut ambient_light: Extract<Res<AmbientLight>>,
mut point_light_shadow_map: Extract<Res<PointLightShadowMap>>,
mut directional_light_shadow_map: Extract<Res<DirectionalLightShadowMap>>,
mut global_point_lights: Extract<Res<GlobalVisiblePointLights>>,
// visible_point_lights: Query<&VisiblePointLights>,
mut point_lights: Query<(&PointLight, &mut CubemapVisibleEntities, &GlobalTransform)>,
mut directional_lights: Query<(
Entity,
&DirectionalLight,
&mut VisibleEntities,
&GlobalTransform,
&Visibility,
)>,
mut point_lights: Extract<Query<(&PointLight, &CubemapVisibleEntities, &GlobalTransform)>>,
mut directional_lights: Extract<
Query<(
Entity,
&DirectionalLight,
&VisibleEntities,
&GlobalTransform,
&Visibility,
)>,
>,
) {
let ambient_light = ambient_light.value();
let point_light_shadow_map = point_light_shadow_map.value();
let directional_light_shadow_map = directional_light_shadow_map.value();
commands.insert_resource(ExtractedAmbientLight {
color: ambient_light.color,
brightness: ambient_light.brightness,
Expand All @@ -379,11 +388,15 @@ pub fn extract_lights(
// https://catlikecoding.com/unity/tutorials/custom-srp/point-and-spot-shadows/
let point_light_texel_size = 2.0 / point_light_shadow_map.size as f32;

for entity in global_point_lights.iter().copied() {
if let Ok((point_light, cubemap_visible_entities, transform)) = point_lights.get_mut(entity)
{
let render_cubemap_visible_entities =
std::mem::take(cubemap_visible_entities.into_inner());
let point_lights = point_lights.value();
for entity in global_point_lights.value().iter().copied() {
if let Ok((point_light, cubemap_visible_entities, transform)) = point_lights.get(entity) {
// PERF: Ideally, this would avoid creating new allocations each frame.
// The nicest way to do that would be to get last frame's render_cubemap_visible_entities,
// and clone into that buffer.
// TODO: Evaluate whether moving the buffers into a resource at the end of frame
// is more performant.
let render_cubemap_visible_entities = cubemap_visible_entities.clone();
commands.get_or_spawn(entity).insert_bundle((
ExtractedPointLight {
color: point_light.color,
Expand All @@ -407,7 +420,7 @@ pub fn extract_lights(
}

for (entity, directional_light, visible_entities, transform, visibility) in
directional_lights.iter_mut()
directional_lights.value().iter()
{
if !visibility.is_visible {
continue;
Expand All @@ -425,7 +438,8 @@ pub fn extract_lights(
);
let directional_light_texel_size =
largest_dimension / directional_light_shadow_map.size as f32;
let render_visible_entities = std::mem::take(visible_entities.into_inner());
// See above
let render_visible_entities = visible_entities.clone();
commands.get_or_spawn(entity).insert_bundle((
ExtractedDirectionalLight {
color: directional_light.color,
Expand Down
60 changes: 35 additions & 25 deletions crates/bevy_pbr/src/render/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use bevy_render::{
renderer::{RenderDevice, RenderQueue},
texture::{BevyDefault, GpuImage, Image, TextureFormatPixelInfo},
view::{ComputedVisibility, ViewUniform, ViewUniformOffset, ViewUniforms},
RenderApp, RenderStage,
Extract, RenderApp, RenderStage,
};
use bevy_transform::components::GlobalTransform;
use smallvec::SmallVec;
Expand Down Expand Up @@ -97,29 +97,35 @@ pub fn extract_meshes(
mut commands: Commands,
mut previous_caster_len: Local<usize>,
mut previous_not_caster_len: Local<usize>,
caster_query: Query<
(
Entity,
&ComputedVisibility,
&GlobalTransform,
&Handle<Mesh>,
Option<&NotShadowReceiver>,
),
Without<NotShadowCaster>,
mut caster_query: Extract<
Query<
(
Entity,
&ComputedVisibility,
&GlobalTransform,
&Handle<Mesh>,
Option<&NotShadowReceiver>,
),
Without<NotShadowCaster>,
>,
>,
not_caster_query: Query<
(
Entity,
&ComputedVisibility,
&GlobalTransform,
&Handle<Mesh>,
Option<&NotShadowReceiver>,
),
With<NotShadowCaster>,
mut not_caster_query: Extract<
Query<
(
Entity,
&ComputedVisibility,
&GlobalTransform,
&Handle<Mesh>,
Option<&NotShadowReceiver>,
),
With<NotShadowCaster>,
>,
>,
) {
let mut caster_values = Vec::with_capacity(*previous_caster_len);
for (entity, computed_visibility, transform, handle, not_receiver) in caster_query.iter() {
for (entity, computed_visibility, transform, handle, not_receiver) in
caster_query.value().iter()
{
if !computed_visibility.is_visible {
continue;
}
Expand All @@ -144,7 +150,9 @@ pub fn extract_meshes(
commands.insert_or_spawn_batch(caster_values);

let mut not_caster_values = Vec::with_capacity(*previous_not_caster_len);
for (entity, computed_visibility, transform, mesh, not_receiver) in not_caster_query.iter() {
for (entity, computed_visibility, transform, mesh, not_receiver) in
not_caster_query.value().iter()
{
if !computed_visibility.is_visible {
continue;
}
Expand Down Expand Up @@ -216,18 +224,20 @@ impl SkinnedMeshJoints {
}

pub fn extract_skinned_meshes(
query: Query<(Entity, &ComputedVisibility, &SkinnedMesh)>,
inverse_bindposes: Res<Assets<SkinnedMeshInverseBindposes>>,
joint_query: Query<&GlobalTransform>,
mut query: Extract<Query<(Entity, &ComputedVisibility, &SkinnedMesh)>>,
mut inverse_bindposes: Extract<Res<Assets<SkinnedMeshInverseBindposes>>>,
mut joint_query: Extract<Query<&GlobalTransform>>,
mut commands: Commands,
mut previous_len: Local<usize>,
mut previous_joint_len: Local<usize>,
) {
let inverse_bindposes = inverse_bindposes.value();
let mut values = Vec::with_capacity(*previous_len);
let mut joints = Vec::with_capacity(*previous_joint_len);
let mut last_start = 0;

for (entity, computed_visibility, skin) in query.iter() {
let joint_query = joint_query.value();
for (entity, computed_visibility, skin) in query.value().iter() {
if !computed_visibility.is_visible {
continue;
}
Expand Down
11 changes: 8 additions & 3 deletions crates/bevy_pbr/src/wireframe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use bevy_asset::{load_internal_asset, Handle, HandleUntyped};
use bevy_core_pipeline::Opaque3d;
use bevy_ecs::{prelude::*, reflect::ReflectComponent};
use bevy_reflect::{Reflect, TypeUuid};
use bevy_render::Extract;
use bevy_render::{
mesh::{Mesh, MeshVertexBufferLayout},
render_asset::RenderAssets,
Expand Down Expand Up @@ -47,14 +48,18 @@ impl Plugin for WireframePlugin {
}
}

fn extract_wireframe_config(mut commands: Commands, wireframe_config: Res<WireframeConfig>) {
fn extract_wireframe_config(
mut commands: Commands,
mut wireframe_config: Extract<Res<WireframeConfig>>,
) {
let wireframe_config = wireframe_config.value();
if wireframe_config.is_added() || wireframe_config.is_changed() {
commands.insert_resource(wireframe_config.into_inner().clone());
}
}

fn extract_wireframes(mut commands: Commands, query: Query<Entity, With<Wireframe>>) {
for entity in query.iter() {
fn extract_wireframes(mut commands: Commands, mut query: Extract<Query<Entity, With<Wireframe>>>) {
for entity in query.value().iter() {
commands.get_or_spawn(entity).insert(Wireframe);
}
}
Expand Down
20 changes: 12 additions & 8 deletions crates/bevy_render/src/camera/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
render_asset::RenderAssets,
render_resource::TextureView,
view::{ExtractedView, ExtractedWindows, VisibleEntities},
RenderApp, RenderStage,
Extract, RenderApp, RenderStage,
};
use bevy_app::{App, CoreStage, Plugin, StartupStage};
use bevy_asset::{AssetEvent, Assets, Handle};
Expand Down Expand Up @@ -288,18 +288,22 @@ pub struct ExtractedCamera {

pub fn extract_cameras<M: Component + Default>(
mut commands: Commands,
windows: Res<Windows>,
images: Res<Assets<Image>>,
active_camera: Res<ActiveCamera<M>>,
query: Query<(&Camera, &GlobalTransform, &VisibleEntities), With<M>>,
mut windows: Extract<Res<Windows>>,
mut images: Extract<Res<Assets<Image>>>,
mut active_camera: Extract<Res<ActiveCamera<M>>>,
mut query: Extract<Query<(&Camera, &GlobalTransform, &VisibleEntities), With<M>>>,
) {
let active_camera = active_camera.value();
if let Some(entity) = active_camera.get() {
if let Ok((camera, transform, visible_entities)) = query.get(entity) {
if let Some(size) = camera.target.get_physical_size(&windows, &images) {
if let Ok((camera, transform, visible_entities)) = query.value().get(entity) {
if let Some(size) = camera
.target
.get_physical_size(&windows.value(), &images.value())
{
commands.get_or_spawn(entity).insert_bundle((
ExtractedCamera {
target: camera.target.clone(),
physical_size: camera.target.get_physical_size(&windows, &images),
physical_size: Some(size),
},
ExtractedView {
projection: camera.projection_matrix,
Expand Down
Loading

0 comments on commit a74211c

Please sign in to comment.