1
1
use async_channel:: { Receiver , Sender } ;
2
2
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
+ } ;
4
8
use bevy_tasks:: ComputeTaskPool ;
5
9
6
10
#[ cfg( feature = "trace" ) ]
7
11
use bevy_utils:: tracing:: Instrument ;
8
12
9
- use crate :: RenderApp ;
13
+ use crate :: { PipelinedRenderingUpdateApp , RenderApp } ;
10
14
11
15
/// Resource to be used for pipelined rendering for sending the render app from the main thread to the rendering thread
12
16
#[ derive( Resource ) ]
@@ -17,7 +21,12 @@ pub struct MainToRenderAppSender(pub Sender<SubApp>);
17
21
pub struct RenderToMainAppReceiver ( pub Receiver < SubApp > ) ;
18
22
19
23
/// 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 ( PipelinedRenderingUpdateApp ) . is_err ( ) {
27
+ return ;
28
+ }
29
+
21
30
let ( app_to_render_sender, app_to_render_receiver) = async_channel:: bounded :: < SubApp > ( 1 ) ;
22
31
let ( render_to_app_sender, render_to_app_receiver) = async_channel:: bounded :: < SubApp > ( 1 ) ;
23
32
@@ -31,55 +40,38 @@ pub fn setup_pipelined_rendering(app: &mut App) {
31
40
loop {
32
41
// TODO: exit loop when app is exited
33
42
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) ;
38
43
let mut sub_app = recv_task. await . unwrap ( ) ;
39
44
sub_app. run ( ) ;
40
45
render_to_app_sender. send ( sub_app) . await . unwrap ( ) ;
41
46
}
42
47
} ;
43
48
#[ cfg( feature = "trace" ) ]
44
- let span = bevy_utils:: tracing:: info_span!( "render task " ) ;
49
+ let span = bevy_utils:: tracing:: info_span!( "render app " ) ;
45
50
#[ cfg( feature = "trace" ) ]
46
51
let render_task = render_task. instrument ( span) ;
47
52
ComputeTaskPool :: get ( ) . spawn ( render_task) . detach ( ) ;
48
53
}
49
54
50
- pub fn update_rendering ( app : & mut App ) {
51
- app. update ( ) ;
52
-
55
+ pub fn update_rendering ( app_world : & mut World ) {
53
56
// 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
56
58
. resource_scope ( |world, main_thread_executor : Mut < MainThreadExecutor > | {
57
59
ComputeTaskPool :: get ( )
58
60
. scope ( Some ( main_thread_executor. 0 . clone ( ) ) , |s| {
59
61
s. spawn ( async {
60
62
let receiver = world. get_resource :: < RenderToMainAppReceiver > ( ) . unwrap ( ) ;
61
63
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) ;
66
64
recv. await . unwrap ( )
67
65
} ) ;
68
66
} )
69
67
. pop ( )
70
68
} )
71
69
. unwrap ( ) ;
72
70
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) ;
83
72
73
+ app_world. resource_scope ( |_world, sender : Mut < MainToRenderAppSender > | {
74
+ sender. 0 . send_blocking ( render_app) . unwrap ( ) ;
75
+ } ) ;
84
76
// frame pacing plugin should run here somehow. i.e. after rendering, but before input handling
85
77
}
0 commit comments