summaryrefslogtreecommitdiffstats
path: root/winit
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-11-03 04:39:11 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2019-11-03 04:39:11 +0100
commit2c6bfdbc8c2262c3550fa16d4472e29d73077956 (patch)
tree4428dea15c7ec8f9baa385927ce96264470d1915 /winit
parentef056d84890e745010675e70f734f882f89356c2 (diff)
downloadiced-2c6bfdbc8c2262c3550fa16d4472e29d73077956.tar.gz
iced-2c6bfdbc8c2262c3550fa16d4472e29d73077956.tar.bz2
iced-2c6bfdbc8c2262c3550fa16d4472e29d73077956.zip
Implement debug view and load system fonts
Diffstat (limited to 'winit')
-rw-r--r--winit/Cargo.toml3
-rw-r--r--winit/src/application.rs60
-rw-r--r--winit/src/debug/basic.rs206
-rw-r--r--winit/src/debug/null.rs48
-rw-r--r--winit/src/lib.rs11
5 files changed, 318 insertions, 10 deletions
diff --git a/winit/Cargo.toml b/winit/Cargo.toml
index c8227ac4..2831ba2f 100644
--- a/winit/Cargo.toml
+++ b/winit/Cargo.toml
@@ -7,6 +7,9 @@ description = "A winit runtime for Iced"
license = "MIT"
repository = "https://github.com/hecrj/iced"
+[features]
+debug = []
+
[dependencies]
iced_native = { version = "0.1.0-alpha", path = "../native" }
winit = { version = "0.20.0-alpha3", git = "https://github.com/rust-windowing/winit", rev = "709808eb4e69044705fcb214bcc30556db761405"}
diff --git a/winit/src/application.rs b/winit/src/application.rs
index 8c7d8c37..5d1aae38 100644
--- a/winit/src/application.rs
+++ b/winit/src/application.rs
@@ -2,13 +2,13 @@ use crate::{
column, conversion,
input::{keyboard, mouse},
renderer::{Target, Windowed},
- Cache, Column, Element, Event, Length, MouseCursor, UserInterface,
+ Cache, Column, Debug, Element, Event, Length, MouseCursor, UserInterface,
};
pub trait Application {
type Renderer: Windowed + column::Renderer;
- type Message;
+ type Message: std::fmt::Debug;
fn update(&mut self, message: Self::Message);
@@ -24,6 +24,9 @@ pub trait Application {
window::WindowBuilder,
};
+ let mut debug = Debug::new();
+
+ debug.startup_started();
let event_loop = EventLoop::new();
// TODO: Ask for window settings and configure this properly
@@ -50,16 +53,22 @@ pub trait Application {
&renderer,
);
+ debug.layout_started();
let user_interface = UserInterface::build(
- document(&mut self, size),
+ document(&mut self, size, &mut debug),
Cache::default(),
&renderer,
);
+ debug.layout_finished();
+ debug.draw_started();
let mut primitive = user_interface.draw(&mut renderer);
+ debug.draw_finished();
+
let mut cache = Some(user_interface.into_cache());
let mut events = Vec::new();
let mut mouse_cursor = MouseCursor::OutOfBounds;
+ debug.startup_finished();
window.request_redraw();
@@ -70,17 +79,23 @@ pub trait Application {
//
// This will allow us to rebuild it only when a message is
// handled.
+ debug.layout_started();
let mut user_interface = UserInterface::build(
- document(&mut self, size),
+ document(&mut self, size, &mut debug),
cache.take().unwrap(),
&renderer,
);
+ debug.layout_finished();
+ debug.event_processing_started();
let messages =
user_interface.update(&renderer, events.drain(..));
+ debug.event_processing_finished();
if messages.is_empty() {
+ debug.draw_started();
primitive = user_interface.draw(&mut renderer);
+ debug.draw_finished();
cache = Some(user_interface.into_cache());
} else {
@@ -91,16 +106,24 @@ pub trait Application {
for message in messages {
log::debug!("Updating");
+ debug.log_message(&message);
+
+ debug.update_started();
self.update(message);
+ debug.update_finished();
}
+ debug.layout_started();
let user_interface = UserInterface::build(
- document(&mut self, size),
+ document(&mut self, size, &mut debug),
temp_cache,
&renderer,
);
+ debug.layout_finished();
+ debug.draw_started();
primitive = user_interface.draw(&mut renderer);
+ debug.draw_finished();
cache = Some(user_interface.into_cache());
}
@@ -108,6 +131,8 @@ pub trait Application {
window.request_redraw();
}
event::Event::RedrawRequested(_) => {
+ debug.render_started();
+
if let Some(new_size) = new_size.take() {
target.resize(new_size.width, new_size.height, &renderer);
@@ -115,7 +140,9 @@ pub trait Application {
}
let new_mouse_cursor =
- renderer.draw(&primitive, None, &mut target);
+ renderer.draw(&primitive, &debug.overlay(), &mut target);
+
+ debug.render_finished();
if new_mouse_cursor != mouse_cursor {
window.set_cursor_icon(conversion::mouse_cursor(
@@ -191,6 +218,14 @@ pub trait Application {
},
..
} => {
+ match (virtual_keycode, state) {
+ (
+ winit::event::VirtualKeyCode::F12,
+ winit::event::ElementState::Pressed,
+ ) => debug.toggle(),
+ _ => {}
+ }
+
events.push(Event::Keyboard(keyboard::Event::Input {
key_code: conversion::key_code(virtual_keycode),
state: conversion::button_state(state),
@@ -229,17 +264,22 @@ impl From<winit::dpi::PhysicalSize> for Size {
}
}
-fn document<Application>(
- application: &mut Application,
+fn document<'a, Application>(
+ application: &'a mut Application,
size: Size,
-) -> Element<Application::Message, Application::Renderer>
+ debug: &mut Debug,
+) -> Element<'a, Application::Message, Application::Renderer>
where
Application: self::Application,
Application::Message: 'static,
{
+ debug.view_started();
+ let view = application.view();
+ debug.view_finished();
+
Column::new()
.width(Length::Units(size.width))
.height(Length::Units(size.height))
- .push(application.view())
+ .push(view)
.into()
}
diff --git a/winit/src/debug/basic.rs b/winit/src/debug/basic.rs
new file mode 100644
index 00000000..09bb5ae1
--- /dev/null
+++ b/winit/src/debug/basic.rs
@@ -0,0 +1,206 @@
+use std::collections::VecDeque;
+use std::time;
+
+#[derive(Debug)]
+pub struct Debug {
+ is_enabled: bool,
+
+ startup_start: time::Instant,
+ startup_duration: time::Duration,
+
+ update_start: time::Instant,
+ update_durations: TimeBuffer,
+
+ view_start: time::Instant,
+ view_durations: TimeBuffer,
+
+ layout_start: time::Instant,
+ layout_durations: TimeBuffer,
+
+ event_start: time::Instant,
+ event_durations: TimeBuffer,
+
+ draw_start: time::Instant,
+ draw_durations: TimeBuffer,
+
+ render_start: time::Instant,
+ render_durations: TimeBuffer,
+
+ message_count: usize,
+ last_messages: VecDeque<String>,
+}
+
+impl Debug {
+ pub fn new() -> Self {
+ let now = time::Instant::now();
+
+ Self {
+ is_enabled: false,
+ startup_start: now,
+ startup_duration: time::Duration::from_secs(0),
+
+ update_start: now,
+ update_durations: TimeBuffer::new(200),
+
+ view_start: now,
+ view_durations: TimeBuffer::new(200),
+
+ layout_start: now,
+ layout_durations: TimeBuffer::new(200),
+
+ event_start: now,
+ event_durations: TimeBuffer::new(200),
+
+ draw_start: now,
+ draw_durations: TimeBuffer::new(200),
+
+ render_start: now,
+ render_durations: TimeBuffer::new(50),
+
+ message_count: 0,
+ last_messages: VecDeque::new(),
+ }
+ }
+
+ pub fn toggle(&mut self) {
+ self.is_enabled = !self.is_enabled;
+ }
+
+ pub fn startup_started(&mut self) {
+ self.startup_start = time::Instant::now();
+ }
+
+ pub fn startup_finished(&mut self) {
+ self.startup_duration = time::Instant::now() - self.startup_start;
+ }
+
+ pub fn update_started(&mut self) {
+ self.update_start = time::Instant::now();
+ }
+
+ pub fn update_finished(&mut self) {
+ self.update_durations
+ .push(time::Instant::now() - self.update_start);
+ }
+
+ pub fn view_started(&mut self) {
+ self.view_start = time::Instant::now();
+ }
+
+ pub fn view_finished(&mut self) {
+ self.view_durations
+ .push(time::Instant::now() - self.view_start);
+ }
+
+ pub fn layout_started(&mut self) {
+ self.layout_start = time::Instant::now();
+ }
+
+ pub fn layout_finished(&mut self) {
+ self.layout_durations
+ .push(time::Instant::now() - self.layout_start);
+ }
+
+ pub fn event_processing_started(&mut self) {
+ self.event_start = time::Instant::now();
+ }
+
+ pub fn event_processing_finished(&mut self) {
+ self.event_durations
+ .push(time::Instant::now() - self.event_start);
+ }
+
+ pub fn draw_started(&mut self) {
+ self.draw_start = time::Instant::now();
+ }
+
+ pub fn draw_finished(&mut self) {
+ self.draw_durations
+ .push(time::Instant::now() - self.draw_start);
+ }
+
+ pub fn render_started(&mut self) {
+ self.render_start = time::Instant::now();
+ }
+
+ pub fn render_finished(&mut self) {
+ self.render_durations
+ .push(time::Instant::now() - self.render_start);
+ }
+
+ pub fn log_message<Message: std::fmt::Debug>(&mut self, message: &Message) {
+ self.last_messages.push_back(format!("{:?}", message));
+
+ if self.last_messages.len() > 10 {
+ let _ = self.last_messages.pop_front();
+ }
+
+ self.message_count += 1;
+ }
+
+ pub fn overlay(&self) -> Vec<String> {
+ if !self.is_enabled {
+ return Vec::new();
+ }
+
+ let mut lines = Vec::new();
+
+ fn key_value<T: std::fmt::Debug>(key: &str, value: T) -> String {
+ format!("{: <30} {:?}", key, value)
+ }
+
+ lines.push(key_value("Startup:", self.startup_duration));
+ lines.push(key_value("Update:", self.update_durations.average()));
+ lines.push(key_value("View:", self.view_durations.average()));
+ lines.push(key_value("Layout:", self.layout_durations.average()));
+ lines.push(key_value(
+ "Event processing:",
+ self.event_durations.average(),
+ ));
+ lines.push(key_value(
+ "Primitive generation:",
+ self.draw_durations.average(),
+ ));
+ lines.push(key_value("Render:", self.render_durations.average()));
+ lines.push(key_value("Message count:", self.message_count));
+ lines.push(String::from("Last messages:"));
+ lines.extend(
+ self.last_messages.iter().map(|msg| format!(" {}", msg)),
+ );
+
+ lines
+ }
+}
+
+#[derive(Debug)]
+struct TimeBuffer {
+ head: usize,
+ size: usize,
+ contents: Vec<time::Duration>,
+}
+
+impl TimeBuffer {
+ fn new(capacity: usize) -> TimeBuffer {
+ TimeBuffer {
+ head: 0,
+ size: 0,
+ contents: vec![time::Duration::from_secs(0); capacity],
+ }
+ }
+
+ fn push(&mut self, duration: time::Duration) {
+ self.head = (self.head + 1) % self.contents.len();
+ self.contents[self.head] = duration;
+ self.size = (self.size + 1).min(self.contents.len());
+ }
+
+ fn average(&self) -> time::Duration {
+ let sum: time::Duration = if self.size == self.contents.len() {
+ self.contents[..].iter().sum()
+ } else {
+ self.contents[..self.size].iter().sum()
+ };
+
+ sum / self.size.max(1) as u32
+ }
+}
diff --git a/winit/src/debug/null.rs b/winit/src/debug/null.rs
new file mode 100644
index 00000000..9c809dd4
--- /dev/null
+++ b/winit/src/debug/null.rs
@@ -0,0 +1,48 @@
+#[derive(Debug)]
+pub struct Debug;
+
+impl Debug {
+ pub fn new() -> Self {
+ Self
+ }
+
+ pub fn toggle(&mut self) {}
+
+ pub fn startup_started(&mut self) {}
+
+ pub fn startup_finished(&mut self) {}
+
+ pub fn update_started(&mut self) {}
+
+ pub fn update_finished(&mut self) {}
+
+ pub fn view_started(&mut self) {}
+
+ pub fn view_finished(&mut self) {}
+
+ pub fn layout_started(&mut self) {}
+
+ pub fn layout_finished(&mut self) {}
+
+ pub fn event_processing_started(&mut self) {}
+
+ pub fn event_processing_finished(&mut self) {}
+
+ pub fn draw_started(&mut self) {}
+
+ pub fn draw_finished(&mut self) {}
+
+ pub fn render_started(&mut self) {}
+
+ pub fn render_finished(&mut self) {}
+
+ pub fn log_message<Message: std::fmt::Debug>(
+ &mut self,
+ _message: &Message,
+ ) {
+ }
+
+ pub fn overlay(&self) -> Vec<String> {
+ Vec::new()
+ }
+}
diff --git a/winit/src/lib.rs b/winit/src/lib.rs
index b08fcb6c..f66c0553 100644
--- a/winit/src/lib.rs
+++ b/winit/src/lib.rs
@@ -6,3 +6,14 @@ pub mod conversion;
mod application;
pub use application::Application;
+
+// We disable debug capabilities on release builds unless the `debug` feature
+// is explicitly enabled.
+#[cfg_attr(any(debug_assertions, feature = "debug"), path = "debug/basic.rs")]
+#[cfg_attr(
+ not(any(debug_assertions, feature = "debug")),
+ path = "debug/null.rs"
+)]
+mod debug;
+
+use debug::Debug;