From 58e04af824a64d9f712a2d6691d4283888d271d3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez <hector0193@gmail.com> Date: Sat, 2 Nov 2019 19:58:49 +0100 Subject: Draft `Metrics` and improve `Target` abstraction --- native/src/lib.rs | 2 + native/src/metrics.rs | 11 ++++++ native/src/renderer.rs | 2 +- native/src/renderer/windowed.rs | 24 +++++++++--- wgpu/src/renderer.rs | 84 ++++++++++++++++++++++++++--------------- winit/src/application.rs | 18 ++++++--- 6 files changed, 99 insertions(+), 42 deletions(-) create mode 100644 native/src/metrics.rs diff --git a/native/src/lib.rs b/native/src/lib.rs index fa72a553..86bfb3ca 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -206,6 +206,7 @@ mod element; mod event; mod hasher; mod layout; +mod metrics; mod mouse_cursor; mod node; mod style; @@ -224,6 +225,7 @@ pub use element::Element; pub use event::Event; pub use hasher::Hasher; pub use layout::Layout; +pub use metrics::Metrics; pub use mouse_cursor::MouseCursor; pub use node::Node; pub use renderer::Renderer; diff --git a/native/src/metrics.rs b/native/src/metrics.rs new file mode 100644 index 00000000..7c344b9b --- /dev/null +++ b/native/src/metrics.rs @@ -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, +} diff --git a/native/src/renderer.rs b/native/src/renderer.rs index afe1b09a..5963d577 100644 --- a/native/src/renderer.rs +++ b/native/src/renderer.rs @@ -24,7 +24,7 @@ mod debugger; mod windowed; pub use debugger::Debugger; -pub use windowed::Windowed; +pub use windowed::{Target, Windowed}; pub trait Renderer { type Output; diff --git a/native/src/renderer/windowed.rs b/native/src/renderer/windowed.rs index bcf37964..0499ca70 100644 --- a/native/src/renderer/windowed.rs +++ b/native/src/renderer/windowed.rs @@ -1,17 +1,29 @@ -use crate::MouseCursor; +use crate::{Metrics, MouseCursor}; use raw_window_handle::HasRawWindowHandle; -pub trait Windowed: super::Renderer { - type Target; +pub trait Windowed: super::Renderer + Sized { + type Target: Target<Renderer = Self>; - fn new<W: HasRawWindowHandle>(window: &W) -> Self; - - fn target(&self, width: u16, height: u16) -> Self::Target; + fn new() -> Self; fn draw( &mut self, output: &Self::Output, + metrics: Option<Metrics>, target: &mut Self::Target, ) -> 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); +} diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index fbc39327..6e90c129 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -1,6 +1,6 @@ use crate::{quad, Image, Primitive, Quad, Transformation}; use iced_native::{ - renderer::Debugger, renderer::Windowed, Background, Color, Layout, + renderer::Debugger, renderer::Windowed, Background, Color, Layout, Metrics, MouseCursor, Point, Rectangle, Widget, }; @@ -26,7 +26,6 @@ mod text; mod text_input; pub struct Renderer { - surface: Surface, device: Device, queue: Queue, quad_pipeline: quad::Pipeline, @@ -36,12 +35,61 @@ pub struct Renderer { } pub struct Target { + surface: Surface, width: u16, height: u16, transformation: Transformation, 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> { bounds: Rectangle<u32>, y_offset: u32, @@ -63,7 +111,7 @@ impl<'a> Layer<'a> { } impl Renderer { - fn new<W: HasRawWindowHandle>(window: &W) -> Self { + fn new() -> Self { let adapter = Adapter::request(&RequestAdapterOptions { power_preference: PowerPreference::LowPower, backends: BackendBit::all(), @@ -77,8 +125,6 @@ impl Renderer { limits: Limits { max_bind_groups: 2 }, }); - let surface = Surface::create(window); - // TODO: Think about font loading strategy // Loading system fonts with fallback may be a good idea let font: &[u8] = @@ -91,7 +137,6 @@ impl Renderer { let image_pipeline = crate::image::Pipeline::new(&mut device); Self { - surface, device, queue, 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( &mut self, (primitive, mouse_cursor): &(Primitive, MouseCursor), @@ -363,17 +390,14 @@ impl iced_native::Renderer for Renderer { impl Windowed for Renderer { type Target = Target; - fn new<W: HasRawWindowHandle>(window: &W) -> Self { - Self::new(window) - } - - fn target(&self, width: u16, height: u16) -> Target { - self.target(width, height) + fn new() -> Self { + Self::new() } fn draw( &mut self, output: &Self::Output, + metrics: Option<Metrics>, target: &mut Target, ) -> MouseCursor { self.draw(output, target) diff --git a/winit/src/application.rs b/winit/src/application.rs index b90b5eef..8c7d8c37 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -1,7 +1,7 @@ use crate::{ column, conversion, input::{keyboard, mouse}, - renderer::Windowed, + renderer::{Target, Windowed}, Cache, Column, Element, Event, Length, MouseCursor, UserInterface, }; @@ -41,8 +41,14 @@ pub trait Application { .into(); let mut new_size: Option<Size> = None; - let mut renderer = Self::Renderer::new(&window); - let mut target = renderer.target(size.width, size.height); + let mut renderer = Self::Renderer::new(); + + let mut target = <Self::Renderer as Windowed>::Target::new( + &window, + size.width, + size.height, + &renderer, + ); let user_interface = UserInterface::build( document(&mut self, size), @@ -103,11 +109,13 @@ pub trait Application { } event::Event::RedrawRequested(_) => { 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; } - 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 { window.set_cursor_icon(conversion::mouse_cursor( -- cgit