diff options
author | 2020-05-19 22:55:12 +0200 | |
---|---|---|
committer | 2020-05-19 23:19:39 +0200 | |
commit | 720e7756f2afe30706b6b1a7fbde86b9f15e1d8c (patch) | |
tree | 3a55248a4b25654b1d63b8c547fd0f653471606d /glow | |
parent | e6180912488db4d59fbffcb46c5930282306cb92 (diff) | |
download | iced-720e7756f2afe30706b6b1a7fbde86b9f15e1d8c.tar.gz iced-720e7756f2afe30706b6b1a7fbde86b9f15e1d8c.tar.bz2 iced-720e7756f2afe30706b6b1a7fbde86b9f15e1d8c.zip |
Move `Layer` to `iced_graphics`
Diffstat (limited to 'glow')
-rw-r--r-- | glow/src/backend.rs | 291 | ||||
-rw-r--r-- | glow/src/lib.rs | 1 | ||||
-rw-r--r-- | glow/src/quad.rs | 33 | ||||
-rw-r--r-- | glow/src/triangle.rs | 5 |
4 files changed, 50 insertions, 280 deletions
diff --git a/glow/src/backend.rs b/glow/src/backend.rs index 94683e56..fb6782e6 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -1,12 +1,13 @@ use crate::quad; use crate::text; use crate::triangle; -use crate::{Quad, Settings, Transformation, Viewport}; +use crate::{Settings, Transformation, Viewport}; use iced_graphics::backend; use iced_graphics::font; +use iced_graphics::Layer; use iced_graphics::Primitive; use iced_native::mouse; -use iced_native::{Background, Font, Point, Rectangle, Size, Vector}; +use iced_native::{Font, HorizontalAlignment, Size, VerticalAlignment}; /// A [`glow`] renderer. /// @@ -18,30 +19,6 @@ pub struct Backend { triangle_pipeline: triangle::Pipeline, } -struct Layer<'a> { - bounds: Rectangle<u32>, - quads: Vec<Quad>, - text: Vec<glow_glyph::Section<'a>>, - meshes: Vec<(Vector, Rectangle<u32>, &'a triangle::Mesh2D)>, -} - -impl<'a> Layer<'a> { - pub fn new(bounds: Rectangle<u32>) -> Self { - Self { - bounds, - quads: Vec::new(), - text: Vec::new(), - meshes: Vec::new(), - } - } - - pub fn intersection(&self, rectangle: Rectangle) -> Option<Rectangle<u32>> { - let layer_bounds: Rectangle<f32> = self.bounds.into(); - - layer_bounds.intersection(&rectangle).map(Into::into) - } -} - impl Backend { /// Creates a new [`Renderer`]. /// @@ -71,23 +48,14 @@ impl Backend { viewport: &Viewport, (primitive, mouse_interaction): &(Primitive, mouse::Interaction), scale_factor: f64, - overlay: &[T], + overlay_text: &[T], ) -> mouse::Interaction { let (width, height) = viewport.dimensions(); let scale_factor = scale_factor as f32; let transformation = viewport.transformation(); - let mut layers = Vec::new(); - - layers.push(Layer::new(Rectangle { - x: 0, - y: 0, - width: (width as f32 / scale_factor).round() as u32, - height: (height as f32 / scale_factor).round() as u32, - })); - - self.draw_primitive(Vector::new(0.0, 0.0), primitive, &mut layers); - self.draw_overlay(overlay, &mut layers); + let mut layers = Layer::generate(primitive, viewport); + layers.push(Layer::overlay(overlay_text, viewport)); for layer in layers { self.flush( @@ -104,213 +72,6 @@ impl Backend { *mouse_interaction } - fn draw_primitive<'a>( - &mut self, - translation: Vector, - primitive: &'a Primitive, - layers: &mut Vec<Layer<'a>>, - ) { - match primitive { - Primitive::None => {} - Primitive::Group { primitives } => { - // TODO: Inspect a bit and regroup (?) - for primitive in primitives { - self.draw_primitive(translation, primitive, layers) - } - } - Primitive::Text { - content, - bounds, - size, - color, - font, - horizontal_alignment, - vertical_alignment, - } => { - let layer = layers.last_mut().unwrap(); - - layer.text.push(glow_glyph::Section { - text: &content, - screen_position: ( - bounds.x + translation.x, - bounds.y + translation.y, - ), - bounds: (bounds.width, bounds.height), - scale: glow_glyph::Scale { x: *size, y: *size }, - color: color.into_linear(), - font_id: self.text_pipeline.find_font(*font), - layout: glow_glyph::Layout::default() - .h_align(match horizontal_alignment { - iced_native::HorizontalAlignment::Left => { - glow_glyph::HorizontalAlign::Left - } - iced_native::HorizontalAlignment::Center => { - glow_glyph::HorizontalAlign::Center - } - iced_native::HorizontalAlignment::Right => { - glow_glyph::HorizontalAlign::Right - } - }) - .v_align(match vertical_alignment { - iced_native::VerticalAlignment::Top => { - glow_glyph::VerticalAlign::Top - } - iced_native::VerticalAlignment::Center => { - glow_glyph::VerticalAlign::Center - } - iced_native::VerticalAlignment::Bottom => { - glow_glyph::VerticalAlign::Bottom - } - }), - ..Default::default() - }) - } - Primitive::Quad { - bounds, - background, - border_radius, - border_width, - border_color, - } => { - let layer = layers.last_mut().unwrap(); - - // TODO: Move some of these computations to the GPU (?) - layer.quads.push(Quad { - position: [ - bounds.x + translation.x, - bounds.y + translation.y, - ], - scale: [bounds.width, bounds.height], - color: match background { - Background::Color(color) => color.into_linear(), - }, - border_radius: *border_radius as f32, - border_width: *border_width as f32, - border_color: border_color.into_linear(), - }); - } - Primitive::Mesh2D { size, buffers } => { - let layer = layers.last_mut().unwrap(); - - // Only draw visible content - if let Some(clip_bounds) = layer.intersection(Rectangle::new( - Point::new(translation.x, translation.y), - *size, - )) { - layer.meshes.push(( - translation, - clip_bounds.into(), - buffers, - )); - } - } - Primitive::Clip { - bounds, - offset, - content, - } => { - let layer = layers.last_mut().unwrap(); - - // Only draw visible content - if let Some(clip_bounds) = - layer.intersection(*bounds + translation) - { - let clip_layer = Layer::new(clip_bounds.into()); - let new_layer = Layer::new(layer.bounds); - - layers.push(clip_layer); - self.draw_primitive( - translation - - Vector::new(offset.x as f32, offset.y as f32), - content, - layers, - ); - layers.push(new_layer); - } - } - Primitive::Translate { - translation: new_translation, - content, - } => { - self.draw_primitive( - translation + *new_translation, - &content, - layers, - ); - } - - Primitive::Cached { cache } => { - self.draw_primitive(translation, &cache, layers); - } - - #[cfg(feature = "image")] - Primitive::Image { handle, bounds } => { - let layer = layers.last_mut().unwrap(); - - layer.images.push(Image { - handle: image::Handle::Raster(handle.clone()), - position: [ - bounds.x + translation.x, - bounds.y + translation.y, - ], - size: [bounds.width, bounds.height], - }); - } - #[cfg(not(feature = "image"))] - Primitive::Image { .. } => {} - - #[cfg(feature = "svg")] - Primitive::Svg { handle, bounds } => { - let layer = layers.last_mut().unwrap(); - - layer.images.push(Image { - handle: image::Handle::Vector(handle.clone()), - position: [ - bounds.x + translation.x, - bounds.y + translation.y, - ], - size: [bounds.width, bounds.height], - }); - } - #[cfg(not(feature = "svg"))] - Primitive::Svg { .. } => {} - } - } - - fn draw_overlay<'a, T: AsRef<str>>( - &mut self, - lines: &'a [T], - layers: &mut Vec<Layer<'a>>, - ) { - let first = layers.first().unwrap(); - let mut overlay = Layer::new(first.bounds); - - let font_id = self.text_pipeline.overlay_font(); - let scale = glow_glyph::Scale { x: 20.0, y: 20.0 }; - - for (i, line) in lines.iter().enumerate() { - overlay.text.push(glow_glyph::Section { - text: line.as_ref(), - screen_position: (11.0, 11.0 + 25.0 * i as f32), - color: [0.9, 0.9, 0.9, 1.0], - scale, - font_id, - ..glow_glyph::Section::default() - }); - - overlay.text.push(glow_glyph::Section { - text: line.as_ref(), - screen_position: (10.0, 10.0 + 25.0 * i as f32), - color: [0.0, 0.0, 0.0, 1.0], - scale, - font_id, - ..glow_glyph::Section::default() - }); - } - - layers.push(overlay); - } - fn flush( &mut self, gl: &glow::Context, @@ -352,13 +113,14 @@ impl Backend { for text in layer.text.iter() { // Target physical coordinates directly to avoid blurry text let text = glow_glyph::Section { + text: text.content, // TODO: We `round` here to avoid rerasterizing text when // its position changes slightly. This can make text feel a // bit "jumpy". We may be able to do better once we improve // our text rendering/caching pipeline. screen_position: ( - (text.screen_position.0 * scale_factor).round(), - (text.screen_position.1 * scale_factor).round(), + (text.bounds.x * scale_factor).round(), + (text.bounds.y * scale_factor).round(), ), // TODO: Fix precision issues with some scale factors. // @@ -370,14 +132,39 @@ impl Backend { // scaling when rendering. This would ensure that both // measuring and rendering follow the same layout rules. bounds: ( - (text.bounds.0 * scale_factor).ceil(), - (text.bounds.1 * scale_factor).ceil(), + (text.bounds.width * scale_factor).ceil(), + (text.bounds.height * scale_factor).ceil(), ), scale: glow_glyph::Scale { - x: text.scale.x * scale_factor, - y: text.scale.y * scale_factor, + x: text.size * scale_factor, + y: text.size * scale_factor, }, - ..*text + color: text.color, + font_id: self.text_pipeline.find_font(text.font), + layout: glow_glyph::Layout::default() + .h_align(match text.horizontal_alignment { + HorizontalAlignment::Left => { + glow_glyph::HorizontalAlign::Left + } + HorizontalAlignment::Center => { + glow_glyph::HorizontalAlign::Center + } + HorizontalAlignment::Right => { + glow_glyph::HorizontalAlign::Right + } + }) + .v_align(match text.vertical_alignment { + VerticalAlignment::Top => { + glow_glyph::VerticalAlign::Top + } + VerticalAlignment::Center => { + glow_glyph::VerticalAlign::Center + } + VerticalAlignment::Bottom => { + glow_glyph::VerticalAlign::Bottom + } + }), + ..Default::default() }; self.text_pipeline.queue(text); diff --git a/glow/src/lib.rs b/glow/src/lib.rs index 724065bd..d40ed0ae 100644 --- a/glow/src/lib.rs +++ b/glow/src/lib.rs @@ -17,7 +17,6 @@ pub use settings::Settings; pub(crate) use backend::Backend; pub(crate) use iced_graphics::Transformation; -pub(crate) use quad::Quad; pub type Renderer = iced_graphics::Renderer<Backend>; diff --git a/glow/src/quad.rs b/glow/src/quad.rs index 744597d2..26424b39 100644 --- a/glow/src/quad.rs +++ b/glow/src/quad.rs @@ -1,7 +1,10 @@ use crate::{Transformation, Viewport}; use glow::HasContext; +use iced_graphics::layer; use iced_native::Rectangle; +const MAX_INSTANCES: usize = 100_000; + #[derive(Debug)] pub struct Pipeline { program: <glow::Context as HasContext>::Program, @@ -37,7 +40,7 @@ impl Pipeline { } let (vertex_array, instances) = - unsafe { create_instance_buffer(gl, Quad::MAX) }; + unsafe { create_instance_buffer(gl, MAX_INSTANCES) }; Pipeline { program, @@ -52,7 +55,7 @@ impl Pipeline { &mut self, gl: &glow::Context, viewport: &Viewport, - instances: &[Quad], + instances: &[layer::Quad], transformation: Transformation, scale: f32, bounds: Rectangle<u32>, @@ -97,7 +100,7 @@ impl Pipeline { let total = instances.len(); while i < total { - let end = (i + Quad::MAX).min(total); + let end = (i + MAX_INSTANCES).min(total); let amount = end - i; unsafe { @@ -115,7 +118,7 @@ impl Pipeline { ); } - i += Quad::MAX; + i += MAX_INSTANCES; } unsafe { @@ -126,24 +129,6 @@ impl Pipeline { } } -#[derive(Debug, Clone, Copy)] -#[repr(C)] -pub struct Quad { - pub position: [f32; 2], - pub scale: [f32; 2], - pub color: [f32; 4], - pub border_color: [f32; 4], - pub border_radius: f32, - pub border_width: f32, -} - -unsafe impl bytemuck::Zeroable for Quad {} -unsafe impl bytemuck::Pod for Quad {} - -impl Quad { - const MAX: usize = 100_000; -} - unsafe fn create_program( gl: &glow::Context, shader_sources: &[(u32, &str)], @@ -196,11 +181,11 @@ unsafe fn create_instance_buffer( gl.bind_buffer(glow::ARRAY_BUFFER, Some(buffer)); gl.buffer_data_size( glow::ARRAY_BUFFER, - (size * std::mem::size_of::<Quad>()) as i32, + (size * std::mem::size_of::<layer::Quad>()) as i32, glow::DYNAMIC_DRAW, ); - let stride = std::mem::size_of::<Quad>() as i32; + let stride = std::mem::size_of::<layer::Quad>() as i32; gl.enable_vertex_attrib_array(0); gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, stride, 0); diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 8b21c0a8..5836f0cf 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -1,7 +1,6 @@ //! Draw meshes of triangles. use crate::{settings, Transformation}; -use iced_native::{Rectangle, Vector}; -use std::mem; +use iced_graphics::layer; pub use iced_graphics::triangle::Mesh2D; @@ -27,7 +26,7 @@ impl Pipeline { target_height: u32, transformation: Transformation, scale_factor: f32, - meshes: &[(Vector, Rectangle<u32>, &Mesh2D)], + meshes: &[layer::Mesh<'_>], ) { } } |