Initial profiling support for Iced.
This commit is contained in:
parent
ba20ac8e49
commit
c5cd236b73
20 changed files with 357 additions and 35 deletions
10
Cargo.toml
10
Cargo.toml
|
|
@ -39,6 +39,14 @@ smol = ["iced_futures/smol"]
|
|||
palette = ["iced_core/palette"]
|
||||
# Enables querying system information
|
||||
system = ["iced_winit/system"]
|
||||
# Enables tracing with Chrome
|
||||
trace_chrome = [
|
||||
"iced_winit/trace",
|
||||
"iced_wgpu?/trace",
|
||||
"iced_glow?/trace",
|
||||
"iced_glutin?/trace",
|
||||
"iced_profiling/tracing-chrome"
|
||||
]
|
||||
|
||||
[badges]
|
||||
maintenance = { status = "actively-developed" }
|
||||
|
|
@ -51,6 +59,7 @@ members = [
|
|||
"glow",
|
||||
"glutin",
|
||||
"lazy",
|
||||
"profiling",
|
||||
"native",
|
||||
"style",
|
||||
"wgpu",
|
||||
|
|
@ -66,6 +75,7 @@ iced_graphics = { version = "0.5", path = "graphics" }
|
|||
iced_winit = { version = "0.6", path = "winit", features = ["application"] }
|
||||
iced_glutin = { version = "0.5", path = "glutin", optional = true }
|
||||
iced_glow = { version = "0.5", path = "glow", optional = true }
|
||||
iced_profiling = { version = "0.1.0", path = "profiling", optional = true }
|
||||
thiserror = "1.0"
|
||||
|
||||
[dependencies.image_rs]
|
||||
|
|
|
|||
BIN
docs/images/perfetto.png
Normal file
BIN
docs/images/perfetto.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
|
|
@ -8,6 +8,7 @@ publish = false
|
|||
[dependencies]
|
||||
iced_winit = { path = "../../winit" }
|
||||
iced_wgpu = { path = "../../wgpu", features = ["webgl"] }
|
||||
iced_profiling = { path = "../../profiling", features = ["tracing-chrome"]}
|
||||
env_logger = "0.8"
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ use winit::{
|
|||
event_loop::{ControlFlow, EventLoop},
|
||||
};
|
||||
|
||||
use iced_profiling::info_span;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
use wasm_bindgen::JsCast;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
|
|
@ -39,6 +41,9 @@ pub fn main() {
|
|||
#[cfg(not(target_arch = "wasm32"))]
|
||||
env_logger::init();
|
||||
|
||||
// Initialize tracing
|
||||
let _guard = iced_profiling::init();
|
||||
|
||||
// Initialize winit
|
||||
let event_loop = EventLoop::new();
|
||||
|
||||
|
|
@ -198,6 +203,8 @@ pub fn main() {
|
|||
}
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
let _ = info_span!("Integration_WGPU", "DRAW").entered();
|
||||
|
||||
if resized {
|
||||
let size = window.inner_size();
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ license = "MIT AND OFL-1.1"
|
|||
repository = "https://github.com/iced-rs/iced"
|
||||
|
||||
[features]
|
||||
trace = ["iced_profiling"]
|
||||
svg = ["iced_graphics/svg"]
|
||||
image = ["iced_graphics/image"]
|
||||
png = ["iced_graphics/png"]
|
||||
|
|
@ -42,6 +43,11 @@ version = "0.5"
|
|||
path = "../graphics"
|
||||
features = ["font-fallback", "font-icons", "opengl"]
|
||||
|
||||
[dependencies.iced_profiling]
|
||||
version = "0.1.0"
|
||||
path = "../profiling"
|
||||
optional = true
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
all-features = true
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ use glow::HasContext;
|
|||
|
||||
use std::cell::RefCell;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use iced_profiling::info_span;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct Pipeline {
|
||||
program: <glow::Context as HasContext>::Program,
|
||||
|
|
@ -148,6 +151,9 @@ impl Pipeline {
|
|||
images: &[layer::Image],
|
||||
layer_bounds: Rectangle<u32>,
|
||||
) {
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Glow::Image", "DRAW").entered();
|
||||
|
||||
unsafe {
|
||||
gl.use_program(Some(self.program));
|
||||
gl.bind_vertex_array(Some(self.vertex_array));
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ use glow::HasContext;
|
|||
use iced_graphics::layer;
|
||||
use iced_native::Rectangle;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use iced_profiling::info_span;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Pipeline {
|
||||
Core(core::Pipeline),
|
||||
|
|
@ -42,6 +45,9 @@ impl Pipeline {
|
|||
scale: f32,
|
||||
bounds: Rectangle<u32>,
|
||||
) {
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Glow::Quad", "DRAW").enter();
|
||||
|
||||
match self {
|
||||
Pipeline::Core(pipeline) => {
|
||||
pipeline.draw(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ use iced_graphics::triangle::{ColoredVertex2D, Vertex2D};
|
|||
use glow::HasContext;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use iced_profiling::info_span;
|
||||
|
||||
const DEFAULT_VERTICES: usize = 1_000;
|
||||
const DEFAULT_INDICES: usize = 1_000;
|
||||
|
||||
|
|
@ -58,6 +61,9 @@ impl Pipeline {
|
|||
transformation: Transformation,
|
||||
scale_factor: f32,
|
||||
) {
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Glow::Triangle", "DRAW").enter();
|
||||
|
||||
unsafe {
|
||||
gl.enable(glow::MULTISAMPLE);
|
||||
gl.enable(glow::SCISSOR_TEST);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ keywords = ["gui", "ui", "graphics", "interface", "widgets"]
|
|||
categories = ["gui"]
|
||||
|
||||
[features]
|
||||
trace = ["iced_profiling/tracing-chrome"]
|
||||
debug = ["iced_winit/debug"]
|
||||
system = ["iced_winit/system"]
|
||||
|
||||
|
|
@ -35,3 +36,8 @@ features = ["application"]
|
|||
version = "0.5"
|
||||
path = "../graphics"
|
||||
features = ["opengl"]
|
||||
|
||||
[dependencies.iced_profiling]
|
||||
version = "0.1.0"
|
||||
path = "../profiling"
|
||||
optional = true
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ use iced_winit::{Clipboard, Command, Debug, Proxy, Settings};
|
|||
use glutin::window::Window;
|
||||
use std::mem::ManuallyDrop;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use iced_profiling::{info_span, instrument::Instrument};
|
||||
|
||||
/// Runs an [`Application`] with an executor, compositor, and the provided
|
||||
/// settings.
|
||||
pub fn run<A, E, C>(
|
||||
|
|
@ -35,9 +38,15 @@ where
|
|||
use glutin::platform::run_return::EventLoopExtRunReturn;
|
||||
use glutin::ContextBuilder;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let _guard = iced_profiling::init();
|
||||
|
||||
let mut debug = Debug::new();
|
||||
debug.startup_started();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Application::Glutin", "RUN").entered();
|
||||
|
||||
let mut event_loop = EventLoopBuilder::with_user_event().build();
|
||||
let proxy = event_loop.create_proxy();
|
||||
|
||||
|
|
@ -124,18 +133,26 @@ where
|
|||
|
||||
let (mut sender, receiver) = mpsc::unbounded();
|
||||
|
||||
let mut instance = Box::pin(run_instance::<A, E, C>(
|
||||
application,
|
||||
compositor,
|
||||
renderer,
|
||||
runtime,
|
||||
proxy,
|
||||
debug,
|
||||
receiver,
|
||||
context,
|
||||
init_command,
|
||||
settings.exit_on_close_request,
|
||||
));
|
||||
let mut instance = Box::pin({
|
||||
let run_instance = run_instance::<A, E, C>(
|
||||
application,
|
||||
compositor,
|
||||
renderer,
|
||||
runtime,
|
||||
proxy,
|
||||
debug,
|
||||
receiver,
|
||||
context,
|
||||
init_command,
|
||||
settings.exit_on_close_request,
|
||||
);
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let run_instance =
|
||||
run_instance.instrument(info_span!("Application", "LOOP"));
|
||||
|
||||
run_instance
|
||||
});
|
||||
|
||||
let mut context = task::Context::from_waker(task::noop_waker_ref());
|
||||
|
||||
|
|
@ -333,6 +350,9 @@ async fn run_instance<A, E, C>(
|
|||
messages.push(message);
|
||||
}
|
||||
event::Event::RedrawRequested(_) => {
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Application", "FRAME").entered();
|
||||
|
||||
debug.render_started();
|
||||
|
||||
#[allow(unsafe_code)]
|
||||
|
|
|
|||
15
profiling/Cargo.toml
Normal file
15
profiling/Cargo.toml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
[package]
|
||||
name = "iced_profiling"
|
||||
authors = ["Bingus <shankern@protonmail.com>"]
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
description = "Profiling backend implementations for Iced"
|
||||
|
||||
[dependencies]
|
||||
tracing = { version = "0.1.37", default-features = false, features = ["std"] }
|
||||
tracing-core = "0.1.30"
|
||||
tracing-subscriber = { version = "0.3.16", features = ["registry", "env-filter"] }
|
||||
|
||||
[dependencies.tracing-chrome]
|
||||
version = "0.7.0"
|
||||
optional = true
|
||||
61
profiling/README.md
Normal file
61
profiling/README.md
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# `iced_profiling`
|
||||
[]
|
||||
[](https://crates.io/crates/iced_profiling)
|
||||
[](https://github.com/iced-rs/iced/blob/master/LICENSE)
|
||||
[](https://discord.gg/3xZJ65GAhd)
|
||||
|
||||
`iced_profiling` is a crate which implements various tracing backends for Iced.
|
||||
|
||||
It relies on the [tracing](https://crates.io/crates/tracing) crate to collect diagnostics. We currently only support
|
||||
tracing with `tracing`'s `info_span!` macro, but will consider different logging levels in the future. PRs welcome!
|
||||
|
||||
## Trace backends
|
||||
|
||||
We currently support only Chrome JSON traces using the [tracing-chrome](https://crates.io/crates/tracing-chrome) crate.
|
||||
|
||||
There are plans to add support for [Tracy](https://github.com/wolfpld/tracy) in the near future!
|
||||
|
||||
## Generating a trace file
|
||||
|
||||
### Using Iced's `Application`
|
||||
|
||||
Simply enable your tracing backend of choice (e.g. `trace_chrome`) feature in Iced & run your project.
|
||||
|
||||
```shell
|
||||
cargo run --features iced/trace_chrome
|
||||
```
|
||||
### Standalone dependency
|
||||
|
||||
You can enable tracing by enabling your tracing backend of choice as a feature of `iced_profiling`.
|
||||
|
||||
```toml
|
||||
iced_profiling = { version = "0.1.0", features = ["tracing-chrome"]}
|
||||
```
|
||||
|
||||
Doing so will require you to initialize the profiler manually like so:
|
||||
|
||||
```rust
|
||||
let _guard = iced_profiling::init();
|
||||
```
|
||||
|
||||
This reference must be kept alive for the entire duration of your application that you wish to profile.
|
||||
|
||||
## Chrome
|
||||
|
||||
By default, Chrome trace files will be generated in the current working directory:
|
||||
```shell
|
||||
path/to/your/project/project_trace_{timestamp}.json
|
||||
```
|
||||
|
||||
You also set a specific path by setting the `CHROME_TRACE_FILE` env variable:
|
||||
```shell
|
||||
CHROME_TRACE_FILE = ~/Desktop/trace.json cargo run
|
||||
```
|
||||
|
||||
If you cannot find your trace file, there may have been a permission issue when trying to generate your file. Be sure to check your cargo manifest directory!
|
||||
|
||||
Once your file is generated, you can view it in Google Chrome at either [ui.perfetto.dev](ui.perfetto.dev) (new) or [chrome://trace](chrome://trace) (old).
|
||||
|
||||
<p align="center">
|
||||
<img alt="The native target" src="../docs/images/perfetto.png" width="80%">
|
||||
</p>
|
||||
100
profiling/src/lib.rs
Normal file
100
profiling/src/lib.rs
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
use std::time::Duration;
|
||||
use tracing_subscriber::prelude::*;
|
||||
use tracing_subscriber::Registry;
|
||||
|
||||
#[cfg(feature = "tracing-chrome")]
|
||||
use {
|
||||
tracing_chrome::FlushGuard,
|
||||
tracing_subscriber::fmt::{format::DefaultFields, FormattedFields},
|
||||
};
|
||||
|
||||
pub use tracing::{info_span, instrument};
|
||||
|
||||
/// Profiler state. This will likely need to be updated or reworked when adding new tracing backends.
|
||||
pub struct Profiler {
|
||||
#[cfg(feature = "tracing-chrome")]
|
||||
/// [`FlushGuard`] must not be dropped until the application scope is dropped for accurate tracing.
|
||||
_guard: FlushGuard,
|
||||
}
|
||||
|
||||
pub fn init() -> Profiler {
|
||||
// Registry stores the spans & generates unique span IDs
|
||||
let subscriber = Registry::default();
|
||||
|
||||
#[cfg(feature = "tracing-chrome")]
|
||||
let (chrome_layer, guard) = {
|
||||
let mut layer = tracing_chrome::ChromeLayerBuilder::new();
|
||||
|
||||
// Optional configurable env var: CHROME_TRACE_FILE=/path/to/trace_file/file.json,
|
||||
// for uploading to chrome://tracing (old) or ui.perfetto.dev (new).
|
||||
if let Ok(path) = std::env::var("CHROME_TRACE_FILE") {
|
||||
layer = layer.file(path);
|
||||
} else if let Ok(current_dir) = std::env::current_dir() {
|
||||
let time = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap_or(Duration::from_millis(0))
|
||||
.as_millis();
|
||||
|
||||
let trace_file_name = current_dir
|
||||
.file_name()
|
||||
.map(|file_dir| {
|
||||
format!(
|
||||
"{}_trace_{}.json",
|
||||
file_dir.to_str().unwrap_or("trace"),
|
||||
time
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| "trace.json".to_string());
|
||||
|
||||
let path = format!(
|
||||
"{}/{}",
|
||||
current_dir.to_str().expect("Invalid path"),
|
||||
trace_file_name
|
||||
);
|
||||
|
||||
layer = layer.file(path);
|
||||
} else {
|
||||
layer = layer.file(env!("CARGO_MANIFEST_DIR"))
|
||||
}
|
||||
|
||||
let (chrome_layer, guard) = layer
|
||||
.name_fn(Box::new(|event_or_span| match event_or_span {
|
||||
tracing_chrome::EventOrSpan::Event(event) => {
|
||||
event.metadata().name().into()
|
||||
}
|
||||
tracing_chrome::EventOrSpan::Span(span) => {
|
||||
if let Some(fields) = span
|
||||
.extensions()
|
||||
.get::<FormattedFields<DefaultFields>>()
|
||||
{
|
||||
format!(
|
||||
"{}: {}",
|
||||
span.metadata().name(),
|
||||
fields.fields.as_str()
|
||||
)
|
||||
} else {
|
||||
span.metadata().name().into()
|
||||
}
|
||||
}
|
||||
}))
|
||||
.build();
|
||||
|
||||
(chrome_layer, guard)
|
||||
};
|
||||
|
||||
let fmt_layer = tracing_subscriber::fmt::Layer::default();
|
||||
let subscriber = subscriber.with(fmt_layer);
|
||||
|
||||
#[cfg(feature = "tracing-chrome")]
|
||||
let subscriber = subscriber.with(chrome_layer);
|
||||
|
||||
// create dispatcher which will forward span events to the subscriber
|
||||
// this can only be set once or will panic
|
||||
tracing::subscriber::set_global_default(subscriber)
|
||||
.expect("Profiler could not set the global default subscriber.");
|
||||
|
||||
Profiler {
|
||||
#[cfg(feature = "tracing-chrome")]
|
||||
_guard: guard,
|
||||
}
|
||||
}
|
||||
|
|
@ -8,24 +8,25 @@ license = "MIT AND OFL-1.1"
|
|||
repository = "https://github.com/iced-rs/iced"
|
||||
|
||||
[features]
|
||||
svg = ["iced_graphics/svg"]
|
||||
bmp = ["iced_graphics/bmp"]
|
||||
canvas = ["iced_graphics/canvas"]
|
||||
dds = ["iced_graphics/dds"]
|
||||
default_system_font = ["iced_graphics/font-source"]
|
||||
farbfeld = ["iced_graphics/farbfeld"]
|
||||
gif = ["iced_graphics/gif"]
|
||||
hdr = ["iced_graphics/hdr"]
|
||||
ico = ["iced_graphics/ico"]
|
||||
image = ["iced_graphics/image"]
|
||||
png = ["iced_graphics/png"]
|
||||
jpeg = ["iced_graphics/jpeg"]
|
||||
jpeg_rayon = ["iced_graphics/jpeg_rayon"]
|
||||
gif = ["iced_graphics/gif"]
|
||||
webp = ["iced_graphics/webp"]
|
||||
png = ["iced_graphics/png"]
|
||||
pnm = ["iced_graphics/pnm"]
|
||||
ico = ["iced_graphics/ico"]
|
||||
bmp = ["iced_graphics/bmp"]
|
||||
hdr = ["iced_graphics/hdr"]
|
||||
dds = ["iced_graphics/dds"]
|
||||
farbfeld = ["iced_graphics/farbfeld"]
|
||||
canvas = ["iced_graphics/canvas"]
|
||||
qr_code = ["iced_graphics/qr_code"]
|
||||
default_system_font = ["iced_graphics/font-source"]
|
||||
spirv = ["wgpu/spirv"]
|
||||
svg = ["iced_graphics/svg"]
|
||||
trace = ["iced_profiling"]
|
||||
webgl = ["wgpu/webgl"]
|
||||
webp = ["iced_graphics/webp"]
|
||||
|
||||
[dependencies]
|
||||
wgpu = "0.14"
|
||||
|
|
@ -50,6 +51,11 @@ version = "0.5"
|
|||
path = "../graphics"
|
||||
features = ["font-fallback", "font-icons"]
|
||||
|
||||
[dependencies.iced_profiling]
|
||||
version = "0.1.0"
|
||||
path = "../profiling"
|
||||
optional = true
|
||||
|
||||
[dependencies.encase]
|
||||
version = "0.3.0"
|
||||
features = ["glam"]
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ use iced_graphics::{Primitive, Viewport};
|
|||
use iced_native::alignment;
|
||||
use iced_native::{Font, Size};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use iced_profiling::info_span;
|
||||
|
||||
#[cfg(any(feature = "image", feature = "svg"))]
|
||||
use crate::image;
|
||||
|
||||
|
|
@ -77,6 +80,8 @@ impl Backend {
|
|||
overlay_text: &[T],
|
||||
) {
|
||||
log::debug!("Drawing");
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Wgpu::Backend", "PRESENT").entered();
|
||||
|
||||
let target_size = viewport.physical_size();
|
||||
let scale_factor = viewport.scale_factor() as f32;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ use iced_native::image;
|
|||
#[cfg(feature = "svg")]
|
||||
use iced_native::svg;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use iced_profiling::info_span;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Pipeline {
|
||||
#[cfg(feature = "image")]
|
||||
|
|
@ -289,6 +292,9 @@ impl Pipeline {
|
|||
target: &wgpu::TextureView,
|
||||
_scale: f32,
|
||||
) {
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Wgpu::Image", "DRAW").entered();
|
||||
|
||||
let instances: &mut Vec<Instance> = &mut Vec::new();
|
||||
|
||||
#[cfg(feature = "image")]
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ use bytemuck::{Pod, Zeroable};
|
|||
use std::mem;
|
||||
use wgpu::util::DeviceExt;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use iced_profiling::info_span;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Pipeline {
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
|
|
@ -173,6 +176,9 @@ impl Pipeline {
|
|||
bounds: Rectangle<u32>,
|
||||
target: &wgpu::TextureView,
|
||||
) {
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Wgpu::Quad", "DRAW").entered();
|
||||
|
||||
let uniforms = Uniforms::new(transformation, scale);
|
||||
|
||||
{
|
||||
|
|
@ -207,6 +213,9 @@ impl Pipeline {
|
|||
|
||||
instance_buffer.copy_from_slice(instance_bytes);
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Wgpu::Quad", "BEGIN_RENDER_PASS").enter();
|
||||
|
||||
{
|
||||
let mut render_pass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ use crate::Transformation;
|
|||
use iced_graphics::layer::mesh::{self, Mesh};
|
||||
use iced_graphics::triangle::ColoredVertex2D;
|
||||
use iced_graphics::Size;
|
||||
#[cfg(feature = "trace")]
|
||||
use iced_profiling::info_span;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Pipeline {
|
||||
|
|
@ -53,6 +55,9 @@ impl Pipeline {
|
|||
scale_factor: f32,
|
||||
meshes: &[Mesh<'_>],
|
||||
) {
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Wgpu::Triangle", "DRAW").entered();
|
||||
|
||||
// Count the total amount of vertices & indices we need to handle
|
||||
let count = mesh::attribute_count_of(meshes);
|
||||
|
||||
|
|
@ -247,6 +252,9 @@ impl Pipeline {
|
|||
(target, None, wgpu::LoadOp::Load)
|
||||
};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Wgpu::Triangle", "BEGIN_RENDER_PASS").enter();
|
||||
|
||||
let mut render_pass =
|
||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("iced_wgpu::triangle render pass"),
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ keywords = ["gui", "ui", "graphics", "interface", "widgets"]
|
|||
categories = ["gui"]
|
||||
|
||||
[features]
|
||||
trace = ["iced_profiling"]
|
||||
debug = ["iced_native/debug"]
|
||||
system = ["sysinfo"]
|
||||
application = []
|
||||
|
|
@ -37,6 +38,11 @@ path = "../graphics"
|
|||
version = "0.5"
|
||||
path = "../futures"
|
||||
|
||||
[dependencies.iced_profiling]
|
||||
version = "0.1.0"
|
||||
path = "../profiling"
|
||||
optional = true
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies.winapi]
|
||||
version = "0.3.6"
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,9 @@ pub use iced_native::application::{Appearance, StyleSheet};
|
|||
|
||||
use std::mem::ManuallyDrop;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use iced_profiling::{info_span, instrument::Instrument};
|
||||
|
||||
/// An interactive, native cross-platform application.
|
||||
///
|
||||
/// This trait is the main entrypoint of Iced. Once implemented, you can run
|
||||
|
|
@ -111,9 +114,15 @@ where
|
|||
use futures::Future;
|
||||
use winit::event_loop::EventLoopBuilder;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let _guard = iced_profiling::init();
|
||||
|
||||
let mut debug = Debug::new();
|
||||
debug.startup_started();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Application", "RUN").entered();
|
||||
|
||||
let event_loop = EventLoopBuilder::with_user_event().build();
|
||||
let proxy = event_loop.create_proxy();
|
||||
|
||||
|
|
@ -175,18 +184,26 @@ where
|
|||
|
||||
let (mut sender, receiver) = mpsc::unbounded();
|
||||
|
||||
let mut instance = Box::pin(run_instance::<A, E, C>(
|
||||
application,
|
||||
compositor,
|
||||
renderer,
|
||||
runtime,
|
||||
proxy,
|
||||
debug,
|
||||
receiver,
|
||||
init_command,
|
||||
window,
|
||||
settings.exit_on_close_request,
|
||||
));
|
||||
let mut instance = Box::pin({
|
||||
let run_instance = run_instance::<A, E, C>(
|
||||
application,
|
||||
compositor,
|
||||
renderer,
|
||||
runtime,
|
||||
proxy,
|
||||
debug,
|
||||
receiver,
|
||||
init_command,
|
||||
window,
|
||||
settings.exit_on_close_request,
|
||||
);
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let run_instance =
|
||||
run_instance.instrument(info_span!("Application", "LOOP"));
|
||||
|
||||
run_instance
|
||||
});
|
||||
|
||||
let mut context = task::Context::from_waker(task::noop_waker_ref());
|
||||
|
||||
|
|
@ -391,6 +408,9 @@ async fn run_instance<A, E, C>(
|
|||
messages.push(message);
|
||||
}
|
||||
event::Event::RedrawRequested(_) => {
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = info_span!("Application", "FRAME").entered();
|
||||
|
||||
let physical_size = state.physical_size();
|
||||
|
||||
if physical_size.width == 0 || physical_size.height == 0 {
|
||||
|
|
@ -529,12 +549,24 @@ pub fn build_user_interface<'a, A: Application>(
|
|||
where
|
||||
<A::Renderer as crate::Renderer>::Theme: StyleSheet,
|
||||
{
|
||||
#[cfg(feature = "trace")]
|
||||
let view_span = info_span!("Application", "VIEW").entered();
|
||||
|
||||
debug.view_started();
|
||||
let view = application.view();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = view_span.exit();
|
||||
debug.view_finished();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let layout_span = info_span!("Application", "LAYOUT").entered();
|
||||
|
||||
debug.layout_started();
|
||||
let user_interface = UserInterface::build(view, size, cache, renderer);
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = layout_span.exit();
|
||||
debug.layout_finished();
|
||||
|
||||
user_interface
|
||||
|
|
@ -559,10 +591,16 @@ pub fn update<A: Application, E: Executor>(
|
|||
<A::Renderer as crate::Renderer>::Theme: StyleSheet,
|
||||
{
|
||||
for message in messages.drain(..) {
|
||||
#[cfg(feature = "trace")]
|
||||
let update_span = info_span!("Application", "UPDATE").entered();
|
||||
|
||||
debug.log_message(&message);
|
||||
|
||||
debug.update_started();
|
||||
let command = runtime.enter(|| application.update(message));
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let _ = update_span.exit();
|
||||
debug.update_finished();
|
||||
|
||||
run_command(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue