From a1a5fcfd46622d5b18d1716aa2adb4659835ccf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ram=C3=B3n=20Jim=C3=A9nez?= Date: Wed, 20 May 2020 20:28:35 +0200 Subject: [PATCH] Refactor `Viewport` and `Compositor` --- core/src/rectangle.rs | 33 +++++----- core/src/size.rs | 22 ++++--- examples/integration/src/main.rs | 57 +++++++++------- glow/src/backend.rs | 23 +++---- glow/src/quad.rs | 8 +-- glow/src/window/compositor.rs | 16 ++--- graphics/Cargo.toml | 1 + graphics/src/layer.rs | 45 ++++--------- graphics/src/lib.rs | 1 + graphics/src/viewport.rs | 47 +++++++++----- graphics/src/window.rs | 3 + {native => graphics}/src/window/compositor.rs | 10 +-- native/Cargo.toml | 1 - native/src/window.rs | 2 - wgpu/src/backend.rs | 26 ++++---- wgpu/src/lib.rs | 2 - wgpu/src/target.rs | 14 ---- wgpu/src/triangle.rs | 3 +- wgpu/src/window.rs | 2 - wgpu/src/window/compositor.rs | 33 ++++++---- wgpu/src/window/swap_chain.rs | 61 ----------------- winit/Cargo.toml | 4 ++ winit/src/application.rs | 65 +++++++++---------- winit/src/lib.rs | 1 - 24 files changed, 202 insertions(+), 278 deletions(-) create mode 100644 graphics/src/window.rs rename {native => graphics}/src/window/compositor.rs (89%) delete mode 100644 wgpu/src/target.rs delete mode 100644 wgpu/src/window/swap_chain.rs diff --git a/core/src/rectangle.rs b/core/src/rectangle.rs index 8bc89a44..aa23372e 100644 --- a/core/src/rectangle.rs +++ b/core/src/rectangle.rs @@ -125,17 +125,29 @@ impl Rectangle { None } } + + /// Rounds the [`Rectangle`] to __unsigned__ integer coordinates. + /// + /// [`Rectangle`]: struct.Rectangle.html + pub fn round(self) -> Rectangle { + Rectangle { + x: self.x as u32, + y: self.y as u32, + width: (self.width + 0.5).round() as u32, + height: (self.height + 0.5).round() as u32, + } + } } -impl std::ops::Mul for Rectangle { +impl std::ops::Mul for Rectangle { type Output = Self; fn mul(self, scale: f32) -> Self { Self { - x: (self.x as f32 * scale).round() as u32, - y: (self.y as f32 * scale).round() as u32, - width: (self.width as f32 * scale).round() as u32, - height: (self.height as f32 * scale).round() as u32, + x: self.x as f32 * scale, + y: self.y as f32 * scale, + width: self.width * scale, + height: self.height * scale, } } } @@ -151,17 +163,6 @@ impl From> for Rectangle { } } -impl From> for Rectangle { - fn from(rectangle: Rectangle) -> Rectangle { - Rectangle { - x: rectangle.x as u32, - y: rectangle.y as u32, - width: (rectangle.width + 0.5).round() as u32, - height: (rectangle.height + 0.5).round() as u32, - } - } -} - impl std::ops::Add> for Rectangle where T: std::ops::Add, diff --git a/core/src/size.rs b/core/src/size.rs index a02299e8..aceb5311 100644 --- a/core/src/size.rs +++ b/core/src/size.rs @@ -2,11 +2,20 @@ use std::f32; /// An amount of space in 2 dimensions. #[derive(Debug, Clone, Copy, PartialEq)] -pub struct Size { +pub struct Size { /// The width. - pub width: f32, + pub width: T, /// The height. - pub height: f32, + pub height: T, +} + +impl Size { + /// Creates a new [`Size`] with the given width and height. + /// + /// [`Size`]: struct.Size.html + pub const fn new(width: T, height: T) -> Self { + Size { width, height } + } } impl Size { @@ -25,13 +34,6 @@ impl Size { /// [`Size`]: struct.Size.html pub const INFINITY: Size = Size::new(f32::INFINITY, f32::INFINITY); - /// Creates a new [`Size`] with the given width and height. - /// - /// [`Size`]: struct.Size.html - pub const fn new(width: f32, height: f32) -> Self { - Size { width, height } - } - /// Increments the [`Size`] to account for the given padding. /// /// [`Size`]: struct.Size.html diff --git a/examples/integration/src/main.rs b/examples/integration/src/main.rs index 0ade0458..8d16ed56 100644 --- a/examples/integration/src/main.rs +++ b/examples/integration/src/main.rs @@ -4,9 +4,7 @@ mod scene; use controls::Controls; use scene::Scene; -use iced_wgpu::{ - wgpu, window::SwapChain, Backend, Primitive, Renderer, Settings, Target, -}; +use iced_wgpu::{wgpu, Backend, Primitive, Renderer, Settings, Viewport}; use iced_winit::{ futures, mouse, winit, Cache, Clipboard, Size, UserInterface, }; @@ -22,8 +20,12 @@ pub fn main() { // Initialize winit let event_loop = EventLoop::new(); let window = winit::window::Window::new(&event_loop).unwrap(); - let mut logical_size = - window.inner_size().to_logical(window.scale_factor()); + + let physical_size = window.inner_size(); + let mut viewport = Viewport::with_physical_size( + Size::new(physical_size.width, physical_size.height), + window.scale_factor(), + ); let mut modifiers = ModifiersState::default(); // Initialize WGPU @@ -55,7 +57,16 @@ pub fn main() { let mut swap_chain = { let size = window.inner_size(); - SwapChain::new(&device, &surface, format, size.width, size.height) + device.create_swap_chain( + &surface, + &wgpu::SwapChainDescriptor { + usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, + format: format, + width: size.width, + height: size.height, + present_mode: wgpu::PresentMode::Mailbox, + }, + ) }; let mut resized = false; @@ -83,8 +94,11 @@ pub fn main() { modifiers = new_modifiers; } WindowEvent::Resized(new_size) => { - logical_size = - new_size.to_logical(window.scale_factor()); + viewport = Viewport::with_physical_size( + Size::new(new_size.width, new_size.height), + window.scale_factor(), + ); + resized = true; } WindowEvent::CloseRequested => { @@ -117,7 +131,7 @@ pub fn main() { // First, we build our user interface. let mut user_interface = UserInterface::build( controls.view(&scene), - Size::new(logical_size.width, logical_size.height), + viewport.logical_size(), cache.take().unwrap(), &mut renderer, ); @@ -151,7 +165,7 @@ pub fn main() { // user interface. UserInterface::build( controls.view(&scene), - Size::new(logical_size.width, logical_size.height), + viewport.logical_size(), cache.take().unwrap(), &mut renderer, ) @@ -170,17 +184,19 @@ pub fn main() { if resized { let size = window.inner_size(); - swap_chain = SwapChain::new( - &device, + swap_chain = device.create_swap_chain( &surface, - format, - size.width, - size.height, + &wgpu::SwapChainDescriptor { + usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, + format: format, + width: size.width, + height: size.height, + present_mode: wgpu::PresentMode::Mailbox, + }, ); } - let (frame, viewport) = - swap_chain.next_frame().expect("Next frame"); + let frame = swap_chain.get_next_texture().expect("Next frame"); let mut encoder = device.create_command_encoder( &wgpu::CommandEncoderDescriptor { label: None }, @@ -193,12 +209,9 @@ pub fn main() { let mouse_interaction = renderer.backend_mut().draw( &mut device, &mut encoder, - Target { - texture: &frame.view, - viewport, - }, + &frame.view, + &viewport, &output, - window.scale_factor(), &["Some debug information!"], ); diff --git a/glow/src/backend.rs b/glow/src/backend.rs index fb6782e6..5e2aa837 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -47,12 +47,10 @@ impl Backend { gl: &glow::Context, viewport: &Viewport, (primitive, mouse_interaction): &(Primitive, mouse::Interaction), - scale_factor: f64, overlay_text: &[T], ) -> mouse::Interaction { - let (width, height) = viewport.dimensions(); - let scale_factor = scale_factor as f32; - let transformation = viewport.transformation(); + let viewport_size = viewport.physical_size(); + let projection = viewport.projection(); let mut layers = Layer::generate(primitive, viewport); layers.push(Layer::overlay(overlay_text, viewport)); @@ -60,12 +58,11 @@ impl Backend { for layer in layers { self.flush( gl, - viewport, - scale_factor, - transformation, + viewport.scale_factor() as f32, + projection, &layer, - width, - height, + viewport_size.width, + viewport_size.height, ); } @@ -75,19 +72,18 @@ impl Backend { fn flush( &mut self, gl: &glow::Context, - viewport: &Viewport, scale_factor: f32, transformation: Transformation, layer: &Layer<'_>, target_width: u32, target_height: u32, ) { - let bounds = layer.bounds * scale_factor; + let bounds = (layer.bounds * scale_factor).round(); if !layer.quads.is_empty() { self.quad_pipeline.draw( gl, - viewport, + target_height, &layer.quads, transformation, scale_factor, @@ -175,8 +171,7 @@ impl Backend { transformation, glow_glyph::Region { x: bounds.x, - y: viewport.height() - - (bounds.y + bounds.height).min(viewport.height()), + y: target_height - (bounds.y + bounds.height), width: bounds.width, height: bounds.height, }, diff --git a/glow/src/quad.rs b/glow/src/quad.rs index 26424b39..fd71757f 100644 --- a/glow/src/quad.rs +++ b/glow/src/quad.rs @@ -1,4 +1,4 @@ -use crate::{Transformation, Viewport}; +use crate::Transformation; use glow::HasContext; use iced_graphics::layer; use iced_native::Rectangle; @@ -54,7 +54,7 @@ impl Pipeline { pub fn draw( &mut self, gl: &glow::Context, - viewport: &Viewport, + target_height: u32, instances: &[layer::Quad], transformation: Transformation, scale: f32, @@ -64,9 +64,7 @@ impl Pipeline { gl.enable(glow::SCISSOR_TEST); gl.scissor( bounds.x as i32, - (viewport.height() - - (bounds.y + bounds.height).min(viewport.height())) - as i32, + (target_height - (bounds.y + bounds.height)) as i32, bounds.width as i32, bounds.height as i32, ); diff --git a/glow/src/window/compositor.rs b/glow/src/window/compositor.rs index 8f770065..514904a8 100644 --- a/glow/src/window/compositor.rs +++ b/glow/src/window/compositor.rs @@ -13,11 +13,11 @@ pub struct Compositor { gl: Option, } -impl iced_native::window::Compositor for Compositor { +impl iced_graphics::window::Compositor for Compositor { type Settings = Settings; type Renderer = Renderer; type Surface = (); - type SwapChain = Viewport; + type SwapChain = (); fn new(_settings: Self::Settings) -> Self { let connection = surfman::Connection::new().expect("Create connection"); @@ -133,16 +133,14 @@ impl iced_native::window::Compositor for Compositor { gl.enable(glow::BLEND); gl.blend_func(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA); } - - Viewport::new(width, height) } fn draw>( &mut self, renderer: &mut Self::Renderer, swap_chain: &mut Self::SwapChain, + viewport: &Viewport, output: &::Output, - scale_factor: f64, overlay: &[T], ) -> mouse::Interaction { let gl = self.gl.as_ref().unwrap(); @@ -151,13 +149,7 @@ impl iced_native::window::Compositor for Compositor { gl.clear(glow::COLOR_BUFFER_BIT); } - let mouse = renderer.backend_mut().draw( - gl, - swap_chain, - output, - scale_factor, - overlay, - ); + let mouse = renderer.backend_mut().draw(gl, viewport, output, overlay); { let mut surface = self diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml index 61f1f6d4..12ad3f14 100644 --- a/graphics/Cargo.toml +++ b/graphics/Cargo.toml @@ -13,6 +13,7 @@ font-icons = [] [dependencies] bytemuck = "1.2" glam = "0.8" +raw-window-handle = "0.3" [dependencies.iced_native] version = "0.2" diff --git a/graphics/src/layer.rs b/graphics/src/layer.rs index ae9c6ce0..916b5c83 100644 --- a/graphics/src/layer.rs +++ b/graphics/src/layer.rs @@ -7,7 +7,7 @@ use crate::{ }; pub struct Layer<'a> { - pub bounds: Rectangle, + pub bounds: Rectangle, pub quads: Vec, pub meshes: Vec>, pub text: Vec>, @@ -15,7 +15,7 @@ pub struct Layer<'a> { } impl<'a> Layer<'a> { - pub fn new(bounds: Rectangle) -> Self { + pub fn new(bounds: Rectangle) -> Self { Self { bounds, quads: Vec::new(), @@ -26,14 +26,8 @@ impl<'a> Layer<'a> { } pub fn overlay(lines: &'a [impl AsRef], viewport: &Viewport) -> Self { - let (width, height) = viewport.dimensions(); - - let mut overlay = Layer::new(Rectangle { - x: 0, - y: 0, - width, - height, - }); + let mut overlay = + Layer::new(Rectangle::with_size(viewport.logical_size())); for (i, line) in lines.iter().enumerate() { let text = Text { @@ -61,28 +55,14 @@ impl<'a> Layer<'a> { overlay } - pub(crate) fn intersection( - &self, - rectangle: Rectangle, - ) -> Option> { - let layer_bounds: Rectangle = self.bounds.into(); - - layer_bounds.intersection(&rectangle).map(Into::into) - } - pub fn generate( primitive: &'a Primitive, viewport: &Viewport, ) -> Vec { - let mut layers = Vec::new(); - let (width, height) = viewport.dimensions(); + let first_layer = + Layer::new(Rectangle::with_size(viewport.logical_size())); - layers.push(Layer::new(Rectangle { - x: 0, - y: 0, - width, - height, - })); + let mut layers = vec![first_layer]; Self::process_primitive(&mut layers, Vector::new(0.0, 0.0), primitive); @@ -156,11 +136,11 @@ impl<'a> Layer<'a> { ); // Only draw visible content - if let Some(clip_bounds) = layer.intersection(bounds) { + if let Some(clip_bounds) = layer.bounds.intersection(&bounds) { layer.meshes.push(Mesh { origin: Point::new(translation.x, translation.y), buffers, - clip_bounds: clip_bounds.into(), + clip_bounds, }); } } @@ -170,12 +150,13 @@ impl<'a> Layer<'a> { content, } => { let layer = layers.last_mut().unwrap(); + let translated_bounds = *bounds + translation; // Only draw visible content if let Some(clip_bounds) = - layer.intersection(*bounds + translation) + layer.bounds.intersection(&translated_bounds) { - let clip_layer = Layer::new(clip_bounds.into()); + let clip_layer = Layer::new(clip_bounds); let new_layer = Layer::new(layer.bounds); layers.push(clip_layer); @@ -236,7 +217,7 @@ pub struct Quad { pub struct Mesh<'a> { pub origin: Point, pub buffers: &'a triangle::Mesh2D, - pub clip_bounds: Rectangle, + pub clip_bounds: Rectangle, } #[derive(Debug, Clone, Copy)] diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs index 5ab333c7..2de9d21c 100644 --- a/graphics/src/lib.rs +++ b/graphics/src/lib.rs @@ -10,6 +10,7 @@ pub mod backend; pub mod font; pub mod layer; pub mod triangle; +pub mod window; #[doc(no_inline)] pub use widget::*; diff --git a/graphics/src/viewport.rs b/graphics/src/viewport.rs index 48e5a249..745ef339 100644 --- a/graphics/src/viewport.rs +++ b/graphics/src/viewport.rs @@ -1,33 +1,48 @@ -use crate::Transformation; +use crate::{Size, Transformation}; /// A viewing region for displaying computer graphics. #[derive(Debug)] pub struct Viewport { - width: u32, - height: u32, - transformation: Transformation, + physical_size: Size, + logical_size: Size, + scale_factor: f64, + projection: Transformation, } impl Viewport { - /// Creates a new [`Viewport`] with the given dimensions. - pub fn new(width: u32, height: u32) -> Viewport { + /// Creates a new [`Viewport`] with the given physical dimensions and scale + /// factor. + /// + /// [`Viewport`]: struct.Viewport.html + pub fn with_physical_size(size: Size, scale_factor: f64) -> Viewport { Viewport { - width, - height, - transformation: Transformation::orthographic(width, height), + physical_size: size, + logical_size: Size::new( + (size.width as f64 / scale_factor) as f32, + (size.height as f64 / scale_factor) as f32, + ), + scale_factor, + projection: Transformation::orthographic(size.width, size.height), } } - pub fn height(&self) -> u32 { - self.height + pub fn physical_size(&self) -> Size { + self.physical_size } - /// Returns the dimensions of the [`Viewport`]. - pub fn dimensions(&self) -> (u32, u32) { - (self.width, self.height) + pub fn physical_height(&self) -> u32 { + self.physical_size.height } - pub fn transformation(&self) -> Transformation { - self.transformation + pub fn logical_size(&self) -> Size { + self.logical_size + } + + pub fn scale_factor(&self) -> f64 { + self.scale_factor + } + + pub fn projection(&self) -> Transformation { + self.projection } } diff --git a/graphics/src/window.rs b/graphics/src/window.rs new file mode 100644 index 00000000..a7c8911b --- /dev/null +++ b/graphics/src/window.rs @@ -0,0 +1,3 @@ +mod compositor; + +pub use compositor::Compositor; diff --git a/native/src/window/compositor.rs b/graphics/src/window/compositor.rs similarity index 89% rename from native/src/window/compositor.rs rename to graphics/src/window/compositor.rs index ae010c89..82faa6e1 100644 --- a/native/src/window/compositor.rs +++ b/graphics/src/window/compositor.rs @@ -1,5 +1,5 @@ -use crate::mouse; - +use crate::Viewport; +use iced_native::mouse; use raw_window_handle::HasRawWindowHandle; /// A graphics compositor that can draw to windows. @@ -8,7 +8,7 @@ pub trait Compositor: Sized { type Settings: Default + Clone; /// The iced renderer of the backend. - type Renderer: crate::Renderer; + type Renderer: iced_native::Renderer; /// The surface of the backend. type Surface; @@ -53,8 +53,8 @@ pub trait Compositor: Sized { &mut self, renderer: &mut Self::Renderer, swap_chain: &mut Self::SwapChain, - output: &::Output, - scale_factor: f64, + viewport: &Viewport, + output: &::Output, overlay: &[T], ) -> mouse::Interaction; } diff --git a/native/Cargo.toml b/native/Cargo.toml index 7e9c2a5a..067b8708 100644 --- a/native/Cargo.toml +++ b/native/Cargo.toml @@ -9,7 +9,6 @@ repository = "https://github.com/hecrj/iced" [dependencies] twox-hash = "1.5" -raw-window-handle = "0.3" unicode-segmentation = "1.6" [dependencies.iced_core] diff --git a/native/src/window.rs b/native/src/window.rs index 84269fbf..220bb3be 100644 --- a/native/src/window.rs +++ b/native/src/window.rs @@ -1,6 +1,4 @@ //! Build window-based GUI applications. -mod compositor; mod event; -pub use compositor::Compositor; pub use event::Event; diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 82e4c4b2..1e62cf07 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -1,11 +1,11 @@ use crate::quad; use crate::text; use crate::triangle; -use crate::{Settings, Target, Transformation}; +use crate::{Settings, Transformation}; use iced_graphics::backend; use iced_graphics::font; use iced_graphics::layer::Layer; -use iced_graphics::Primitive; +use iced_graphics::{Primitive, Viewport}; use iced_native::mouse; use iced_native::{Font, HorizontalAlignment, Size, VerticalAlignment}; @@ -62,19 +62,19 @@ impl Backend { &mut self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, - target: Target<'_>, + frame: &wgpu::TextureView, + viewport: &Viewport, (primitive, mouse_interaction): &(Primitive, mouse::Interaction), - scale_factor: f64, overlay_text: &[T], ) -> mouse::Interaction { log::debug!("Drawing"); - let (width, height) = target.viewport.dimensions(); - let scale_factor = scale_factor as f32; - let transformation = target.viewport.transformation(); + let target_size = viewport.physical_size(); + let scale_factor = viewport.scale_factor() as f32; + let transformation = viewport.projection(); - let mut layers = Layer::generate(primitive, &target.viewport); - layers.push(Layer::overlay(overlay_text, &target.viewport)); + let mut layers = Layer::generate(primitive, viewport); + layers.push(Layer::overlay(overlay_text, viewport)); for layer in layers { self.flush( @@ -83,9 +83,9 @@ impl Backend { transformation, &layer, encoder, - target.texture, - width, - height, + &frame, + target_size.width, + target_size.height, ); } @@ -106,7 +106,7 @@ impl Backend { target_width: u32, target_height: u32, ) { - let bounds = layer.bounds * scale_factor; + let bounds = (layer.bounds * scale_factor).round(); if !layer.quads.is_empty() { self.quad_pipeline.draw( diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index 74007eae..b0eee0a0 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -34,7 +34,6 @@ pub mod window; mod backend; mod quad; -mod target; mod text; pub use iced_graphics::{Defaults, Primitive, Viewport}; @@ -42,7 +41,6 @@ pub use wgpu; pub use backend::Backend; pub use settings::Settings; -pub use target::Target; #[doc(no_inline)] pub use widget::*; diff --git a/wgpu/src/target.rs b/wgpu/src/target.rs deleted file mode 100644 index 1e72c0c3..00000000 --- a/wgpu/src/target.rs +++ /dev/null @@ -1,14 +0,0 @@ -use crate::Viewport; - -/// A rendering target. -#[derive(Debug)] -pub struct Target<'a> { - /// The texture where graphics will be rendered. - pub texture: &'a wgpu::TextureView, - - /// The viewport of the target. - /// - /// Most of the time, you will want this to match the dimensions of the - /// texture. - pub viewport: &'a Viewport, -} diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs index 31975005..dc58a52a 100644 --- a/wgpu/src/triangle.rs +++ b/wgpu/src/triangle.rs @@ -326,7 +326,8 @@ impl Pipeline { for (i, (vertex_offset, index_offset, indices)) in offsets.into_iter().enumerate() { - let clip_bounds = meshes[i].clip_bounds * scale_factor; + let clip_bounds = + (meshes[i].clip_bounds * scale_factor).round(); render_pass.set_scissor_rect( clip_bounds.x, diff --git a/wgpu/src/window.rs b/wgpu/src/window.rs index 391d3e36..aac5fb9e 100644 --- a/wgpu/src/window.rs +++ b/wgpu/src/window.rs @@ -1,6 +1,4 @@ //! Display rendering results on windows. mod compositor; -mod swap_chain; pub use compositor::Compositor; -pub use swap_chain::SwapChain; diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 8950ffd4..7eba8924 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -1,5 +1,6 @@ -use crate::{window::SwapChain, Renderer, Settings, Target}; +use crate::{Renderer, Settings}; +use iced_graphics::Viewport; use iced_native::{futures, mouse}; use raw_window_handle::HasRawWindowHandle; @@ -11,11 +12,11 @@ pub struct Compositor { format: wgpu::TextureFormat, } -impl iced_native::window::Compositor for Compositor { +impl iced_graphics::window::Compositor for Compositor { type Settings = Settings; type Renderer = Renderer; type Surface = wgpu::Surface; - type SwapChain = SwapChain; + type SwapChain = wgpu::SwapChain; fn new(settings: Self::Settings) -> Self { let (device, queue) = futures::executor::block_on(async { @@ -66,19 +67,28 @@ impl iced_native::window::Compositor for Compositor { surface: &Self::Surface, width: u32, height: u32, - ) -> SwapChain { - SwapChain::new(&self.device, surface, self.format, width, height) + ) -> Self::SwapChain { + self.device.create_swap_chain( + surface, + &wgpu::SwapChainDescriptor { + usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, + format: self.format, + width, + height, + present_mode: wgpu::PresentMode::Mailbox, + }, + ) } fn draw>( &mut self, renderer: &mut Self::Renderer, - swap_chain: &mut SwapChain, + swap_chain: &mut Self::SwapChain, + viewport: &Viewport, output: &::Output, - scale_factor: f64, overlay: &[T], ) -> mouse::Interaction { - let (frame, viewport) = swap_chain.next_frame().expect("Next frame"); + let frame = swap_chain.get_next_texture().expect("Next frame"); let mut encoder = self.device.create_command_encoder( &wgpu::CommandEncoderDescriptor { label: None }, @@ -103,12 +113,9 @@ impl iced_native::window::Compositor for Compositor { let mouse_interaction = renderer.backend_mut().draw( &mut self.device, &mut encoder, - Target { - texture: &frame.view, - viewport, - }, + &frame.view, + viewport, output, - scale_factor, overlay, ); diff --git a/wgpu/src/window/swap_chain.rs b/wgpu/src/window/swap_chain.rs deleted file mode 100644 index 72e58a50..00000000 --- a/wgpu/src/window/swap_chain.rs +++ /dev/null @@ -1,61 +0,0 @@ -use crate::Viewport; - -/// The rendering target of a window. -/// -/// It represents a series of virtual framebuffers with a scale factor. -#[derive(Debug)] -pub struct SwapChain { - raw: wgpu::SwapChain, - viewport: Viewport, -} - -impl SwapChain {} - -impl SwapChain { - /// Creates a new [`SwapChain`] for the given surface. - /// - /// [`SwapChain`]: struct.SwapChain.html - pub fn new( - device: &wgpu::Device, - surface: &wgpu::Surface, - format: wgpu::TextureFormat, - width: u32, - height: u32, - ) -> SwapChain { - SwapChain { - raw: new_swap_chain(surface, format, width, height, device), - viewport: Viewport::new(width, height), - } - } - - /// Returns the next frame of the [`SwapChain`] alongside its [`Viewport`]. - /// - /// [`SwapChain`]: struct.SwapChain.html - /// [`Viewport`]: ../struct.Viewport.html - pub fn next_frame( - &mut self, - ) -> Result<(wgpu::SwapChainOutput, &Viewport), wgpu::TimeOut> { - let viewport = &self.viewport; - - self.raw.get_next_texture().map(|output| (output, viewport)) - } -} - -fn new_swap_chain( - surface: &wgpu::Surface, - format: wgpu::TextureFormat, - width: u32, - height: u32, - device: &wgpu::Device, -) -> wgpu::SwapChain { - device.create_swap_chain( - &surface, - &wgpu::SwapChainDescriptor { - usage: wgpu::TextureUsage::OUTPUT_ATTACHMENT, - format, - width, - height, - present_mode: wgpu::PresentMode::Mailbox, - }, - ) -} diff --git a/winit/Cargo.toml b/winit/Cargo.toml index b6662451..1bf2d7b3 100644 --- a/winit/Cargo.toml +++ b/winit/Cargo.toml @@ -22,5 +22,9 @@ log = "0.4" version = "0.2" path = "../native" +[dependencies.iced_graphics] +version = "0.1" +path = "../graphics" + [target.'cfg(target_os = "windows")'.dependencies.winapi] version = "0.3.6" diff --git a/winit/src/application.rs b/winit/src/application.rs index 83b53de2..9196709b 100644 --- a/winit/src/application.rs +++ b/winit/src/application.rs @@ -1,8 +1,9 @@ use crate::{ - conversion, mouse, size::Size, window, Cache, Clipboard, Command, Debug, - Element, Executor, Mode, Proxy, Runtime, Settings, Subscription, - UserInterface, + conversion, mouse, Cache, Clipboard, Command, Debug, Element, Executor, + Mode, Proxy, Runtime, Settings, Size, Subscription, UserInterface, }; +use iced_graphics::window; +use iced_graphics::Viewport; /// An interactive, native cross-platform application. /// @@ -124,7 +125,7 @@ pub trait Application: Sized { ) where Self: 'static, { - use window::Compositor as _; + use iced_graphics::window::Compositor as _; use winit::{ event::{self, WindowEvent}, event_loop::{ControlFlow, EventLoop}, @@ -181,7 +182,11 @@ pub trait Application: Sized { window_builder.build(&event_loop).expect("Open window") }; - let mut size = Size::new(window.inner_size(), window.scale_factor()); + let physical_size = window.inner_size(); + let mut viewport = Viewport::with_physical_size( + Size::new(physical_size.width, physical_size.height), + window.scale_factor(), + ); let mut resized = false; let clipboard = Clipboard::new(&window); @@ -190,21 +195,17 @@ pub trait Application: Sized { let surface = compositor.create_surface(&window); let mut renderer = compositor.create_renderer(backend_settings); - let mut swap_chain = { - let physical_size = size.physical(); - - compositor.create_swap_chain( - &surface, - physical_size.width, - physical_size.height, - ) - }; + let mut swap_chain = compositor.create_swap_chain( + &surface, + physical_size.width, + physical_size.height, + ); let user_interface = build_user_interface( &mut application, Cache::default(), &mut renderer, - size.logical(), + viewport.logical_size(), &mut debug, ); @@ -226,16 +227,11 @@ pub trait Application: Sized { return; } - // TODO: We should be able to keep a user interface alive - // between events once we remove state references. - // - // This will allow us to rebuild it only when a message is - // handled. let mut user_interface = build_user_interface( &mut application, cache.take().unwrap(), &mut renderer, - size.logical(), + viewport.logical_size(), &mut debug, ); @@ -306,7 +302,7 @@ pub trait Application: Sized { &mut application, temp_cache, &mut renderer, - size.logical(), + viewport.logical_size(), &mut debug, ); @@ -326,7 +322,7 @@ pub trait Application: Sized { debug.render_started(); if resized { - let physical_size = size.physical(); + let physical_size = viewport.physical_size(); swap_chain = compositor.create_swap_chain( &surface, @@ -340,8 +336,8 @@ pub trait Application: Sized { let new_mouse_interaction = compositor.draw( &mut renderer, &mut swap_chain, + &viewport, &primitive, - size.scale_factor(), &debug.overlay(), ); @@ -364,7 +360,12 @@ pub trait Application: Sized { } => { match window_event { WindowEvent::Resized(new_size) => { - size = Size::new(new_size, window.scale_factor()); + let size = Size::new(new_size.width, new_size.height); + + viewport = Viewport::with_physical_size( + size, + window.scale_factor(), + ); resized = true; } WindowEvent::CloseRequested => { @@ -402,7 +403,7 @@ pub trait Application: Sized { if let Some(event) = conversion::window_event( &window_event, - size.scale_factor(), + viewport.scale_factor(), modifiers, ) { events.push(event); @@ -419,7 +420,7 @@ fn build_user_interface<'a, A: Application>( application: &'a mut A, cache: Cache, renderer: &mut ::Renderer, - size: winit::dpi::LogicalSize, + size: Size, debug: &mut Debug, ) -> UserInterface< 'a, @@ -431,15 +432,7 @@ fn build_user_interface<'a, A: Application>( debug.view_finished(); debug.layout_started(); - let user_interface = UserInterface::build( - view, - iced_native::Size::new( - size.width.round() as f32, - size.height.round() as f32, - ), - cache, - renderer, - ); + let user_interface = UserInterface::build(view, size, cache, renderer); debug.layout_finished(); user_interface diff --git a/winit/src/lib.rs b/winit/src/lib.rs index f99e1290..b0f235ad 100644 --- a/winit/src/lib.rs +++ b/winit/src/lib.rs @@ -32,7 +32,6 @@ mod application; mod clipboard; mod mode; mod proxy; -mod size; // We disable debug capabilities on release builds unless the `debug` feature // is explicitly enabled.