Restructured everything to make profiling a feature of iced_winit.
This commit is contained in:
parent
c5cd236b73
commit
4b6d3797d4
23 changed files with 184 additions and 254 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,3 +4,4 @@ pkg/
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
.cargo/
|
.cargo/
|
||||||
dist/
|
dist/
|
||||||
|
traces/
|
||||||
13
Cargo.toml
13
Cargo.toml
|
|
@ -39,13 +39,12 @@ smol = ["iced_futures/smol"]
|
||||||
palette = ["iced_core/palette"]
|
palette = ["iced_core/palette"]
|
||||||
# Enables querying system information
|
# Enables querying system information
|
||||||
system = ["iced_winit/system"]
|
system = ["iced_winit/system"]
|
||||||
# Enables tracing with Chrome
|
# Enables chrome traces
|
||||||
trace_chrome = [
|
chrome-trace = [
|
||||||
"iced_winit/trace",
|
"iced_winit/chrome-trace",
|
||||||
"iced_wgpu?/trace",
|
|
||||||
"iced_glow?/trace",
|
|
||||||
"iced_glutin?/trace",
|
"iced_glutin?/trace",
|
||||||
"iced_profiling/tracing-chrome"
|
"iced_wgpu?/tracing",
|
||||||
|
"iced_glow?/tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[badges]
|
[badges]
|
||||||
|
|
@ -59,7 +58,6 @@ members = [
|
||||||
"glow",
|
"glow",
|
||||||
"glutin",
|
"glutin",
|
||||||
"lazy",
|
"lazy",
|
||||||
"profiling",
|
|
||||||
"native",
|
"native",
|
||||||
"style",
|
"style",
|
||||||
"wgpu",
|
"wgpu",
|
||||||
|
|
@ -75,7 +73,6 @@ iced_graphics = { version = "0.5", path = "graphics" }
|
||||||
iced_winit = { version = "0.6", path = "winit", features = ["application"] }
|
iced_winit = { version = "0.6", path = "winit", features = ["application"] }
|
||||||
iced_glutin = { version = "0.5", path = "glutin", optional = true }
|
iced_glutin = { version = "0.5", path = "glutin", optional = true }
|
||||||
iced_glow = { version = "0.5", path = "glow", optional = true }
|
iced_glow = { version = "0.5", path = "glow", optional = true }
|
||||||
iced_profiling = { version = "0.1.0", path = "profiling", optional = true }
|
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
[dependencies.image_rs]
|
[dependencies.image_rs]
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.5 MiB |
|
|
@ -8,7 +8,6 @@ publish = false
|
||||||
[dependencies]
|
[dependencies]
|
||||||
iced_winit = { path = "../../winit" }
|
iced_winit = { path = "../../winit" }
|
||||||
iced_wgpu = { path = "../../wgpu", features = ["webgl"] }
|
iced_wgpu = { path = "../../wgpu", features = ["webgl"] }
|
||||||
iced_profiling = { path = "../../profiling", features = ["tracing-chrome"]}
|
|
||||||
env_logger = "0.8"
|
env_logger = "0.8"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,6 @@ use winit::{
|
||||||
event_loop::{ControlFlow, EventLoop},
|
event_loop::{ControlFlow, EventLoop},
|
||||||
};
|
};
|
||||||
|
|
||||||
use iced_profiling::info_span;
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
|
|
@ -41,9 +39,6 @@ pub fn main() {
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
// Initialize tracing
|
|
||||||
let _guard = iced_profiling::init();
|
|
||||||
|
|
||||||
// Initialize winit
|
// Initialize winit
|
||||||
let event_loop = EventLoop::new();
|
let event_loop = EventLoop::new();
|
||||||
|
|
||||||
|
|
@ -203,8 +198,6 @@ pub fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::RedrawRequested(_) => {
|
Event::RedrawRequested(_) => {
|
||||||
let _ = info_span!("Integration_WGPU", "DRAW").entered();
|
|
||||||
|
|
||||||
if resized {
|
if resized {
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ license = "MIT AND OFL-1.1"
|
||||||
repository = "https://github.com/iced-rs/iced"
|
repository = "https://github.com/iced-rs/iced"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
trace = ["iced_profiling"]
|
|
||||||
svg = ["iced_graphics/svg"]
|
svg = ["iced_graphics/svg"]
|
||||||
image = ["iced_graphics/image"]
|
image = ["iced_graphics/image"]
|
||||||
png = ["iced_graphics/png"]
|
png = ["iced_graphics/png"]
|
||||||
|
|
@ -43,9 +42,8 @@ version = "0.5"
|
||||||
path = "../graphics"
|
path = "../graphics"
|
||||||
features = ["font-fallback", "font-icons", "opengl"]
|
features = ["font-fallback", "font-icons", "opengl"]
|
||||||
|
|
||||||
[dependencies.iced_profiling]
|
[dependencies.tracing]
|
||||||
version = "0.1.0"
|
version = "0.1.6"
|
||||||
path = "../profiling"
|
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ use glow::HasContext;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
use iced_profiling::info_span;
|
use tracing::info_span;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Pipeline {
|
pub(crate) struct Pipeline {
|
||||||
|
|
@ -151,7 +151,7 @@ impl Pipeline {
|
||||||
images: &[layer::Image],
|
images: &[layer::Image],
|
||||||
layer_bounds: Rectangle<u32>,
|
layer_bounds: Rectangle<u32>,
|
||||||
) {
|
) {
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Glow::Image", "DRAW").entered();
|
let _ = info_span!("Glow::Image", "DRAW").entered();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ use glow::HasContext;
|
||||||
use iced_graphics::layer;
|
use iced_graphics::layer;
|
||||||
use iced_native::Rectangle;
|
use iced_native::Rectangle;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
use iced_profiling::info_span;
|
use tracing::info_span;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Pipeline {
|
pub enum Pipeline {
|
||||||
|
|
@ -45,7 +45,7 @@ impl Pipeline {
|
||||||
scale: f32,
|
scale: f32,
|
||||||
bounds: Rectangle<u32>,
|
bounds: Rectangle<u32>,
|
||||||
) {
|
) {
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Glow::Quad", "DRAW").enter();
|
let _ = info_span!("Glow::Quad", "DRAW").enter();
|
||||||
|
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ use iced_graphics::triangle::{ColoredVertex2D, Vertex2D};
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
use iced_profiling::info_span;
|
use tracing::info_span;
|
||||||
|
|
||||||
const DEFAULT_VERTICES: usize = 1_000;
|
const DEFAULT_VERTICES: usize = 1_000;
|
||||||
const DEFAULT_INDICES: usize = 1_000;
|
const DEFAULT_INDICES: usize = 1_000;
|
||||||
|
|
@ -61,7 +61,7 @@ impl Pipeline {
|
||||||
transformation: Transformation,
|
transformation: Transformation,
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
) {
|
) {
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Glow::Triangle", "DRAW").enter();
|
let _ = info_span!("Glow::Triangle", "DRAW").enter();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ keywords = ["gui", "ui", "graphics", "interface", "widgets"]
|
||||||
categories = ["gui"]
|
categories = ["gui"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
trace = ["iced_profiling/tracing-chrome"]
|
trace = ["iced_winit/trace"]
|
||||||
debug = ["iced_winit/debug"]
|
debug = ["iced_winit/debug"]
|
||||||
system = ["iced_winit/system"]
|
system = ["iced_winit/system"]
|
||||||
|
|
||||||
|
|
@ -37,7 +37,6 @@ version = "0.5"
|
||||||
path = "../graphics"
|
path = "../graphics"
|
||||||
features = ["opengl"]
|
features = ["opengl"]
|
||||||
|
|
||||||
[dependencies.iced_profiling]
|
[dependencies.tracing]
|
||||||
version = "0.1.0"
|
version = "0.1.6"
|
||||||
path = "../profiling"
|
optional = true
|
||||||
optional = true
|
|
||||||
|
|
@ -17,8 +17,8 @@ use iced_winit::{Clipboard, Command, Debug, Proxy, Settings};
|
||||||
use glutin::window::Window;
|
use glutin::window::Window;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
use iced_profiling::{info_span, instrument::Instrument};
|
use tracing::{info_span, instrument::Instrument};
|
||||||
|
|
||||||
/// Runs an [`Application`] with an executor, compositor, and the provided
|
/// Runs an [`Application`] with an executor, compositor, and the provided
|
||||||
/// settings.
|
/// settings.
|
||||||
|
|
@ -39,12 +39,12 @@ where
|
||||||
use glutin::ContextBuilder;
|
use glutin::ContextBuilder;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
let _guard = iced_profiling::init();
|
let _guard = iced_winit::Profiler::init();
|
||||||
|
|
||||||
let mut debug = Debug::new();
|
let mut debug = Debug::new();
|
||||||
debug.startup_started();
|
debug.startup_started();
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Application::Glutin", "RUN").entered();
|
let _ = info_span!("Application::Glutin", "RUN").entered();
|
||||||
|
|
||||||
let mut event_loop = EventLoopBuilder::with_user_event().build();
|
let mut event_loop = EventLoopBuilder::with_user_event().build();
|
||||||
|
|
@ -147,7 +147,7 @@ where
|
||||||
settings.exit_on_close_request,
|
settings.exit_on_close_request,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let run_instance =
|
let run_instance =
|
||||||
run_instance.instrument(info_span!("Application", "LOOP"));
|
run_instance.instrument(info_span!("Application", "LOOP"));
|
||||||
|
|
||||||
|
|
@ -350,7 +350,7 @@ async fn run_instance<A, E, C>(
|
||||||
messages.push(message);
|
messages.push(message);
|
||||||
}
|
}
|
||||||
event::Event::RedrawRequested(_) => {
|
event::Event::RedrawRequested(_) => {
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Application", "FRAME").entered();
|
let _ = info_span!("Application", "FRAME").entered();
|
||||||
|
|
||||||
debug.render_started();
|
debug.render_started();
|
||||||
|
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
[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
|
|
||||||
|
|
@ -1,61 +0,0 @@
|
||||||
# `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>
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
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,25 +8,24 @@ license = "MIT AND OFL-1.1"
|
||||||
repository = "https://github.com/iced-rs/iced"
|
repository = "https://github.com/iced-rs/iced"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
bmp = ["iced_graphics/bmp"]
|
svg = ["iced_graphics/svg"]
|
||||||
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"]
|
image = ["iced_graphics/image"]
|
||||||
|
png = ["iced_graphics/png"]
|
||||||
jpeg = ["iced_graphics/jpeg"]
|
jpeg = ["iced_graphics/jpeg"]
|
||||||
jpeg_rayon = ["iced_graphics/jpeg_rayon"]
|
jpeg_rayon = ["iced_graphics/jpeg_rayon"]
|
||||||
png = ["iced_graphics/png"]
|
gif = ["iced_graphics/gif"]
|
||||||
pnm = ["iced_graphics/pnm"]
|
|
||||||
qr_code = ["iced_graphics/qr_code"]
|
|
||||||
spirv = ["wgpu/spirv"]
|
|
||||||
svg = ["iced_graphics/svg"]
|
|
||||||
trace = ["iced_profiling"]
|
|
||||||
webgl = ["wgpu/webgl"]
|
|
||||||
webp = ["iced_graphics/webp"]
|
webp = ["iced_graphics/webp"]
|
||||||
|
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"]
|
||||||
|
webgl = ["wgpu/webgl"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
wgpu = "0.14"
|
wgpu = "0.14"
|
||||||
|
|
@ -51,9 +50,8 @@ version = "0.5"
|
||||||
path = "../graphics"
|
path = "../graphics"
|
||||||
features = ["font-fallback", "font-icons"]
|
features = ["font-fallback", "font-icons"]
|
||||||
|
|
||||||
[dependencies.iced_profiling]
|
[dependencies.tracing]
|
||||||
version = "0.1.0"
|
version = "0.1.6"
|
||||||
path = "../profiling"
|
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[dependencies.encase]
|
[dependencies.encase]
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ use iced_graphics::{Primitive, Viewport};
|
||||||
use iced_native::alignment;
|
use iced_native::alignment;
|
||||||
use iced_native::{Font, Size};
|
use iced_native::{Font, Size};
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
use iced_profiling::info_span;
|
use tracing::info_span;
|
||||||
|
|
||||||
#[cfg(any(feature = "image", feature = "svg"))]
|
#[cfg(any(feature = "image", feature = "svg"))]
|
||||||
use crate::image;
|
use crate::image;
|
||||||
|
|
@ -80,7 +80,7 @@ impl Backend {
|
||||||
overlay_text: &[T],
|
overlay_text: &[T],
|
||||||
) {
|
) {
|
||||||
log::debug!("Drawing");
|
log::debug!("Drawing");
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Wgpu::Backend", "PRESENT").entered();
|
let _ = info_span!("Wgpu::Backend", "PRESENT").entered();
|
||||||
|
|
||||||
let target_size = viewport.physical_size();
|
let target_size = viewport.physical_size();
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ use iced_native::image;
|
||||||
#[cfg(feature = "svg")]
|
#[cfg(feature = "svg")]
|
||||||
use iced_native::svg;
|
use iced_native::svg;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
use iced_profiling::info_span;
|
use tracing::info_span;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Pipeline {
|
pub struct Pipeline {
|
||||||
|
|
@ -292,7 +292,7 @@ impl Pipeline {
|
||||||
target: &wgpu::TextureView,
|
target: &wgpu::TextureView,
|
||||||
_scale: f32,
|
_scale: f32,
|
||||||
) {
|
) {
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Wgpu::Image", "DRAW").entered();
|
let _ = info_span!("Wgpu::Image", "DRAW").entered();
|
||||||
|
|
||||||
let instances: &mut Vec<Instance> = &mut Vec::new();
|
let instances: &mut Vec<Instance> = &mut Vec::new();
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ use bytemuck::{Pod, Zeroable};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use wgpu::util::DeviceExt;
|
use wgpu::util::DeviceExt;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
use iced_profiling::info_span;
|
use tracing::info_span;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Pipeline {
|
pub struct Pipeline {
|
||||||
|
|
@ -176,7 +176,7 @@ impl Pipeline {
|
||||||
bounds: Rectangle<u32>,
|
bounds: Rectangle<u32>,
|
||||||
target: &wgpu::TextureView,
|
target: &wgpu::TextureView,
|
||||||
) {
|
) {
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Wgpu::Quad", "DRAW").entered();
|
let _ = info_span!("Wgpu::Quad", "DRAW").entered();
|
||||||
|
|
||||||
let uniforms = Uniforms::new(transformation, scale);
|
let uniforms = Uniforms::new(transformation, scale);
|
||||||
|
|
@ -213,7 +213,7 @@ impl Pipeline {
|
||||||
|
|
||||||
instance_buffer.copy_from_slice(instance_bytes);
|
instance_buffer.copy_from_slice(instance_bytes);
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Wgpu::Quad", "BEGIN_RENDER_PASS").enter();
|
let _ = info_span!("Wgpu::Quad", "BEGIN_RENDER_PASS").enter();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@ use crate::Transformation;
|
||||||
use iced_graphics::layer::mesh::{self, Mesh};
|
use iced_graphics::layer::mesh::{self, Mesh};
|
||||||
use iced_graphics::triangle::ColoredVertex2D;
|
use iced_graphics::triangle::ColoredVertex2D;
|
||||||
use iced_graphics::Size;
|
use iced_graphics::Size;
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
use iced_profiling::info_span;
|
use tracing::info_span;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Pipeline {
|
pub struct Pipeline {
|
||||||
|
|
@ -55,7 +55,7 @@ impl Pipeline {
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
meshes: &[Mesh<'_>],
|
meshes: &[Mesh<'_>],
|
||||||
) {
|
) {
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Wgpu::Triangle", "DRAW").entered();
|
let _ = info_span!("Wgpu::Triangle", "DRAW").entered();
|
||||||
|
|
||||||
// Count the total amount of vertices & indices we need to handle
|
// Count the total amount of vertices & indices we need to handle
|
||||||
|
|
@ -252,7 +252,7 @@ impl Pipeline {
|
||||||
(target, None, wgpu::LoadOp::Load)
|
(target, None, wgpu::LoadOp::Load)
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "tracing")]
|
||||||
let _ = info_span!("Wgpu::Triangle", "BEGIN_RENDER_PASS").enter();
|
let _ = info_span!("Wgpu::Triangle", "BEGIN_RENDER_PASS").enter();
|
||||||
|
|
||||||
let mut render_pass =
|
let mut render_pass =
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@ keywords = ["gui", "ui", "graphics", "interface", "widgets"]
|
||||||
categories = ["gui"]
|
categories = ["gui"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
trace = ["iced_profiling"]
|
trace = ["tracing", "tracing-core", "tracing-subscriber"]
|
||||||
|
chrome-trace = ["trace", "tracing-chrome"]
|
||||||
debug = ["iced_native/debug"]
|
debug = ["iced_native/debug"]
|
||||||
system = ["sysinfo"]
|
system = ["sysinfo"]
|
||||||
application = []
|
application = []
|
||||||
|
|
@ -38,9 +39,22 @@ path = "../graphics"
|
||||||
version = "0.5"
|
version = "0.5"
|
||||||
path = "../futures"
|
path = "../futures"
|
||||||
|
|
||||||
[dependencies.iced_profiling]
|
[dependencies.tracing]
|
||||||
version = "0.1.0"
|
version = "0.1.37"
|
||||||
path = "../profiling"
|
optional = true
|
||||||
|
features = ["std"]
|
||||||
|
|
||||||
|
[dependencies.tracing-core]
|
||||||
|
version = "0.1.30"
|
||||||
|
optional = true
|
||||||
|
|
||||||
|
[dependencies.tracing-subscriber]
|
||||||
|
version = "0.3.16"
|
||||||
|
optional = true
|
||||||
|
features = ["registry"]
|
||||||
|
|
||||||
|
[dependencies.tracing-chrome]
|
||||||
|
version = "0.7.0"
|
||||||
optional = true
|
optional = true
|
||||||
|
|
||||||
[target.'cfg(target_os = "windows")'.dependencies.winapi]
|
[target.'cfg(target_os = "windows")'.dependencies.winapi]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
//! Create interactive, native cross-platform applications.
|
//! Create interactive, native cross-platform applications.
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
mod profiler;
|
||||||
mod state;
|
mod state;
|
||||||
|
|
||||||
pub use state::State;
|
pub use state::State;
|
||||||
|
|
@ -25,7 +27,9 @@ pub use iced_native::application::{Appearance, StyleSheet};
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
use iced_profiling::{info_span, instrument::Instrument};
|
pub use profiler::Profiler;
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
use tracing::{info_span, instrument::Instrument};
|
||||||
|
|
||||||
/// An interactive, native cross-platform application.
|
/// An interactive, native cross-platform application.
|
||||||
///
|
///
|
||||||
|
|
@ -115,7 +119,7 @@ where
|
||||||
use winit::event_loop::EventLoopBuilder;
|
use winit::event_loop::EventLoopBuilder;
|
||||||
|
|
||||||
#[cfg(feature = "trace")]
|
#[cfg(feature = "trace")]
|
||||||
let _guard = iced_profiling::init();
|
let _guard = Profiler::init();
|
||||||
|
|
||||||
let mut debug = Debug::new();
|
let mut debug = Debug::new();
|
||||||
debug.startup_started();
|
debug.startup_started();
|
||||||
|
|
|
||||||
101
winit/src/application/profiler.rs
Normal file
101
winit/src/application/profiler.rs
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
//! A simple profiler for Iced.
|
||||||
|
use std::ffi::OsStr;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::time::Duration;
|
||||||
|
use tracing_subscriber::prelude::*;
|
||||||
|
use tracing_subscriber::Registry;
|
||||||
|
#[cfg(feature = "chrome-trace")]
|
||||||
|
use {
|
||||||
|
tracing_chrome::FlushGuard,
|
||||||
|
tracing_subscriber::fmt::{format::DefaultFields, FormattedFields},
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Profiler state. This will likely need to be updated or reworked when adding new tracing backends.
|
||||||
|
#[allow(missing_debug_implementations)]
|
||||||
|
pub struct Profiler {
|
||||||
|
#[cfg(feature = "chrome-trace")]
|
||||||
|
/// [`FlushGuard`] must not be dropped until the application scope is dropped for accurate tracing.
|
||||||
|
_guard: FlushGuard,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Profiler {
|
||||||
|
/// Initializes the [`Profiler`].
|
||||||
|
pub fn init() -> Self {
|
||||||
|
// Registry stores the spans & generates unique span IDs
|
||||||
|
let subscriber = Registry::default();
|
||||||
|
|
||||||
|
let default_path = Path::new(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
let curr_exe = std::env::current_exe()
|
||||||
|
.unwrap_or_else(|_| default_path.to_path_buf());
|
||||||
|
let out_dir = curr_exe.parent().unwrap_or(default_path).join("traces");
|
||||||
|
|
||||||
|
#[cfg(feature = "chrome-trace")]
|
||||||
|
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 std::fs::create_dir_all(&out_dir).is_ok() {
|
||||||
|
let time = std::time::SystemTime::now()
|
||||||
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
|
.unwrap_or(Duration::from_millis(0))
|
||||||
|
.as_millis();
|
||||||
|
|
||||||
|
let curr_exe_name = curr_exe
|
||||||
|
.file_name()
|
||||||
|
.unwrap_or_else(|| OsStr::new("trace"))
|
||||||
|
.to_str()
|
||||||
|
.unwrap_or("trace");
|
||||||
|
|
||||||
|
let path = out_dir
|
||||||
|
.join(format!("{}_trace_{}.json", curr_exe_name, time));
|
||||||
|
|
||||||
|
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 = "chrome-trace")]
|
||||||
|
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("Tracer could not set the global default subscriber.");
|
||||||
|
|
||||||
|
Profiler {
|
||||||
|
#[cfg(feature = "chrome-trace")]
|
||||||
|
_guard: guard,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -51,6 +51,8 @@ mod proxy;
|
||||||
|
|
||||||
#[cfg(feature = "application")]
|
#[cfg(feature = "application")]
|
||||||
pub use application::Application;
|
pub use application::Application;
|
||||||
|
#[cfg(feature = "trace")]
|
||||||
|
pub use application::Profiler;
|
||||||
pub use clipboard::Clipboard;
|
pub use clipboard::Clipboard;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use position::Position;
|
pub use position::Position;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue