Merge pull request #2881 from iced-rs/presentation-metrics

Presentation metrics for `comet`
This commit is contained in:
Héctor 2025-04-09 22:58:25 +02:00 committed by GitHub
commit 208de5578c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 211 additions and 43 deletions

2
Cargo.lock generated
View file

@ -2556,6 +2556,7 @@ version = "0.14.0-dev"
dependencies = [ dependencies = [
"bytemuck", "bytemuck",
"cosmic-text", "cosmic-text",
"iced_debug",
"iced_graphics", "iced_graphics",
"kurbo 0.10.4", "kurbo 0.10.4",
"log", "log",
@ -2575,6 +2576,7 @@ dependencies = [
"futures", "futures",
"glam", "glam",
"guillotiere", "guillotiere",
"iced_debug",
"iced_graphics", "iced_graphics",
"log", "log",
"lyon", "lyon",

View file

@ -94,6 +94,7 @@ pub fn run() -> impl Stream<Item = Event> {
let mut last_message = String::new(); let mut last_message = String::new();
let mut last_commands_spawned = 0; let mut last_commands_spawned = 0;
let mut last_present_window = None;
loop { loop {
match receive(&mut stream, &mut buffer).await { match receive(&mut stream, &mut buffer).await {
@ -146,6 +147,11 @@ pub fn run() -> impl Stream<Item = Event> {
last_message.clear(); last_message.clear();
last_commands_spawned = 0; last_commands_spawned = 0;
} }
client::Event::SpanStarted(
span::Stage::Present(window),
) => {
last_present_window = Some(window);
}
client::Event::SpanStarted(_) => {} client::Event::SpanStarted(_) => {}
client::Event::SpanFinished( client::Event::SpanFinished(
stage, stage,
@ -173,6 +179,30 @@ pub fn run() -> impl Stream<Item = Event> {
span::Stage::Draw(window) => { span::Stage::Draw(window) => {
Span::Draw { window } Span::Draw { window }
} }
span::Stage::Prepare(primitive) => {
let Some(window) =
last_present_window
else {
continue;
};
Span::Prepare {
window,
primitive,
}
}
span::Stage::Render(primitive) => {
let Some(window) =
last_present_window
else {
continue;
};
Span::Render {
window,
primitive,
}
}
span::Stage::Present(window) => { span::Stage::Present(window) => {
Span::Present { window } Span::Present { window }
} }

View file

@ -21,6 +21,14 @@ pub enum Span {
Draw { Draw {
window: window::Id, window: window::Id,
}, },
Prepare {
window: window::Id,
primitive: Primitive,
},
Render {
window: window::Id,
primitive: Primitive,
},
Present { Present {
window: window::Id, window: window::Id,
}, },
@ -30,6 +38,26 @@ pub enum Span {
}, },
} }
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Hash,
Serialize,
Deserialize,
)]
pub enum Primitive {
Quad,
Triangle,
Shader,
Text,
Image,
}
impl Span { impl Span {
pub fn stage(&self) -> Stage { pub fn stage(&self) -> Stage {
match self { match self {
@ -39,6 +67,8 @@ impl Span {
Span::Layout { window } => Stage::Layout(*window), Span::Layout { window } => Stage::Layout(*window),
Span::Interact { window } => Stage::Interact(*window), Span::Interact { window } => Stage::Interact(*window),
Span::Draw { window } => Stage::Draw(*window), Span::Draw { window } => Stage::Draw(*window),
Span::Prepare { primitive, .. } => Stage::Prepare(*primitive),
Span::Render { primitive, .. } => Stage::Render(*primitive),
Span::Present { window } => Stage::Present(*window), Span::Present { window } => Stage::Present(*window),
Span::Custom { window, name } => { Span::Custom { window, name } => {
Stage::Custom(*window, name.clone()) Stage::Custom(*window, name.clone())
@ -58,6 +88,8 @@ pub enum Stage {
Interact(window::Id), Interact(window::Id),
Draw(window::Id), Draw(window::Id),
Present(window::Id), Present(window::Id),
Prepare(Primitive),
Render(Primitive),
Custom(window::Id, String), Custom(window::Id, String),
} }
@ -70,6 +102,8 @@ impl std::fmt::Display for Stage {
Stage::Layout(_) => "Layout", Stage::Layout(_) => "Layout",
Stage::Interact(_) => "Interact", Stage::Interact(_) => "Interact",
Stage::Draw(_) => "Draw", Stage::Draw(_) => "Draw",
Stage::Prepare(_) => "Prepare",
Stage::Render(_) => "Render",
Stage::Present(_) => "Present", Stage::Present(_) => "Present",
Stage::Custom(_, name) => name, Stage::Custom(_, name) => name,
}) })

View file

@ -7,6 +7,15 @@ pub use internal::Span;
use std::io; use std::io;
#[derive(Debug, Clone, Copy)]
pub enum Primitive {
Quad,
Triangle,
Shader,
Image,
Text,
}
pub fn init(name: &str) { pub fn init(name: &str) {
internal::init(name); internal::init(name);
} }
@ -51,6 +60,14 @@ pub fn draw(window: window::Id) -> Span {
internal::draw(window) internal::draw(window)
} }
pub fn prepare(primitive: Primitive) -> Span {
internal::prepare(primitive)
}
pub fn render(primitive: Primitive) -> Span {
internal::render(primitive)
}
pub fn present(window: window::Id) -> Span { pub fn present(window: window::Id) -> Span {
internal::present(window) internal::present(window)
} }
@ -65,6 +82,7 @@ pub fn skip_next_timing() {
#[cfg(all(feature = "enable", not(target_arch = "wasm32")))] #[cfg(all(feature = "enable", not(target_arch = "wasm32")))]
mod internal { mod internal {
use crate::Primitive;
use crate::core::theme; use crate::core::theme;
use crate::core::time::Instant; use crate::core::time::Instant;
use crate::core::window; use crate::core::window;
@ -171,6 +189,14 @@ mod internal {
span(span::Stage::Draw(window)) span(span::Stage::Draw(window))
} }
pub fn prepare(primitive: Primitive) -> Span {
span(span::Stage::Prepare(to_primitive(primitive)))
}
pub fn render(primitive: Primitive) -> Span {
span(span::Stage::Render(to_primitive(primitive)))
}
pub fn present(window: window::Id) -> Span { pub fn present(window: window::Id) -> Span {
span(span::Stage::Present(window)) span(span::Stage::Present(window))
} }
@ -192,6 +218,16 @@ mod internal {
} }
} }
fn to_primitive(primitive: Primitive) -> span::Primitive {
match primitive {
Primitive::Quad => span::Primitive::Quad,
Primitive::Triangle => span::Primitive::Triangle,
Primitive::Shader => span::Primitive::Shader,
Primitive::Text => span::Primitive::Text,
Primitive::Image => span::Primitive::Image,
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct Span { pub struct Span {
span: span::Stage, span: span::Stage,
@ -222,6 +258,7 @@ mod internal {
#[cfg(any(not(feature = "enable"), target_arch = "wasm32"))] #[cfg(any(not(feature = "enable"), target_arch = "wasm32"))]
mod internal { mod internal {
use crate::Primitive;
use crate::core::theme; use crate::core::theme;
use crate::core::window; use crate::core::window;
@ -263,6 +300,14 @@ mod internal {
Span Span
} }
pub fn prepare(_primitive: Primitive) -> Span {
Span
}
pub fn render(_primitive: Primitive) -> Span {
Span
}
pub fn present(_window: window::Id) -> Span { pub fn present(_window: window::Id) -> Span {
Span Span
} }

View file

@ -196,7 +196,7 @@ where
"--git", "--git",
"https://github.com/iced-rs/comet.git", "https://github.com/iced-rs/comet.git",
"--rev", "--rev",
"5efd34550e42974a0e85af7560c60401bfc13919", "fc9832833f81a8e95e2c4ab8e7e65dcc3c000253",
]) ])
.stdin(Stdio::null()) .stdin(Stdio::null())
.stdout(Stdio::null()) .stdout(Stdio::null())

View file

@ -19,6 +19,7 @@ svg = ["iced_graphics/svg", "resvg"]
geometry = ["iced_graphics/geometry"] geometry = ["iced_graphics/geometry"]
[dependencies] [dependencies]
iced_debug.workspace = true
iced_graphics.workspace = true iced_graphics.workspace = true
bytemuck.workspace = true bytemuck.workspace = true

View file

@ -17,6 +17,7 @@ mod vector;
#[cfg(feature = "geometry")] #[cfg(feature = "geometry")]
pub mod geometry; pub mod geometry;
use iced_debug as debug;
pub use iced_graphics as graphics; pub use iced_graphics as graphics;
pub use iced_graphics::core; pub use iced_graphics::core;
@ -112,6 +113,8 @@ impl Renderer {
engine::adjust_clip_mask(clip_mask, clip_bounds); engine::adjust_clip_mask(clip_mask, clip_bounds);
if !layer.quads.is_empty() {
let render_span = debug::render(debug::Primitive::Quad);
for (quad, background) in &layer.quads { for (quad, background) in &layer.quads {
self.engine.draw_quad( self.engine.draw_quad(
quad, quad,
@ -122,6 +125,11 @@ impl Renderer {
clip_bounds, clip_bounds,
); );
} }
render_span.finish();
}
if !layer.primitives.is_empty() {
let render_span = debug::render(debug::Primitive::Triangle);
for group in &layer.primitives { for group in &layer.primitives {
let Some(new_clip_bounds) = (group.clip_bounds() let Some(new_clip_bounds) = (group.clip_bounds()
@ -147,6 +155,12 @@ impl Renderer {
engine::adjust_clip_mask(clip_mask, clip_bounds); engine::adjust_clip_mask(clip_mask, clip_bounds);
} }
render_span.finish();
}
if !layer.images.is_empty() {
let render_span = debug::render(debug::Primitive::Image);
for image in &layer.images { for image in &layer.images {
self.engine.draw_image( self.engine.draw_image(
image, image,
@ -157,6 +171,12 @@ impl Renderer {
); );
} }
render_span.finish();
}
if !layer.text.is_empty() {
let render_span = debug::render(debug::Primitive::Image);
for group in &layer.text { for group in &layer.text {
for text in group.as_slice() { for text in group.as_slice() {
self.engine.draw_text( self.engine.draw_text(
@ -169,6 +189,9 @@ impl Renderer {
); );
} }
} }
render_span.finish();
}
} }
} }

View file

@ -26,6 +26,7 @@ webgl = ["wgpu/webgl"]
strict-assertions = [] strict-assertions = []
[dependencies] [dependencies]
iced_debug.workspace = true
iced_graphics.workspace = true iced_graphics.workspace = true
bitflags.workspace = true bitflags.workspace = true

View file

@ -47,6 +47,7 @@ mod image;
use buffer::Buffer; use buffer::Buffer;
use iced_debug as debug;
pub use iced_graphics as graphics; pub use iced_graphics as graphics;
pub use iced_graphics::core; pub use iced_graphics::core;
@ -320,6 +321,8 @@ impl Renderer {
} }
if !layer.quads.is_empty() { if !layer.quads.is_empty() {
let prepare_span = debug::prepare(debug::Primitive::Quad);
self.quad.prepare( self.quad.prepare(
&self.engine.quad_pipeline, &self.engine.quad_pipeline,
&self.engine.device, &self.engine.device,
@ -329,9 +332,13 @@ impl Renderer {
viewport.projection(), viewport.projection(),
scale_factor, scale_factor,
); );
prepare_span.finish();
} }
if !layer.triangles.is_empty() { if !layer.triangles.is_empty() {
let prepare_span = debug::prepare(debug::Primitive::Triangle);
self.triangle.prepare( self.triangle.prepare(
&self.engine.triangle_pipeline, &self.engine.triangle_pipeline,
&self.engine.device, &self.engine.device,
@ -341,9 +348,13 @@ impl Renderer {
Transformation::scale(scale_factor), Transformation::scale(scale_factor),
viewport.physical_size(), viewport.physical_size(),
); );
prepare_span.finish();
} }
if !layer.primitives.is_empty() { if !layer.primitives.is_empty() {
let prepare_span = debug::prepare(debug::Primitive::Shader);
let mut primitive_storage = self let mut primitive_storage = self
.engine .engine
.primitive_storage .primitive_storage
@ -360,10 +371,14 @@ impl Renderer {
viewport, viewport,
); );
} }
prepare_span.finish();
} }
#[cfg(any(feature = "svg", feature = "image"))] #[cfg(any(feature = "svg", feature = "image"))]
if !layer.images.is_empty() { if !layer.images.is_empty() {
let prepare_span = debug::prepare(debug::Primitive::Image);
self.image.prepare( self.image.prepare(
&self.engine.image_pipeline, &self.engine.image_pipeline,
&self.engine.device, &self.engine.device,
@ -374,9 +389,13 @@ impl Renderer {
viewport.projection(), viewport.projection(),
scale_factor, scale_factor,
); );
prepare_span.finish();
} }
if !layer.text.is_empty() { if !layer.text.is_empty() {
let prepare_span = debug::prepare(debug::Primitive::Text);
self.text.prepare( self.text.prepare(
&self.engine.text_pipeline, &self.engine.text_pipeline,
&self.engine.device, &self.engine.device,
@ -387,6 +406,8 @@ impl Renderer {
layer.bounds, layer.bounds,
Transformation::scale(scale_factor), Transformation::scale(scale_factor),
); );
prepare_span.finish();
} }
} }
} }
@ -459,6 +480,7 @@ impl Renderer {
}; };
if !layer.quads.is_empty() { if !layer.quads.is_empty() {
let render_span = debug::render(debug::Primitive::Quad);
self.quad.render( self.quad.render(
&self.engine.quad_pipeline, &self.engine.quad_pipeline,
quad_layer, quad_layer,
@ -466,6 +488,7 @@ impl Renderer {
&layer.quads, &layer.quads,
&mut render_pass, &mut render_pass,
); );
render_span.finish();
quad_layer += 1; quad_layer += 1;
} }
@ -473,6 +496,7 @@ impl Renderer {
if !layer.triangles.is_empty() { if !layer.triangles.is_empty() {
let _ = ManuallyDrop::into_inner(render_pass); let _ = ManuallyDrop::into_inner(render_pass);
let render_span = debug::render(debug::Primitive::Triangle);
mesh_layer += self.triangle.render( mesh_layer += self.triangle.render(
&self.engine.triangle_pipeline, &self.engine.triangle_pipeline,
encoder, encoder,
@ -482,6 +506,7 @@ impl Renderer {
physical_bounds, physical_bounds,
scale, scale,
); );
render_span.finish();
render_pass = ManuallyDrop::new(encoder.begin_render_pass( render_pass = ManuallyDrop::new(encoder.begin_render_pass(
&wgpu::RenderPassDescriptor { &wgpu::RenderPassDescriptor {
@ -504,6 +529,7 @@ impl Renderer {
} }
if !layer.primitives.is_empty() { if !layer.primitives.is_empty() {
let render_span = debug::render(debug::Primitive::Shader);
let _ = ManuallyDrop::into_inner(render_pass); let _ = ManuallyDrop::into_inner(render_pass);
let primitive_storage = self let primitive_storage = self
@ -526,6 +552,8 @@ impl Renderer {
} }
} }
render_span.finish();
render_pass = ManuallyDrop::new(encoder.begin_render_pass( render_pass = ManuallyDrop::new(encoder.begin_render_pass(
&wgpu::RenderPassDescriptor { &wgpu::RenderPassDescriptor {
label: Some("iced_wgpu render pass"), label: Some("iced_wgpu render pass"),
@ -548,6 +576,7 @@ impl Renderer {
#[cfg(any(feature = "svg", feature = "image"))] #[cfg(any(feature = "svg", feature = "image"))]
if !layer.images.is_empty() { if !layer.images.is_empty() {
let render_span = debug::render(debug::Primitive::Image);
self.image.render( self.image.render(
&self.engine.image_pipeline, &self.engine.image_pipeline,
&image_cache, &image_cache,
@ -555,11 +584,13 @@ impl Renderer {
scissor_rect, scissor_rect,
&mut render_pass, &mut render_pass,
); );
render_span.finish();
image_layer += 1; image_layer += 1;
} }
if !layer.text.is_empty() { if !layer.text.is_empty() {
let render_span = debug::render(debug::Primitive::Text);
text_layer += self.text.render( text_layer += self.text.render(
&self.engine.text_pipeline, &self.engine.text_pipeline,
&self.text_viewport, &self.text_viewport,
@ -568,6 +599,7 @@ impl Renderer {
scissor_rect, scissor_rect,
&mut render_pass, &mut render_pass,
); );
render_span.finish();
} }
} }