Skip to content

Commit e8c5e9c

Browse files
committed
add ability to disable pipelined rendering
1 parent feb4746 commit e8c5e9c

File tree

4 files changed

+56
-36
lines changed

4 files changed

+56
-36
lines changed

crates/bevy_app/src/app.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,11 @@ impl App {
161161
/// See [`add_sub_app`](Self::add_sub_app) and [`run_once`](Schedule::run_once) for more details.
162162
pub fn update(&mut self) {
163163
#[cfg(feature = "trace")]
164-
let _bevy_frame_update_span = info_span!("frame").entered();
164+
let _bevy_frame_update_span = info_span!("main_app").entered();
165165
self.schedule.run(&mut self.world);
166166
for sub_app in self.sub_apps.values_mut() {
167-
(sub_app.extract)(&mut self.world, &mut sub_app.app);
167+
sub_app.extract(&mut self.world);
168+
sub_app.run();
168169
}
169170
}
170171

crates/bevy_render/src/lib.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ pub mod prelude {
3939

4040
use globals::GlobalsPlugin;
4141
pub use once_cell;
42+
use pipelined_rendering::update_rendering;
4243
use prelude::ComputedVisibility;
4344

4445
use crate::{
@@ -61,8 +62,20 @@ use std::{
6162
};
6263

6364
/// Contains the default Bevy rendering backend based on wgpu.
64-
#[derive(Default)]
65-
pub struct RenderPlugin;
65+
pub struct RenderPlugin {
66+
pub use_pipelined_rendering: bool,
67+
}
68+
69+
impl Default for RenderPlugin {
70+
fn default() -> Self {
71+
RenderPlugin {
72+
#[cfg(not(target_arch = "wasm32"))]
73+
use_pipelined_rendering: true,
74+
#[cfg(target_arch = "wasm32")]
75+
use_pipelined_rendering: false,
76+
}
77+
}
78+
}
6679

6780
/// The labels of the default App rendering stages.
6881
#[derive(Debug, Hash, PartialEq, Eq, Clone, StageLabel)]
@@ -127,6 +140,10 @@ pub mod main_graph {
127140
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, AppLabel)]
128141
pub struct RenderApp;
129142

143+
/// A Label for the sub app that runs the parts of pipelined rendering that need to run on the main thread.
144+
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, AppLabel)]
145+
pub struct PipelinedRenderingApp;
146+
130147
impl Plugin for RenderPlugin {
131148
/// Initializes the renderer, sets up the [`RenderStage`](RenderStage) and creates the rendering sub-app.
132149
fn build(&self, app: &mut App) {
@@ -220,7 +237,7 @@ impl Plugin for RenderPlugin {
220237

221238
app.add_sub_app(RenderApp, render_app, move |app_world, render_app| {
222239
#[cfg(feature = "trace")]
223-
let _render_span = bevy_utils::tracing::info_span!("renderer subapp").entered();
240+
let _render_span = bevy_utils::tracing::info_span!("extract").entered();
224241
{
225242
#[cfg(feature = "trace")]
226243
let _stage_span =
@@ -329,6 +346,17 @@ impl Plugin for RenderPlugin {
329346
});
330347
}
331348

349+
if self.use_pipelined_rendering {
350+
app.add_sub_app(
351+
PipelinedRenderingApp,
352+
App::new(),
353+
|app_world, _render_app| {
354+
update_rendering(app_world);
355+
},
356+
|_render_world| {},
357+
);
358+
}
359+
332360
app.add_plugin(ValidParentCheckPlugin::<ComputedVisibility>::default())
333361
.add_plugin(WindowRenderPlugin)
334362
.add_plugin(CameraPlugin)
Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
use async_channel::{Receiver, Sender};
22
use bevy_app::{App, SubApp};
3-
use bevy_ecs::{schedule::MainThreadExecutor, system::Resource, world::Mut};
3+
use bevy_ecs::{
4+
schedule::MainThreadExecutor,
5+
system::Resource,
6+
world::{Mut, World},
7+
};
48
use bevy_tasks::ComputeTaskPool;
59

610
#[cfg(feature = "trace")]
711
use bevy_utils::tracing::Instrument;
812

9-
use crate::RenderApp;
13+
use crate::{PipelinedRenderingApp, RenderApp};
1014

1115
/// Resource to be used for pipelined rendering for sending the render app from the main thread to the rendering thread
1216
#[derive(Resource)]
@@ -17,7 +21,12 @@ pub struct MainToRenderAppSender(pub Sender<SubApp>);
1721
pub struct RenderToMainAppReceiver(pub Receiver<SubApp>);
1822

1923
/// sets up the render thread and insert resource into the main app for controlling the render thread
20-
pub fn setup_pipelined_rendering(app: &mut App) {
24+
pub fn setup_rendering(app: &mut App) {
25+
// skip this if pipelined rendering is not enabled
26+
if app.get_sub_app(PipelinedRenderingApp).is_err() {
27+
return;
28+
}
29+
2130
let (app_to_render_sender, app_to_render_receiver) = async_channel::bounded::<SubApp>(1);
2231
let (render_to_app_sender, render_to_app_receiver) = async_channel::bounded::<SubApp>(1);
2332

@@ -31,55 +40,38 @@ pub fn setup_pipelined_rendering(app: &mut App) {
3140
loop {
3241
// TODO: exit loop when app is exited
3342
let recv_task = app_to_render_receiver.recv();
34-
#[cfg(feature = "trace")]
35-
let span = bevy_utils::tracing::info_span!("receive render world from main");
36-
#[cfg(feature = "trace")]
37-
let recv_task = recv_task.instrument(span);
3843
let mut sub_app = recv_task.await.unwrap();
3944
sub_app.run();
4045
render_to_app_sender.send(sub_app).await.unwrap();
4146
}
4247
};
4348
#[cfg(feature = "trace")]
44-
let span = bevy_utils::tracing::info_span!("render task");
49+
let span = bevy_utils::tracing::info_span!("render app");
4550
#[cfg(feature = "trace")]
4651
let render_task = render_task.instrument(span);
4752
ComputeTaskPool::get().spawn(render_task).detach();
4853
}
4954

50-
pub fn update_rendering(app: &mut App) {
51-
app.update();
52-
55+
pub fn update_rendering(app_world: &mut World) {
5356
// wait to get the render app back to signal that rendering is finished
54-
let mut render_app = app
55-
.world
57+
let mut render_app = app_world
5658
.resource_scope(|world, main_thread_executor: Mut<MainThreadExecutor>| {
5759
ComputeTaskPool::get()
5860
.scope(Some(main_thread_executor.0.clone()), |s| {
5961
s.spawn(async {
6062
let receiver = world.get_resource::<RenderToMainAppReceiver>().unwrap();
6163
let recv = receiver.0.recv();
62-
#[cfg(feature = "trace")]
63-
let span = bevy_utils::tracing::info_span!("wait for render");
64-
#[cfg(feature = "trace")]
65-
let recv = recv.instrument(span);
6664
recv.await.unwrap()
6765
});
6866
})
6967
.pop()
7068
})
7169
.unwrap();
7270

73-
render_app.extract(&mut app.world);
74-
75-
{
76-
#[cfg(feature = "trace")]
77-
let _span = bevy_utils::tracing::info_span!("send world to render").entered();
78-
app.world
79-
.resource_scope(|_world, sender: Mut<MainToRenderAppSender>| {
80-
sender.0.send_blocking(render_app).unwrap();
81-
});
82-
}
71+
render_app.extract(app_world);
8372

73+
app_world.resource_scope(|_world, sender: Mut<MainToRenderAppSender>| {
74+
sender.0.send_blocking(render_app).unwrap();
75+
});
8476
// frame pacing plugin should run here somehow. i.e. after rendering, but before input handling
8577
}

crates/bevy_winit/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ mod web_resize;
44
mod winit_config;
55
mod winit_windows;
66

7-
use bevy_render::pipelined_rendering::{setup_pipelined_rendering, update_rendering};
7+
use bevy_render::pipelined_rendering::setup_rendering;
88
use converters::convert_cursor_grab_mode;
99
pub use winit_config::*;
1010
pub use winit_windows::*;
@@ -349,7 +349,7 @@ pub fn winit_runner_with(mut app: App) {
349349

350350
let return_from_run = app.world.resource::<WinitSettings>().return_from_run;
351351

352-
setup_pipelined_rendering(&mut app);
352+
setup_rendering(&mut app);
353353

354354
trace!("Entering winit event loop");
355355

@@ -592,8 +592,7 @@ pub fn winit_runner_with(mut app: App) {
592592
};
593593
if update {
594594
winit_state.last_update = Instant::now();
595-
update_rendering(&mut app);
596-
// app.update();
595+
app.update();
597596
}
598597
}
599598
Event::RedrawEventsCleared => {

0 commit comments

Comments
 (0)