@@ -6,7 +6,9 @@ const FPS_LABEL_NODE_NAME: &str = "profiling_overlay_fps";
66const SIM_LABEL_NODE_NAME : & str = "profiling_overlay_sim" ;
77const GRAPHICS_LABEL_NODE_NAME : & str = "profiling_overlay_graphics" ;
88const ROW_NODE_NAME : & str = "profiling_overlay_row" ;
9- const REFRESH_SECONDS : f32 = 1.0 ;
9+
10+ const REFRESH_SECONDS : f32 = 2.0 ;
11+ const PROFILE_SAMPLE_EVERY_FRAMES : u32 = 60 ;
1012
1113#[ State ]
1214struct DemoProfilingOverlayState {
@@ -16,73 +18,103 @@ struct DemoProfilingOverlayState {
1618 pub sim_label : NodeID ,
1719 #[ default = NodeID :: nil ( ) ]
1820 pub graphics_label : NodeID ,
21+
1922 pub refresh_timer : f32 ,
23+
24+ #[ default = 0 ]
25+ pub frame_counter : u32 ,
26+
2027 pub fps_value : f32 ,
2128 pub dt_us_value : f32 ,
2229 pub sim_us_value : f32 ,
2330 pub graphics_us_value : f32 ,
31+
32+ pub fps_sum : f32 ,
2433 pub dt_us_sum : f32 ,
2534 pub sim_us_sum : f32 ,
2635 pub graphics_us_sum : f32 ,
36+
2737 pub timing_samples : u32 ,
2838}
2939
3040lifecycle ! ( {
3141 fn on_init( & self , ctx: & mut ScriptContext <' _, API >) {
3242 let row = get_child!( ctx. run, ctx. id, ROW_NODE_NAME ) . unwrap_or( NodeID :: nil( ) ) ;
33- let fps_label = get_child!( ctx. run, row, FPS_LABEL_NODE_NAME ) . unwrap_or( NodeID :: nil( ) ) ;
34- let sim_label = get_child!( ctx. run, row, SIM_LABEL_NODE_NAME ) . unwrap_or( NodeID :: nil( ) ) ;
43+
44+ let fps_label =
45+ get_child!( ctx. run, row, FPS_LABEL_NODE_NAME ) . unwrap_or( NodeID :: nil( ) ) ;
46+
47+ let sim_label =
48+ get_child!( ctx. run, row, SIM_LABEL_NODE_NAME ) . unwrap_or( NodeID :: nil( ) ) ;
49+
3550 let graphics_label =
36- get_child!( ctx. run, row, GRAPHICS_LABEL_NODE_NAME ) . unwrap_or( NodeID :: nil( ) ) ;
51+ get_child!( ctx. run, row, GRAPHICS_LABEL_NODE_NAME )
52+ . unwrap_or( NodeID :: nil( ) ) ;
53+
3754 with_state_mut!( ctx. run, DemoProfilingOverlayState , ctx. id, |state| {
3855 state. fps_label = fps_label;
3956 state. sim_label = sim_label;
4057 state. graphics_label = graphics_label;
4158 } ) ;
59+
4260 self . refresh_text( ctx) ;
4361 }
4462
4563 fn on_update( & self , ctx: & mut ScriptContext <' _, API >) {
4664 let dt = delta_time!( ctx. run) . max( 0.0 ) ;
47- let p = profiling!( ctx. run) ;
48- let fps = if p. fps. is_finite( ) && p. fps > 0.0 {
49- p. fps
50- } else {
51- 0.0
52- } ;
53- let dt_us = dt * 1_000_000.0 ;
54- let sim_us = p. simulation_time. as_micros( ) as f32 ;
55- let graphics_us = p. graphics_time. as_micros( ) as f32 ;
56-
57- let should_refresh = with_state_mut!( ctx. run, DemoProfilingOverlayState , ctx. id, |state| {
58- state. refresh_timer += dt;
59- if fps > 0.0 {
60- state. fps_value = fps;
61- }
62- if dt_us > 0.0 || sim_us > 0.0 || graphics_us > 0.0 {
63- state. dt_us_sum += dt_us;
64- state. sim_us_sum += sim_us;
65- state. graphics_us_sum += graphics_us;
66- state. timing_samples = state. timing_samples. saturating_add( 1 ) ;
67- }
68- if state. refresh_timer >= REFRESH_SECONDS {
69- state. refresh_timer = 0.0 ;
70- if state. timing_samples > 0 {
71- let samples = state. timing_samples as f32 ;
72- state. dt_us_value = state. dt_us_sum / samples;
73- state. sim_us_value = state. sim_us_sum / samples;
74- state. graphics_us_value = state. graphics_us_sum / samples;
75- state. dt_us_sum = 0.0 ;
76- state. sim_us_sum = 0.0 ;
77- state. graphics_us_sum = 0.0 ;
78- state. timing_samples = 0 ;
65+
66+ let ( should_sample, should_refresh) =
67+ with_state_mut!( ctx. run, DemoProfilingOverlayState , ctx. id, |state| {
68+ state. refresh_timer += dt;
69+ state. frame_counter = state. frame_counter. wrapping_add( 1 ) ;
70+ let should_sample =
71+ state. frame_counter % PROFILE_SAMPLE_EVERY_FRAMES == 0 ;
72+
73+ if state. refresh_timer >= REFRESH_SECONDS {
74+ state. refresh_timer = 0.0 ;
75+
76+ if state. timing_samples > 0 {
77+ let samples = state. timing_samples as f32 ;
78+
79+ state. fps_value = state. fps_sum / samples;
80+ state. dt_us_value = state. dt_us_sum / samples;
81+ state. sim_us_value = state. sim_us_sum / samples;
82+ state. graphics_us_value =
83+ state. graphics_us_sum / samples;
84+
85+ state. fps_sum = 0.0 ;
86+ state. dt_us_sum = 0.0 ;
87+ state. sim_us_sum = 0.0 ;
88+ state. graphics_us_sum = 0.0 ;
89+
90+ state. timing_samples = 0 ;
91+ }
92+
93+ ( should_sample, true )
94+ } else {
95+ ( should_sample, false )
7996 }
80- true
81- } else {
82- false
83- }
84- } )
85- . unwrap_or( true ) ;
97+ } )
98+ . unwrap_or( ( false , false ) ) ;
99+
100+ if should_sample {
101+ let p = profiling!( ctx. run) ;
102+
103+ with_state_mut!( ctx. run, DemoProfilingOverlayState , ctx. id, |state| {
104+ let fps = if p. fps. is_finite( ) && p. fps > 0.0 {
105+ p. fps
106+ } else {
107+ 0.0
108+ } ;
109+
110+ state. fps_sum += fps;
111+ state. dt_us_sum += dt * 1_000_000.0 ;
112+ state. sim_us_sum += p. simulation_time. as_micros( ) as f32 ;
113+ state. graphics_us_sum += p. graphics_time. as_micros( ) as f32 ;
114+ state. timing_samples = state. timing_samples. saturating_add( 1 ) ;
115+ } ) ;
116+ }
117+
86118 if should_refresh {
87119 self . refresh_text( ctx) ;
88120 }
@@ -91,8 +123,19 @@ lifecycle!({
91123
92124methods ! ( {
93125 fn refresh_text( & self , ctx: & mut ScriptContext <' _, API >) {
94- let ( fps_label, sim_label, graphics_label, fps, dt_us, sim_us, graphics_us) =
95- with_state!( ctx. run, DemoProfilingOverlayState , ctx. id, |state| {
126+ let (
127+ fps_label,
128+ sim_label,
129+ graphics_label,
130+ fps,
131+ dt_us,
132+ sim_us,
133+ graphics_us,
134+ ) = with_state!(
135+ ctx. run,
136+ DemoProfilingOverlayState ,
137+ ctx. id,
138+ |state| {
96139 (
97140 state. fps_label,
98141 state. sim_label,
@@ -102,11 +145,26 @@ methods!({
102145 state. sim_us_value,
103146 state. graphics_us_value,
104147 )
105- } ) ;
148+ }
149+ ) ;
150+
151+ set_label_text(
152+ ctx,
153+ fps_label,
154+ format!( "FPS {:.1}" , fps) ,
155+ ) ;
106156
107- set_label_text( ctx, fps_label, format!( "FPS {:.1}" , fps) ) ;
108- set_label_text( ctx, sim_label, format!( "Sim {:.0} us | dt {:.0} us" , sim_us, dt_us) ) ;
109- set_label_text( ctx, graphics_label, format!( "Gfx {:.0} us" , graphics_us) ) ;
157+ set_label_text(
158+ ctx,
159+ sim_label,
160+ format!( "Sim {:.0} us | dt {:.0} us" , sim_us, dt_us) ,
161+ ) ;
162+
163+ set_label_text(
164+ ctx,
165+ graphics_label,
166+ format!( "Gfx {:.0} us" , graphics_us) ,
167+ ) ;
110168 }
111169} ) ;
112170
@@ -118,6 +176,7 @@ fn set_label_text<API: ScriptAPI + ?Sized>(
118176 if id. is_nil ( ) {
119177 return ;
120178 }
179+
121180 with_node_mut ! ( ctx. run, UiLabel , id, |label| {
122181 label. text = text. into( ) ;
123182 } ) ;
0 commit comments