From 719c073fc67c87d6b2da1bc01b74751d3f5e59f0 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 25 Oct 2019 03:47:34 +0200 Subject: Draft `Scrollable` widget (no clipping yet!) --- wgpu/src/renderer.rs | 97 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 28 deletions(-) (limited to 'wgpu/src/renderer.rs') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index ab6f744f..bb0e7b27 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -20,6 +20,7 @@ mod column; mod image; mod radio; mod row; +mod scrollable; mod slider; mod text; @@ -31,8 +32,6 @@ pub struct Renderer { quad_pipeline: quad::Pipeline, image_pipeline: crate::image::Pipeline, - quads: Vec, - images: Vec, glyph_brush: Rc>>, } @@ -43,6 +42,24 @@ pub struct Target { swap_chain: SwapChain, } +pub struct Layer { + quads: Vec, + images: Vec, + layers: Vec, + y_offset: u32, +} + +impl Layer { + pub fn new(y_offset: u32) -> Self { + Self { + quads: Vec::new(), + images: Vec::new(), + layers: Vec::new(), + y_offset, + } + } +} + impl Renderer { fn new(window: &W) -> Self { let adapter = Adapter::request(&RequestAdapterOptions { @@ -79,8 +96,6 @@ impl Renderer { quad_pipeline, image_pipeline, - quads: Vec::new(), - images: Vec::new(), glyph_brush: Rc::new(RefCell::new(glyph_brush)), } } @@ -132,27 +147,10 @@ impl Renderer { depth_stencil_attachment: None, }); - self.draw_primitive(primitive); + let mut layer = Layer::new(0); - self.quad_pipeline.draw( - &mut self.device, - &mut encoder, - &self.quads, - target.transformation, - &frame.view, - ); - - self.quads.clear(); - - self.image_pipeline.draw( - &mut self.device, - &mut encoder, - &self.images, - target.transformation, - &frame.view, - ); - - self.images.clear(); + self.draw_primitive(primitive, &mut layer); + self.flush(target.transformation, &layer, &mut encoder, &frame.view); self.glyph_brush .borrow_mut() @@ -170,13 +168,13 @@ impl Renderer { *mouse_cursor } - fn draw_primitive(&mut self, primitive: &Primitive) { + fn draw_primitive(&mut self, primitive: &Primitive, layer: &mut Layer) { match primitive { Primitive::None => {} Primitive::Group { primitives } => { // TODO: Inspect a bit and regroup (?) for primitive in primitives { - self.draw_primitive(primitive) + self.draw_primitive(primitive, layer) } } Primitive::Text { @@ -244,7 +242,7 @@ impl Renderer { background, border_radius, } => { - self.quads.push(Quad { + layer.quads.push(Quad { position: [bounds.x, bounds.y], scale: [bounds.width, bounds.height], color: match background { @@ -254,12 +252,55 @@ impl Renderer { }); } Primitive::Image { path, bounds } => { - self.images.push(Image { + layer.images.push(Image { path: path.clone(), position: [bounds.x, bounds.y], scale: [bounds.width, bounds.height], }); } + Primitive::Scrollable { + bounds, + offset, + content, + } => { + let mut new_layer = Layer::new(layer.y_offset + offset); + + // TODO: Primitive culling + self.draw_primitive(content, &mut new_layer); + + layer.layers.push(new_layer); + } + } + } + + fn flush( + &mut self, + transformation: Transformation, + layer: &Layer, + encoder: &mut wgpu::CommandEncoder, + target: &wgpu::TextureView, + ) { + let translated = transformation + * Transformation::translate(0.0, -(layer.y_offset as f32)); + + self.quad_pipeline.draw( + &mut self.device, + encoder, + &layer.quads, + transformation, + target, + ); + + self.image_pipeline.draw( + &mut self.device, + encoder, + &layer.images, + translated, + target, + ); + + for layer in layer.layers.iter() { + self.flush(transformation, layer, encoder, target); } } } -- cgit From 0a0aa3edd9c5185551040c75a934f12d3bce7618 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 27 Oct 2019 02:29:23 +0100 Subject: Implement clipping for images --- wgpu/src/renderer.rs | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) (limited to 'wgpu/src/renderer.rs') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index bb0e7b27..d838c6ee 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -1,7 +1,7 @@ use crate::{quad, Image, Primitive, Quad, Transformation}; use iced_native::{ renderer::Debugger, renderer::Windowed, Background, Color, Layout, - MouseCursor, Point, Widget, + MouseCursor, Point, Rectangle, Widget, }; use raw_window_handle::HasRawWindowHandle; @@ -43,19 +43,21 @@ pub struct Target { } pub struct Layer { + bounds: Rectangle, + y_offset: u32, quads: Vec, images: Vec, layers: Vec, - y_offset: u32, } impl Layer { - pub fn new(y_offset: u32) -> Self { + pub fn new(bounds: Rectangle, y_offset: u32) -> Self { Self { + bounds, + y_offset, quads: Vec::new(), images: Vec::new(), layers: Vec::new(), - y_offset, } } } @@ -147,7 +149,15 @@ impl Renderer { depth_stencil_attachment: None, }); - let mut layer = Layer::new(0); + let mut layer = Layer::new( + Rectangle { + x: 0, + y: 0, + width: u32::from(target.width), + height: u32::from(target.height), + }, + 0, + ); self.draw_primitive(primitive, &mut layer); self.flush(target.transformation, &layer, &mut encoder, &frame.view); @@ -263,7 +273,15 @@ impl Renderer { offset, content, } => { - let mut new_layer = Layer::new(layer.y_offset + offset); + let mut new_layer = Layer::new( + Rectangle { + x: bounds.x as u32, + y: bounds.y as u32 - layer.y_offset, + width: bounds.width as u32, + height: bounds.height as u32, + }, + layer.y_offset + offset, + ); // TODO: Primitive culling self.draw_primitive(content, &mut new_layer); @@ -296,6 +314,7 @@ impl Renderer { encoder, &layer.images, translated, + layer.bounds, target, ); -- cgit From e2668b882a8115fd0afcd32373edb180492908b1 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 27 Oct 2019 02:30:19 +0100 Subject: Remove `adapter` from `iced_wgpu::Renderer` --- wgpu/src/renderer.rs | 2 -- 1 file changed, 2 deletions(-) (limited to 'wgpu/src/renderer.rs') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index d838c6ee..5bd7be8d 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -26,7 +26,6 @@ mod text; pub struct Renderer { surface: Surface, - adapter: Adapter, device: Device, queue: Queue, quad_pipeline: quad::Pipeline, @@ -92,7 +91,6 @@ impl Renderer { Self { surface, - adapter, device, queue, quad_pipeline, -- cgit From 21eb2f692c687a675c54ae5e951556e28e7435eb Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 27 Oct 2019 03:10:49 +0100 Subject: Implement clipping for quads --- wgpu/src/renderer.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'wgpu/src/renderer.rs') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 5bd7be8d..ba140a66 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -251,7 +251,7 @@ impl Renderer { border_radius, } => { layer.quads.push(Quad { - position: [bounds.x, bounds.y], + position: [bounds.x, bounds.y - layer.y_offset as f32], scale: [bounds.width, bounds.height], color: match background { Background::Color(color) => color.into_linear(), @@ -304,6 +304,7 @@ impl Renderer { encoder, &layer.quads, transformation, + layer.bounds, target, ); -- cgit From 35e94f5a324f5c28de855b725039733efb21b26a Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Sun, 27 Oct 2019 03:11:54 +0100 Subject: Draft text scrolling (no clipping yet!) --- wgpu/src/renderer.rs | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'wgpu/src/renderer.rs') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index ba140a66..cfdd7a45 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -41,21 +41,23 @@ pub struct Target { swap_chain: SwapChain, } -pub struct Layer { +pub struct Layer<'a> { bounds: Rectangle, y_offset: u32, quads: Vec, images: Vec, - layers: Vec, + text: Vec>, + layers: Vec>, } -impl Layer { +impl<'a> Layer<'a> { pub fn new(bounds: Rectangle, y_offset: u32) -> Self { Self { bounds, y_offset, quads: Vec::new(), images: Vec::new(), + text: Vec::new(), layers: Vec::new(), } } @@ -176,7 +178,11 @@ impl Renderer { *mouse_cursor } - fn draw_primitive(&mut self, primitive: &Primitive, layer: &mut Layer) { + fn draw_primitive<'a>( + &mut self, + primitive: &'a Primitive, + layer: &mut Layer<'a>, + ) { match primitive { Primitive::None => {} Primitive::Group { primitives } => { @@ -213,7 +219,7 @@ impl Renderer { } }; - self.glyph_brush.borrow_mut().queue(Section { + layer.text.push(Section { text: &content, screen_position: (x, y), bounds: (bounds.width, bounds.height), @@ -317,6 +323,23 @@ impl Renderer { target, ); + { + let mut glyph_brush = self.glyph_brush.borrow_mut(); + + for text in layer.text.iter() { + glyph_brush.queue(text); + } + + glyph_brush + .draw_queued_with_transform( + &mut self.device, + encoder, + target, + translated.into(), + ) + .expect("Draw text"); + } + for layer in layer.layers.iter() { self.flush(transformation, layer, encoder, target); } -- cgit From 2b23e0986c532dbacd89ccd73bb603db558cbdaf Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Mon, 28 Oct 2019 04:28:21 +0100 Subject: Implement text clipping (caching still broken) --- wgpu/src/renderer.rs | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'wgpu/src/renderer.rs') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index cfdd7a45..0f91428e 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -75,7 +75,7 @@ impl Renderer { extensions: Extensions { anisotropic_filtering: false, }, - limits: Limits { max_bind_groups: 1 }, + limits: Limits { max_bind_groups: 2 }, }); let surface = Surface::create(window); @@ -162,17 +162,6 @@ impl Renderer { self.draw_primitive(primitive, &mut layer); self.flush(target.transformation, &layer, &mut encoder, &frame.view); - self.glyph_brush - .borrow_mut() - .draw_queued( - &mut self.device, - &mut encoder, - &frame.view, - u32::from(target.width), - u32::from(target.height), - ) - .expect("Draw text"); - self.queue.submit(&[encoder.finish()]); *mouse_cursor @@ -331,11 +320,17 @@ impl Renderer { } glyph_brush - .draw_queued_with_transform( + .draw_queued_with_transform_and_scissoring( &mut self.device, encoder, target, translated.into(), + wgpu_glyph::Region { + x: layer.bounds.x, + y: layer.bounds.y, + width: layer.bounds.width, + height: layer.bounds.height, + }, ) .expect("Draw text"); } -- cgit From 23ebfb707a52d03a7beceaa5e197b4491619ae1d Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 29 Oct 2019 01:21:28 +0100 Subject: Issue draw calls only when necessary --- wgpu/src/renderer.rs | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) (limited to 'wgpu/src/renderer.rs') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index 0f91428e..bb7cb858 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -294,25 +294,29 @@ impl Renderer { let translated = transformation * Transformation::translate(0.0, -(layer.y_offset as f32)); - self.quad_pipeline.draw( - &mut self.device, - encoder, - &layer.quads, - transformation, - layer.bounds, - target, - ); + if layer.quads.len() > 0 { + self.quad_pipeline.draw( + &mut self.device, + encoder, + &layer.quads, + transformation, + layer.bounds, + target, + ); + } - self.image_pipeline.draw( - &mut self.device, - encoder, - &layer.images, - translated, - layer.bounds, - target, - ); + if layer.images.len() > 0 { + self.image_pipeline.draw( + &mut self.device, + encoder, + &layer.images, + translated, + layer.bounds, + target, + ); + } - { + if layer.text.len() > 0 { let mut glyph_brush = self.glyph_brush.borrow_mut(); for text in layer.text.iter() { -- cgit From be488ac73837c9a741d900617840ee5c4ed74d61 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 29 Oct 2019 02:00:17 +0100 Subject: Draw scrollbar on top of scrollable content --- wgpu/src/renderer.rs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'wgpu/src/renderer.rs') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index bb7cb858..f0be0860 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -47,7 +47,6 @@ pub struct Layer<'a> { quads: Vec, images: Vec, text: Vec>, - layers: Vec>, } impl<'a> Layer<'a> { @@ -58,7 +57,6 @@ impl<'a> Layer<'a> { quads: Vec::new(), images: Vec::new(), text: Vec::new(), - layers: Vec::new(), } } } @@ -149,7 +147,8 @@ impl Renderer { depth_stencil_attachment: None, }); - let mut layer = Layer::new( + let mut layers = Vec::new(); + let mut current = Layer::new( Rectangle { x: 0, y: 0, @@ -159,8 +158,17 @@ impl Renderer { 0, ); - self.draw_primitive(primitive, &mut layer); - self.flush(target.transformation, &layer, &mut encoder, &frame.view); + self.draw_primitive(primitive, &mut current, &mut layers); + layers.push(current); + + for layer in layers { + self.flush( + target.transformation, + &layer, + &mut encoder, + &frame.view, + ); + } self.queue.submit(&[encoder.finish()]); @@ -171,13 +179,14 @@ impl Renderer { &mut self, primitive: &'a Primitive, layer: &mut Layer<'a>, + layers: &mut Vec>, ) { match primitive { Primitive::None => {} Primitive::Group { primitives } => { // TODO: Inspect a bit and regroup (?) for primitive in primitives { - self.draw_primitive(primitive, layer) + self.draw_primitive(primitive, layer, layers) } } Primitive::Text { @@ -277,9 +286,9 @@ impl Renderer { ); // TODO: Primitive culling - self.draw_primitive(content, &mut new_layer); + self.draw_primitive(content, &mut new_layer, layers); - layer.layers.push(new_layer); + layers.push(new_layer); } } } @@ -338,10 +347,6 @@ impl Renderer { ) .expect("Draw text"); } - - for layer in layer.layers.iter() { - self.flush(transformation, layer, encoder, target); - } } } -- cgit From 85916c9e8710ee90cbf37d384acbb6d208ff1da3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 29 Oct 2019 19:50:34 +0100 Subject: Rename `Primitive::Scrollable` to `Clip` --- wgpu/src/renderer.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'wgpu/src/renderer.rs') diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs index f0be0860..a70693af 100644 --- a/wgpu/src/renderer.rs +++ b/wgpu/src/renderer.rs @@ -270,7 +270,7 @@ impl Renderer { scale: [bounds.width, bounds.height], }); } - Primitive::Scrollable { + Primitive::Clip { bounds, offset, content, -- cgit