Draft Metrics and improve Target abstraction

This commit is contained in:
Héctor Ramón Jiménez 2019-11-02 19:58:49 +01:00
parent f3baae9228
commit 58e04af824
6 changed files with 99 additions and 42 deletions

View file

@ -206,6 +206,7 @@ mod element;
mod event; mod event;
mod hasher; mod hasher;
mod layout; mod layout;
mod metrics;
mod mouse_cursor; mod mouse_cursor;
mod node; mod node;
mod style; mod style;
@ -224,6 +225,7 @@ pub use element::Element;
pub use event::Event; pub use event::Event;
pub use hasher::Hasher; pub use hasher::Hasher;
pub use layout::Layout; pub use layout::Layout;
pub use metrics::Metrics;
pub use mouse_cursor::MouseCursor; pub use mouse_cursor::MouseCursor;
pub use node::Node; pub use node::Node;
pub use renderer::Renderer; pub use renderer::Renderer;

11
native/src/metrics.rs Normal file
View file

@ -0,0 +1,11 @@
use std::time;
/// A bunch of metrics about an Iced application.
#[derive(Debug, Clone, Copy)]
pub struct Metrics {
pub startup_time: time::Duration,
pub update_time: time::Duration,
pub view_time: time::Duration,
pub renderer_output_time: time::Duration,
pub message_count: usize,
}

View file

@ -24,7 +24,7 @@ mod debugger;
mod windowed; mod windowed;
pub use debugger::Debugger; pub use debugger::Debugger;
pub use windowed::Windowed; pub use windowed::{Target, Windowed};
pub trait Renderer { pub trait Renderer {
type Output; type Output;

View file

@ -1,17 +1,29 @@
use crate::MouseCursor; use crate::{Metrics, MouseCursor};
use raw_window_handle::HasRawWindowHandle; use raw_window_handle::HasRawWindowHandle;
pub trait Windowed: super::Renderer { pub trait Windowed: super::Renderer + Sized {
type Target; type Target: Target<Renderer = Self>;
fn new<W: HasRawWindowHandle>(window: &W) -> Self; fn new() -> Self;
fn target(&self, width: u16, height: u16) -> Self::Target;
fn draw( fn draw(
&mut self, &mut self,
output: &Self::Output, output: &Self::Output,
metrics: Option<Metrics>,
target: &mut Self::Target, target: &mut Self::Target,
) -> MouseCursor; ) -> MouseCursor;
} }
pub trait Target {
type Renderer;
fn new<W: HasRawWindowHandle>(
window: &W,
width: u16,
height: u16,
renderer: &Self::Renderer,
) -> Self;
fn resize(&mut self, width: u16, height: u16, renderer: &Self::Renderer);
}

View file

@ -1,6 +1,6 @@
use crate::{quad, Image, Primitive, Quad, Transformation}; use crate::{quad, Image, Primitive, Quad, Transformation};
use iced_native::{ use iced_native::{
renderer::Debugger, renderer::Windowed, Background, Color, Layout, renderer::Debugger, renderer::Windowed, Background, Color, Layout, Metrics,
MouseCursor, Point, Rectangle, Widget, MouseCursor, Point, Rectangle, Widget,
}; };
@ -26,7 +26,6 @@ mod text;
mod text_input; mod text_input;
pub struct Renderer { pub struct Renderer {
surface: Surface,
device: Device, device: Device,
queue: Queue, queue: Queue,
quad_pipeline: quad::Pipeline, quad_pipeline: quad::Pipeline,
@ -36,12 +35,61 @@ pub struct Renderer {
} }
pub struct Target { pub struct Target {
surface: Surface,
width: u16, width: u16,
height: u16, height: u16,
transformation: Transformation, transformation: Transformation,
swap_chain: SwapChain, swap_chain: SwapChain,
} }
impl iced_native::renderer::Target for Target {
type Renderer = Renderer;
fn new<W: HasRawWindowHandle>(
window: &W,
width: u16,
height: u16,
renderer: &Renderer,
) -> Target {
let surface = Surface::create(window);
let swap_chain = renderer.device.create_swap_chain(
&surface,
&SwapChainDescriptor {
usage: TextureUsage::OUTPUT_ATTACHMENT,
format: TextureFormat::Bgra8UnormSrgb,
width: u32::from(width),
height: u32::from(height),
present_mode: wgpu::PresentMode::Vsync,
},
);
Target {
surface,
width,
height,
transformation: Transformation::orthographic(width, height),
swap_chain,
}
}
fn resize(&mut self, width: u16, height: u16, renderer: &Renderer) {
self.width = width;
self.height = height;
self.transformation = Transformation::orthographic(width, height);
self.swap_chain = renderer.device.create_swap_chain(
&self.surface,
&SwapChainDescriptor {
usage: TextureUsage::OUTPUT_ATTACHMENT,
format: TextureFormat::Bgra8UnormSrgb,
width: u32::from(width),
height: u32::from(height),
present_mode: wgpu::PresentMode::Vsync,
},
);
}
}
pub struct Layer<'a> { pub struct Layer<'a> {
bounds: Rectangle<u32>, bounds: Rectangle<u32>,
y_offset: u32, y_offset: u32,
@ -63,7 +111,7 @@ impl<'a> Layer<'a> {
} }
impl Renderer { impl Renderer {
fn new<W: HasRawWindowHandle>(window: &W) -> Self { fn new() -> Self {
let adapter = Adapter::request(&RequestAdapterOptions { let adapter = Adapter::request(&RequestAdapterOptions {
power_preference: PowerPreference::LowPower, power_preference: PowerPreference::LowPower,
backends: BackendBit::all(), backends: BackendBit::all(),
@ -77,8 +125,6 @@ impl Renderer {
limits: Limits { max_bind_groups: 2 }, limits: Limits { max_bind_groups: 2 },
}); });
let surface = Surface::create(window);
// TODO: Think about font loading strategy // TODO: Think about font loading strategy
// Loading system fonts with fallback may be a good idea // Loading system fonts with fallback may be a good idea
let font: &[u8] = let font: &[u8] =
@ -91,7 +137,6 @@ impl Renderer {
let image_pipeline = crate::image::Pipeline::new(&mut device); let image_pipeline = crate::image::Pipeline::new(&mut device);
Self { Self {
surface,
device, device,
queue, queue,
quad_pipeline, quad_pipeline,
@ -101,24 +146,6 @@ impl Renderer {
} }
} }
fn target(&self, width: u16, height: u16) -> Target {
Target {
width,
height,
transformation: Transformation::orthographic(width, height),
swap_chain: self.device.create_swap_chain(
&self.surface,
&SwapChainDescriptor {
usage: TextureUsage::OUTPUT_ATTACHMENT,
format: TextureFormat::Bgra8UnormSrgb,
width: u32::from(width),
height: u32::from(height),
present_mode: wgpu::PresentMode::Vsync,
},
),
}
}
fn draw( fn draw(
&mut self, &mut self,
(primitive, mouse_cursor): &(Primitive, MouseCursor), (primitive, mouse_cursor): &(Primitive, MouseCursor),
@ -363,17 +390,14 @@ impl iced_native::Renderer for Renderer {
impl Windowed for Renderer { impl Windowed for Renderer {
type Target = Target; type Target = Target;
fn new<W: HasRawWindowHandle>(window: &W) -> Self { fn new() -> Self {
Self::new(window) Self::new()
}
fn target(&self, width: u16, height: u16) -> Target {
self.target(width, height)
} }
fn draw( fn draw(
&mut self, &mut self,
output: &Self::Output, output: &Self::Output,
metrics: Option<Metrics>,
target: &mut Target, target: &mut Target,
) -> MouseCursor { ) -> MouseCursor {
self.draw(output, target) self.draw(output, target)

View file

@ -1,7 +1,7 @@
use crate::{ use crate::{
column, conversion, column, conversion,
input::{keyboard, mouse}, input::{keyboard, mouse},
renderer::Windowed, renderer::{Target, Windowed},
Cache, Column, Element, Event, Length, MouseCursor, UserInterface, Cache, Column, Element, Event, Length, MouseCursor, UserInterface,
}; };
@ -41,8 +41,14 @@ pub trait Application {
.into(); .into();
let mut new_size: Option<Size> = None; let mut new_size: Option<Size> = None;
let mut renderer = Self::Renderer::new(&window); let mut renderer = Self::Renderer::new();
let mut target = renderer.target(size.width, size.height);
let mut target = <Self::Renderer as Windowed>::Target::new(
&window,
size.width,
size.height,
&renderer,
);
let user_interface = UserInterface::build( let user_interface = UserInterface::build(
document(&mut self, size), document(&mut self, size),
@ -103,11 +109,13 @@ pub trait Application {
} }
event::Event::RedrawRequested(_) => { event::Event::RedrawRequested(_) => {
if let Some(new_size) = new_size.take() { if let Some(new_size) = new_size.take() {
target = renderer.target(new_size.width, new_size.height); target.resize(new_size.width, new_size.height, &renderer);
size = new_size; size = new_size;
} }
let new_mouse_cursor = renderer.draw(&primitive, &mut target); let new_mouse_cursor =
renderer.draw(&primitive, None, &mut target);
if new_mouse_cursor != mouse_cursor { if new_mouse_cursor != mouse_cursor {
window.set_cursor_icon(conversion::mouse_cursor( window.set_cursor_icon(conversion::mouse_cursor(