From eb6c663420a28e087c91c39e376db3c294b5aea1 Mon Sep 17 00:00:00 2001 From: Bingus Date: Fri, 26 May 2023 09:55:49 -0700 Subject: [PATCH] Adjusted `Quads` struct to be opaque `quad::Layer`. --- wgpu/src/backend.rs | 2 +- wgpu/src/layer.rs | 87 ++--------------------------------------- wgpu/src/layer/quad.rs | 89 ++++++++++++++++++++++++++++++++++++++++++ wgpu/src/quad.rs | 37 +++++++----------- 4 files changed, 109 insertions(+), 106 deletions(-) diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 764a033bf2..844987f200 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -268,7 +268,7 @@ impl Backend { self.quad_pipeline.render( quad_layer, bounds, - &layer.quads.order, + &layer.quads, &mut render_pass, ); diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index f5c4b57677..4e028eac40 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -12,8 +12,7 @@ pub use text::Text; use crate::core; use crate::core::alignment; -use crate::core::{Background, Color, Font, Point, Rectangle, Size, Vector}; -use crate::graphics::gradient; +use crate::core::{Color, Font, Point, Rectangle, Size, Vector}; use crate::graphics::{Primitive, Viewport}; /// A group of primitives that should be clipped together. @@ -23,7 +22,7 @@ pub struct Layer<'a> { pub bounds: Rectangle, /// The quads of the [`Layer`]. - pub quads: Quads, + pub quads: quad::Layer, /// The triangle meshes of the [`Layer`]. pub meshes: Vec>, @@ -35,35 +34,12 @@ pub struct Layer<'a> { pub images: Vec, } -/// The quads of the [`Layer`]. -#[derive(Default, Debug)] -pub struct Quads { - /// The solid quads of the [`Layer`]. - pub solids: Vec, - - /// The gradient quads of the [`Layer`]. - pub gradients: Vec, - - /// The quad order of the [`Layer`]; stored as a tuple of the quad type & its count. - pub order: Vec<(quad::Order, usize)>, - - // The last index of quad ordering. - index: usize, -} - -impl Quads { - /// Returns true if there are no quads of any type in [`Quads`]. - pub fn is_empty(&self) -> bool { - self.solids.is_empty() && self.gradients.is_empty() - } -} - impl<'a> Layer<'a> { /// Creates a new [`Layer`] with the given clipping bounds. pub fn new(bounds: Rectangle) -> Self { Self { bounds, - quads: Quads::default(), + quads: quad::Layer::default(), meshes: Vec::new(), text: Vec::new(), images: Vec::new(), @@ -180,62 +156,7 @@ impl<'a> Layer<'a> { border_width: *border_width, }; - let quad_order = match background { - Background::Color(color) => { - layer.quads.solids.push(quad::Solid { - color: color.into_linear(), - quad, - }); - quad::Order::Solid - } - Background::Gradient(gradient) => { - let quad = quad::Gradient { - gradient: gradient::pack( - gradient, - Rectangle::new( - quad.position.into(), - quad.size.into(), - ), - ), - quad, - }; - - layer.quads.gradients.push(quad); - quad::Order::Gradient - } - }; - - match (layer.quads.order.get_mut(layer.quads.index), quad_order) - { - (Some((quad_order, count)), quad::Order::Solid) => { - match quad_order { - quad::Order::Solid => { - *count += 1; - } - quad::Order::Gradient => { - layer.quads.order.push((quad::Order::Solid, 1)); - layer.quads.index += 1; - } - } - } - (Some((quad_order, count)), quad::Order::Gradient) => { - match quad_order { - quad::Order::Solid => { - layer - .quads - .order - .push((quad::Order::Gradient, 1)); - layer.quads.index += 1; - } - quad::Order::Gradient => { - *count += 1; - } - } - } - (None, _) => { - layer.quads.order.push((quad_order, 1)); - } - } + layer.quads.add(quad, background); } Primitive::Image { handle, bounds } => { let layer = &mut layers[current_layer]; diff --git a/wgpu/src/layer/quad.rs b/wgpu/src/layer/quad.rs index aaaebd5b70..284a761807 100644 --- a/wgpu/src/layer/quad.rs +++ b/wgpu/src/layer/quad.rs @@ -1,4 +1,5 @@ //! A rectangle with certain styled properties. +use crate::core::{Background, Rectangle}; use crate::graphics::gradient; use bytemuck::{Pod, Zeroable}; @@ -58,3 +59,91 @@ pub enum Order { /// A gradient quad Gradient, } + +/// A group of [`Quad`]s rendered together. +#[derive(Default, Debug)] +pub struct Layer { + /// The solid quads of the [`Layer`]. + solids: Vec, + + /// The gradient quads of the [`Layer`]. + gradients: Vec, + + /// The quad order of the [`Layer`]; stored as a tuple of the quad type & its count. + order: Vec<(Order, usize)>, + + /// The last index of quad ordering. + index: usize, +} + +impl Layer { + /// Returns true if there are no quads of any type in [`Quads`]. + pub fn is_empty(&self) -> bool { + self.solids.is_empty() && self.gradients.is_empty() + } + + /// The [`Solid`] quads of the [`Layer`]. + pub fn solids(&self) -> &[Solid] { + &self.solids + } + + /// The [`Gradient`] quads of the [`Layer`]. + pub fn gradients(&self) -> &[Gradient] { + &self.gradients + } + + /// The order of quads within the [`Layer`], grouped by (type, count) for rendering in batches. + pub fn ordering(&self) -> &[(Order, usize)] { + &self.order + } + + /// Adds a [`Quad`] with the provided `Background` type to the quad [`Layer`]. + pub fn add(&mut self, quad: Quad, background: &Background) { + let quad_order = match background { + Background::Color(color) => { + self.solids.push(Solid { + color: color.into_linear(), + quad, + }); + + Order::Solid + } + Background::Gradient(gradient) => { + let quad = Gradient { + gradient: gradient::pack( + gradient, + Rectangle::new(quad.position.into(), quad.size.into()), + ), + quad, + }; + + self.gradients.push(quad); + Order::Gradient + } + }; + + match (self.order.get_mut(self.index), quad_order) { + (Some((quad_order, count)), Order::Solid) => match quad_order { + Order::Solid => { + *count += 1; + } + Order::Gradient => { + self.order.push((Order::Solid, 1)); + self.index += 1; + } + }, + (Some((quad_order, count)), Order::Gradient) => match quad_order { + Order::Solid => { + self.order.push((Order::Gradient, 1)); + self.index += 1; + } + Order::Gradient => { + *count += 1; + } + }, + (None, _) => { + self.order.push((quad_order, 1)); + } + } + } +} diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index a05e5468aa..065da15366 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -1,6 +1,6 @@ use crate::core::Rectangle; use crate::graphics::Transformation; -use crate::layer::{self, quad}; +use crate::layer::quad; use std::mem; use wgpu::util::DeviceExt; @@ -69,7 +69,7 @@ impl Pipeline { &mut self, device: &wgpu::Device, queue: &wgpu::Queue, - instances: &layer::Quads, + quads: &quad::Layer, transformation: Transformation, scale: f32, ) { @@ -78,7 +78,7 @@ impl Pipeline { } let layer = &mut self.layers[self.prepare_layer]; - layer.prepare(device, queue, instances, transformation, scale); + layer.prepare(device, queue, quads, transformation, scale); self.prepare_layer += 1; } @@ -87,7 +87,7 @@ impl Pipeline { &'a self, layer: usize, bounds: Rectangle, - ordering: &Vec<(quad::Order, usize)>, + quads: &quad::Layer, render_pass: &mut wgpu::RenderPass<'a>, ) { if let Some(layer) = self.layers.get(layer) { @@ -106,7 +106,7 @@ impl Pipeline { let mut solid_offset = 0; let mut gradient_offset = 0; - for (quad_order, count) in ordering { + for (quad_order, count) in quads.ordering() { match quad_order { quad::Order::Solid => { render_pass.set_pipeline(&self.solid.pipeline); @@ -177,7 +177,7 @@ impl Layer { &mut self, device: &wgpu::Device, queue: &wgpu::Queue, - instances: &layer::Quads, + quads: &quad::Layer, transformation: Transformation, scale: f32, ) { @@ -192,22 +192,15 @@ impl Layer { bytemuck::bytes_of(&uniforms), ); - let _ = self.solid.instances.resize(device, instances.solids.len()); - let _ = self - .gradient - .instances - .resize(device, instances.gradients.len()); - let _ = - self.solid - .instances - .write(queue, 0, instances.solids.as_slice()); - self.solid.instance_count = instances.solids.len(); - let _ = self.gradient.instances.write( - queue, - 0, - instances.gradients.as_slice(), - ); - self.gradient.instance_count = instances.gradients.len(); + let solids = quads.solids(); + let gradients = quads.gradients(); + + let _ = self.solid.instances.resize(device, solids.len()); + let _ = self.gradient.instances.resize(device, gradients.len()); + let _ = self.solid.instances.write(queue, 0, solids); + self.solid.instance_count = solids.len(); + let _ = self.gradient.instances.write(queue, 0, gradients); + self.gradient.instance_count = gradients.len(); } }