use skulpin::app::TimeState;
use skulpin::skia_safe;
use skulpin::skia_safe::Canvas;
use skulpin::winit;
use skulpin::CoordinateSystemHelper;
use skulpin_plugin_imgui::imgui;
use skulpin_plugin_imgui::ImguiRendererPlugin;
mod imgui_support;
use imgui_support::ImguiManager;
struct ExampleApp {
profiler_ui: puffin_imgui::ProfilerUi,
}
impl ExampleApp {
pub fn new() -> Self {
ExampleApp {
profiler_ui: puffin_imgui::ProfilerUi::default(),
}
}
fn update(
&mut self,
_time_state: &TimeState,
) {
profiling::scope!("update");
some_function();
some_other_function(3);
}
fn draw(
&mut self,
canvas: &mut Canvas,
_coordinate_system_helper: &CoordinateSystemHelper,
imgui_manager: &ImguiManager,
) {
profiling::scope!("draw");
imgui_manager.with_ui(|ui| {
self.profiler_ui.window(ui);
});
canvas.clear(skia_safe::Color::from_argb(0, 0, 0, 255));
let mut paint = skia_safe::Paint::new(skia_safe::Color4f::new(0.8, 0.8, 0.8, 1.0), None);
paint.set_anti_alias(true);
paint.set_style(skia_safe::paint::Style::StrokeAndFill);
paint.set_stroke_width(1.0);
canvas.draw_circle(skia_safe::Point::new(200.0, 200.0), 100.0, &paint);
let mut text_paint =
skia_safe::Paint::new(skia_safe::Color4f::new(1.0, 1.0, 0.0, 1.0), None);
text_paint.set_anti_alias(true);
text_paint.set_style(skia_safe::paint::Style::StrokeAndFill);
text_paint.set_stroke_width(1.0);
let mut font = skia_safe::Font::default();
font.set_size(20.0);
canvas.draw_str(
imgui::im_str!("profiling demo using puffin"),
(50, 100),
&font,
&text_paint,
);
}
}
fn main() {
env_logger::Builder::from_default_env()
.filter_level(log::LevelFilter::Debug)
.init();
puffin::set_scopes_on(true);
let event_loop = winit::event_loop::EventLoop::<()>::with_user_event();
let logical_size = winit::dpi::LogicalSize::new(900.0, 600.0);
let visible_range = skulpin::skia_safe::Rect {
left: 0.0,
right: logical_size.width as f32,
top: 0.0,
bottom: logical_size.height as f32,
};
let scale_to_fit = skulpin::skia_safe::matrix::ScaleToFit::Center;
let winit_window = winit::window::WindowBuilder::new()
.with_title("Skulpin")
.with_inner_size(logical_size)
.build(&event_loop)
.expect("Failed to create window");
let window = skulpin::WinitWindow::new(&winit_window);
let imgui_manager = imgui_support::init_imgui_manager(&winit_window);
let mut imgui_plugin: Option<Box<dyn skulpin::RendererPlugin>> = None;
imgui_manager.with_context(|context| {
imgui_plugin = Some(Box::new(ImguiRendererPlugin::new(context)));
});
let renderer = skulpin::RendererBuilder::new()
.use_vulkan_debug_layer(true)
.coordinate_system(skulpin::CoordinateSystem::VisibleRange(
visible_range,
scale_to_fit,
))
.add_plugin(imgui_plugin.unwrap())
.build(&window);
if let Err(e) = renderer {
println!("Error during renderer construction: {:?}", e);
return;
}
let mut renderer = renderer.unwrap();
let mut app = ExampleApp::new();
let mut time_state = skulpin::app::TimeState::new();
event_loop.run(move |event, _window_target, control_flow| {
let window = skulpin::WinitWindow::new(&winit_window);
imgui_manager.handle_event(&winit_window, &event);
match event {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::CloseRequested,
..
} => *control_flow = winit::event_loop::ControlFlow::Exit,
winit::event::Event::WindowEvent {
event:
winit::event::WindowEvent::KeyboardInput {
input:
winit::event::KeyboardInput {
virtual_keycode: Some(winit::event::VirtualKeyCode::Escape),
..
},
..
},
..
} => *control_flow = winit::event_loop::ControlFlow::Exit,
winit::event::Event::MainEventsCleared => {
time_state.update();
app.update(&time_state);
winit_window.request_redraw();
}
winit::event::Event::RedrawRequested(_window_id) => {
if let Err(e) = renderer.draw(&window, |canvas, coordinate_system_helper| {
imgui_manager.begin_frame(&winit_window);
app.draw(canvas, &coordinate_system_helper, &imgui_manager);
imgui_manager.render(&winit_window);
}) {
println!("Error during draw: {:?}", e);
*control_flow = winit::event_loop::ControlFlow::Exit
}
profiling::finish_frame!();
}
_ => {}
}
});
}
fn burn_time(micros: u128) {
let start_time = std::time::Instant::now();
loop {
if (std::time::Instant::now() - start_time).as_micros() > micros {
break;
}
}
}
#[profiling::function]
fn some_function() {
burn_time(200);
}
fn some_other_function(iterations: usize) {
profiling::scope!("some_other_function");
burn_time(200);
{
profiling::scope!("do iterations");
for i in 0..iterations {
profiling::scope!(
"some_inner_function_that_sleeps",
format!("other data {}", i).as_str()
);
some_inner_function(i);
burn_time(200);
}
}
}
#[profiling::function]
fn some_inner_function(_iteration_index: usize) {
burn_time(200);
}