Browse Source

Opt-in logging of egui-wgpu using puffin

pull/2287/head
Emil Ernerfeldt 2 years ago
parent
commit
e225c6b8d0
  1. 1
      Cargo.lock
  2. 2
      crates/eframe/Cargo.toml
  3. 7
      crates/egui-wgpu/Cargo.toml
  4. 22
      crates/egui-wgpu/src/lib.rs
  5. 34
      crates/egui-wgpu/src/renderer.rs
  6. 31
      crates/egui-wgpu/src/winit.rs

1
Cargo.lock

@ -1175,6 +1175,7 @@ dependencies = [
"document-features",
"egui",
"pollster",
"puffin",
"tracing",
"type-map",
"wgpu",

2
crates/eframe/Cargo.toml

@ -47,7 +47,7 @@ persistence = [
##
## Only enabled on native, because of the low resolution (1ms) of time keeping in browsers.
## `eframe` will call `puffin::GlobalProfiler::lock().new_frame()` for you
puffin = ["dep:puffin", "egui_glow?/puffin"]
puffin = ["dep:puffin", "egui_glow?/puffin", "egui-wgpu?/puffin"]
## Enable screen reader support (requires `ctx.options().screen_reader = true;`)
screen_reader = ["egui-winit/screen_reader", "tts"]

7
crates/egui-wgpu/Cargo.toml

@ -28,6 +28,9 @@ all-features = true
[features]
## Enable profiling with the [`puffin`](https://docs.rs/puffin) crate.
puffin = ["dep:puffin"]
## Enable [`winit`](https://docs.rs/winit) integration.
winit = ["dep:pollster", "dep:winit"]
@ -48,3 +51,7 @@ document-features = { version = "0.2", optional = true }
pollster = { version = "0.2", optional = true }
winit = { version = "0.27.2", optional = true }
# Native:
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
puffin = { version = "0.14", optional = true }

22
crates/egui-wgpu/src/lib.rs

@ -95,3 +95,25 @@ pub fn preferred_framebuffer_format(formats: &[wgpu::TextureFormat]) -> wgpu::Te
}
formats[0] // take the first
}
// ---------------------------------------------------------------------------
/// Profiling macro for feature "puffin"
macro_rules! profile_function {
($($arg: tt)*) => {
#[cfg(feature = "puffin")]
#[cfg(not(target_arch = "wasm32"))]
puffin::profile_function!($($arg)*);
};
}
pub(crate) use profile_function;
/// Profiling macro for feature "puffin"
macro_rules! profile_scope {
($($arg: tt)*) => {
#[cfg(feature = "puffin")]
#[cfg(not(target_arch = "wasm32"))]
puffin::profile_scope!($($arg)*);
};
}
pub(crate) use profile_scope;

34
crates/egui-wgpu/src/renderer.rs

@ -174,6 +174,8 @@ impl Renderer {
output_depth_format: Option<wgpu::TextureFormat>,
msaa_samples: u32,
) -> Self {
crate::profile_function!();
let shader = wgpu::ShaderModuleDescriptor {
label: Some("egui"),
source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("egui.wgsl"))),
@ -347,6 +349,8 @@ impl Renderer {
paint_jobs: &[egui::epaint::ClippedPrimitive],
screen_descriptor: &ScreenDescriptor,
) {
crate::profile_function!();
let pixels_per_point = screen_descriptor.pixels_per_point;
let size_in_pixels = screen_descriptor.size_in_pixels;
@ -421,6 +425,8 @@ impl Renderer {
};
if callback.rect.is_positive() {
crate::profile_scope!("callback");
needs_reset = true;
{
@ -472,6 +478,8 @@ impl Renderer {
id: egui::TextureId,
image_delta: &egui::epaint::ImageDelta,
) {
crate::profile_function!();
let width = image_delta.image.width() as u32;
let height = image_delta.image.height() as u32;
@ -653,6 +661,8 @@ impl Renderer {
texture: &wgpu::TextureView,
sampler_descriptor: wgpu::SamplerDescriptor<'_>,
) -> egui::TextureId {
crate::profile_function!();
let sampler = device.create_sampler(&wgpu::SamplerDescriptor {
compare: None,
..sampler_descriptor
@ -692,6 +702,8 @@ impl Renderer {
sampler_descriptor: wgpu::SamplerDescriptor<'_>,
id: egui::TextureId,
) {
crate::profile_function!();
let (_user_texture, user_texture_binding) = self
.textures
.get_mut(&id)
@ -732,8 +744,12 @@ impl Renderer {
paint_jobs: &[egui::epaint::ClippedPrimitive],
screen_descriptor: &ScreenDescriptor,
) -> Vec<wgpu::CommandBuffer> {
crate::profile_function!();
let screen_size_in_points = screen_descriptor.screen_size_in_points();
{
crate::profile_scope!("uniforms");
// Update uniform buffer
queue.write_buffer(
&self.uniform_buffer,
@ -743,9 +759,11 @@ impl Renderer {
_padding: Default::default(),
}]),
);
}
// Determine how many vertices & indices need to be rendered.
let (vertex_count, index_count) =
let (vertex_count, index_count) = {
crate::profile_scope!("count_vertices_indices");
paint_jobs.iter().fold((0, 0), |acc, clipped_primitive| {
match &clipped_primitive.primitive {
Primitive::Mesh(mesh) => {
@ -753,9 +771,11 @@ impl Renderer {
}
Primitive::Callback(_) => acc,
}
});
// Resize index buffer if needed.
})
};
{
// Resize index buffer if needed:
self.index_buffer.slices.clear();
let required_size = (std::mem::size_of::<u32>() * index_count) as u64;
if self.index_buffer.capacity < required_size {
@ -764,8 +784,9 @@ impl Renderer {
self.index_buffer.buffer = create_index_buffer(device, self.index_buffer.capacity);
}
}
// Resize vertex buffer if needed.
{
// Resize vertex buffer if needed:
self.vertex_buffer.slices.clear();
let required_size = (std::mem::size_of::<Vertex>() * vertex_count) as u64;
if self.vertex_buffer.capacity < required_size {
@ -778,6 +799,8 @@ impl Renderer {
// Upload index & vertex data and call user callbacks
let mut user_cmd_bufs = Vec::new(); // collect user command buffers
crate::profile_scope!("primitives");
for egui::ClippedPrimitive { primitive, .. } in paint_jobs.iter() {
match primitive {
Primitive::Mesh(mesh) => {
@ -806,6 +829,7 @@ impl Renderer {
continue;
};
crate::profile_scope!("callback");
user_cmd_bufs.extend((cbfn.prepare)(
device,
queue,
@ -841,6 +865,7 @@ fn create_sampler(options: egui::TextureOptions, device: &wgpu::Device) -> wgpu:
}
fn create_vertex_buffer(device: &wgpu::Device, size: u64) -> wgpu::Buffer {
crate::profile_function!();
device.create_buffer(&wgpu::BufferDescriptor {
label: Some("egui_vertex_buffer"),
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
@ -850,6 +875,7 @@ fn create_vertex_buffer(device: &wgpu::Device, size: u64) -> wgpu::Buffer {
}
fn create_index_buffer(device: &wgpu::Device, size: u64) -> wgpu::Buffer {
crate::profile_function!();
device.create_buffer(&wgpu::BufferDescriptor {
label: Some("egui_index_buffer"),
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,

31
crates/egui-wgpu/src/winit.rs

@ -109,6 +109,8 @@ impl Painter {
}
fn configure_surface(&mut self, width_in_pixels: u32, height_in_pixels: u32) {
crate::profile_function!();
let render_state = self
.render_state
.as_ref()
@ -227,6 +229,8 @@ impl Painter {
clipped_primitives: &[egui::ClippedPrimitive],
textures_delta: &egui::TexturesDelta,
) {
crate::profile_function!();
let render_state = match self.render_state.as_mut() {
Some(rs) => rs,
None => return,
@ -237,7 +241,13 @@ impl Painter {
};
let (width, height) = (surface_state.width, surface_state.height);
let output_frame = match surface_state.surface.get_current_texture() {
let output_frame = {
crate::profile_scope!("get_current_texture");
// This is what vsync-waiting happens, at least on Mac.
surface_state.surface.get_current_texture()
};
let output_frame = match output_frame {
Ok(frame) => frame,
#[allow(clippy::single_match_else)]
Err(e) => match (*self.configuration.on_surface_error)(e) {
@ -326,16 +336,25 @@ impl Painter {
}
}
let encoded = {
crate::profile_scope!("CommandEncoder::finish");
encoder.finish()
};
// Submit the commands: both the main buffer and user-defined ones.
render_state.queue.submit(
user_cmd_bufs
.into_iter()
.chain(std::iter::once(encoder.finish())),
);
{
crate::profile_scope!("Queue::submit");
render_state
.queue
.submit(user_cmd_bufs.into_iter().chain(std::iter::once(encoded)));
};
// Redraw egui
{
crate::profile_scope!("present");
output_frame.present();
}
}
#[allow(clippy::unused_self)]
pub fn destroy(&mut self) {

Loading…
Cancel
Save