summaryrefslogtreecommitdiffstats
path: root/wgpu
diff options
context:
space:
mode:
Diffstat (limited to 'wgpu')
-rw-r--r--wgpu/Cargo.toml5
-rw-r--r--wgpu/src/backend.rs261
-rw-r--r--wgpu/src/image.rs10
-rw-r--r--wgpu/src/quad.rs10
-rw-r--r--wgpu/src/text.rs40
-rw-r--r--wgpu/src/triangle.rs10
-rw-r--r--wgpu/src/window/compositor.rs29
7 files changed, 195 insertions, 170 deletions
diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml
index b3fbfc00..7a6b75f0 100644
--- a/wgpu/Cargo.toml
+++ b/wgpu/Cargo.toml
@@ -59,8 +59,9 @@ path = "../graphics"
[dependencies.glyphon]
version = "0.2"
-git = "https://github.com/hecrj/glyphon.git"
-rev = "3c2acb9dea5b9fcb0fa650b3c73b3a3242c62f4a"
+# git = "https://github.com/hecrj/glyphon.git"
+# rev = "3c2acb9dea5b9fcb0fa650b3c73b3a3242c62f4a"
+path = "../../glyphon"
[dependencies.tracing]
version = "0.1.6"
diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs
index 8c4c0daa..9d1e3d1c 100644
--- a/wgpu/src/backend.rs
+++ b/wgpu/src/backend.rs
@@ -5,8 +5,7 @@ use crate::{Settings, Transformation};
use iced_graphics::backend;
use iced_graphics::layer::Layer;
-use iced_graphics::{Primitive, Viewport};
-use iced_native::{Font, Size};
+use iced_graphics::{Color, Font, Primitive, Size, Viewport};
#[cfg(feature = "tracing")]
use tracing::info_span;
@@ -71,6 +70,7 @@ impl Backend {
device: &wgpu::Device,
queue: &wgpu::Queue,
encoder: &mut wgpu::CommandEncoder,
+ clear_color: Option<Color>,
frame: &wgpu::TextureView,
primitives: &[Primitive],
viewport: &Viewport,
@@ -87,18 +87,25 @@ impl Backend {
let mut layers = Layer::generate(primitives, viewport);
layers.push(Layer::overlay(overlay_text, viewport));
- for layer in layers {
- self.flush(
- device,
- queue,
- scale_factor,
- transformation,
- &layer,
- encoder,
- frame,
- target_size,
- );
- }
+ self.prepare(
+ device,
+ queue,
+ encoder,
+ scale_factor,
+ transformation,
+ target_size,
+ &layers,
+ );
+
+ self.render(
+ device,
+ encoder,
+ frame,
+ clear_color,
+ scale_factor,
+ target_size,
+ &layers,
+ );
self.quad_pipeline.end_frame();
self.text_pipeline.end_frame();
@@ -108,90 +115,153 @@ impl Backend {
self.image_pipeline.end_frame(device, queue, encoder);
}
- fn flush(
+ fn prepare(
&mut self,
device: &wgpu::Device,
queue: &wgpu::Queue,
+ _encoder: &mut wgpu::CommandEncoder,
scale_factor: f32,
transformation: Transformation,
- layer: &Layer<'_>,
- encoder: &mut wgpu::CommandEncoder,
- target: &wgpu::TextureView,
target_size: Size<u32>,
+ layers: &[Layer<'_>],
) {
- let bounds = (layer.bounds * scale_factor).snap();
+ for layer in layers {
+ let bounds = (layer.bounds * scale_factor).snap();
- if bounds.width < 1 || bounds.height < 1 {
- return;
- }
+ if bounds.width < 1 || bounds.height < 1 {
+ return;
+ }
- if !layer.quads.is_empty() {
- self.quad_pipeline.prepare(
- device,
- queue,
- &layer.quads,
- transformation,
- scale_factor,
- );
-
- let mut render_pass =
- encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- label: Some("iced_wgpu::quad render pass"),
- color_attachments: &[Some(
- wgpu::RenderPassColorAttachment {
- view: target,
- resolve_target: None,
- ops: wgpu::Operations {
- load: wgpu::LoadOp::Load,
- store: true,
- },
- },
- )],
- depth_stencil_attachment: None,
- });
+ if !layer.quads.is_empty() {
+ self.quad_pipeline.prepare(
+ device,
+ queue,
+ &layer.quads,
+ transformation,
+ scale_factor,
+ );
+ }
- self.quad_pipeline.render(bounds, &mut render_pass);
- }
+ if !layer.meshes.is_empty() {
+ let scaled = transformation
+ * Transformation::scale(scale_factor, scale_factor);
+
+ self.triangle_pipeline.prepare(
+ device,
+ queue,
+ &layer.meshes,
+ scaled,
+ );
+ }
- if !layer.meshes.is_empty() {
- let scaled = transformation
- * Transformation::scale(scale_factor, scale_factor);
-
- self.triangle_pipeline.prepare(
- device,
- queue,
- &layer.meshes,
- scaled,
- );
-
- self.triangle_pipeline.render(
- device,
- encoder,
- target,
- target_size,
- &layer.meshes,
- scale_factor,
- );
+ #[cfg(any(feature = "image", feature = "svg"))]
+ {
+ if !layer.images.is_empty() {
+ let scaled = transformation
+ * Transformation::scale(scale_factor, scale_factor);
+
+ self.image_pipeline.prepare(
+ device,
+ queue,
+ _encoder,
+ &layer.images,
+ scaled,
+ scale_factor,
+ );
+ }
+ }
+
+ if !layer.text.is_empty() {
+ self.text_pipeline.prepare(
+ device,
+ queue,
+ &layer.text,
+ layer.bounds,
+ scale_factor,
+ target_size,
+ );
+ }
}
+ }
+ fn render(
+ &mut self,
+ device: &wgpu::Device,
+ encoder: &mut wgpu::CommandEncoder,
+ target: &wgpu::TextureView,
+ clear_color: Option<Color>,
+ scale_factor: f32,
+ target_size: Size<u32>,
+ layers: &[Layer<'_>],
+ ) {
+ use std::mem::ManuallyDrop;
+
+ let mut quad_layer = 0;
+ let mut triangle_layer = 0;
#[cfg(any(feature = "image", feature = "svg"))]
- {
- if !layer.images.is_empty() {
- let scaled = transformation
- * Transformation::scale(scale_factor, scale_factor);
+ let mut image_layer = 0;
+ let mut text_layer = 0;
+
+ let mut render_pass = ManuallyDrop::new(encoder.begin_render_pass(
+ &wgpu::RenderPassDescriptor {
+ label: Some("iced_wgpu::quad render pass"),
+ color_attachments: &[Some(wgpu::RenderPassColorAttachment {
+ view: target,
+ resolve_target: None,
+ ops: wgpu::Operations {
+ load: match clear_color {
+ Some(background_color) => wgpu::LoadOp::Clear({
+ let [r, g, b, a] =
+ background_color.into_linear();
+
+ wgpu::Color {
+ r: f64::from(r),
+ g: f64::from(g),
+ b: f64::from(b),
+ a: f64::from(a),
+ }
+ }),
+ None => wgpu::LoadOp::Load,
+ },
+ store: true,
+ },
+ })],
+ depth_stencil_attachment: None,
+ },
+ ));
+
+ for layer in layers {
+ let bounds = (layer.bounds * scale_factor).snap();
- self.image_pipeline.prepare(
+ if bounds.width < 1 || bounds.height < 1 {
+ return;
+ }
+
+ if !layer.quads.is_empty() {
+ self.quad_pipeline
+ .render(quad_layer, bounds, &mut render_pass);
+
+ quad_layer += 1;
+ }
+
+ if !layer.meshes.is_empty() {
+ let _ = ManuallyDrop::into_inner(render_pass);
+
+ self.triangle_pipeline.render(
device,
- queue,
encoder,
- &layer.images,
- scaled,
+ target,
+ triangle_layer,
+ target_size,
+ &layer.meshes,
scale_factor,
);
- let mut render_pass =
- encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- label: Some("iced_wgpu::image render pass"),
+ triangle_layer += 1;
+
+ render_pass = ManuallyDrop::new(encoder.begin_render_pass(
+ &wgpu::RenderPassDescriptor {
+ label: Some("iced_wgpu::quad render pass"),
color_attachments: &[Some(
wgpu::RenderPassColorAttachment {
view: target,
@@ -203,24 +273,31 @@ impl Backend {
},
)],
depth_stencil_attachment: None,
- });
+ },
+ ));
+ }
- self.image_pipeline.render(bounds, &mut render_pass);
+ #[cfg(any(feature = "image", feature = "svg"))]
+ {
+ if !layer.images.is_empty() {
+ self.image_pipeline.render(
+ image_layer,
+ bounds,
+ &mut render_pass,
+ );
+
+ image_layer += 1;
+ }
}
- }
- if !layer.text.is_empty() {
- self.text_pipeline.prepare(
- device,
- queue,
- &layer.text,
- layer.bounds,
- scale_factor,
- target_size,
- );
-
- self.text_pipeline.render(encoder, target);
+ if !layer.text.is_empty() {
+ self.text_pipeline.render(text_layer, &mut render_pass);
+
+ text_layer += 1;
+ }
}
+
+ let _ = ManuallyDrop::into_inner(render_pass);
}
}
diff --git a/wgpu/src/image.rs b/wgpu/src/image.rs
index 5d1ae8d7..db05d2ff 100644
--- a/wgpu/src/image.rs
+++ b/wgpu/src/image.rs
@@ -45,7 +45,6 @@ pub struct Pipeline {
layers: Vec<Layer>,
prepare_layer: usize,
- render_layer: usize,
}
#[derive(Debug)]
@@ -321,7 +320,6 @@ impl Pipeline {
layers: Vec::new(),
prepare_layer: 0,
- render_layer: 0,
}
}
@@ -452,11 +450,12 @@ impl Pipeline {
}
pub fn render<'a>(
- &'a mut self,
+ &'a self,
+ layer: usize,
bounds: Rectangle<u32>,
render_pass: &mut wgpu::RenderPass<'a>,
) {
- if let Some(layer) = self.layers.get(self.render_layer) {
+ if let Some(layer) = self.layers.get(layer) {
render_pass.set_pipeline(&self.pipeline);
render_pass.set_scissor_rect(
@@ -474,8 +473,6 @@ impl Pipeline {
render_pass.set_vertex_buffer(0, self.vertices.slice(..));
layer.render(render_pass);
-
- self.render_layer += 1;
}
}
@@ -496,7 +493,6 @@ impl Pipeline {
.trim(&mut self.texture_atlas, &mut (device, queue, encoder));
self.prepare_layer = 0;
- self.render_layer = 0;
}
}
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs
index c1aa49c4..246cc5e1 100644
--- a/wgpu/src/quad.rs
+++ b/wgpu/src/quad.rs
@@ -17,7 +17,6 @@ pub struct Pipeline {
indices: wgpu::Buffer,
layers: Vec<Layer>,
prepare_layer: usize,
- render_layer: usize,
}
impl Pipeline {
@@ -140,7 +139,6 @@ impl Pipeline {
indices,
layers: Vec::new(),
prepare_layer: 0,
- render_layer: 0,
}
}
@@ -163,11 +161,12 @@ impl Pipeline {
}
pub fn render<'a>(
- &'a mut self,
+ &'a self,
+ layer: usize,
bounds: Rectangle<u32>,
render_pass: &mut wgpu::RenderPass<'a>,
) {
- if let Some(layer) = self.layers.get(self.render_layer) {
+ if let Some(layer) = self.layers.get(layer) {
render_pass.set_pipeline(&self.pipeline);
render_pass.set_scissor_rect(
@@ -184,14 +183,11 @@ impl Pipeline {
render_pass.set_vertex_buffer(0, self.vertices.slice(..));
layer.draw(render_pass);
-
- self.render_layer += 1;
}
}
pub fn end_frame(&mut self) {
self.prepare_layer = 0;
- self.render_layer = 0;
}
}
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs
index 95994a4e..73708fd8 100644
--- a/wgpu/src/text.rs
+++ b/wgpu/src/text.rs
@@ -16,7 +16,7 @@ pub struct Pipeline {
system: Option<System>,
renderers: Vec<glyphon::TextRenderer>,
atlas: glyphon::TextAtlas,
- layer: usize,
+ prepare_layer: usize,
}
#[ouroboros::self_referencing]
@@ -55,7 +55,7 @@ impl Pipeline {
),
renderers: Vec::new(),
atlas: glyphon::TextAtlas::new(device, queue, format),
- layer: 0,
+ prepare_layer: 0,
}
}
@@ -88,12 +88,12 @@ impl Pipeline {
target_size: Size<u32>,
) {
self.system.as_mut().unwrap().with_mut(|fields| {
- if self.renderers.len() <= self.layer {
+ if self.renderers.len() <= self.prepare_layer {
self.renderers
.push(glyphon::TextRenderer::new(device, queue));
}
- let renderer = &mut self.renderers[self.layer];
+ let renderer = &mut self.renderers[self.prepare_layer];
let keys: Vec<_> = sections
.iter()
@@ -179,35 +179,21 @@ impl Pipeline {
&mut glyphon::SwashCache::new(fields.fonts),
)
.expect("Prepare text sections");
+
+ self.prepare_layer += 1;
});
}
- pub fn render(
- &mut self,
- encoder: &mut wgpu::CommandEncoder,
- target: &wgpu::TextureView,
+ pub fn render<'a>(
+ &'a self,
+ layer: usize,
+ render_pass: &mut wgpu::RenderPass<'a>,
) {
- let mut render_pass =
- encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- label: None,
- color_attachments: &[Some(wgpu::RenderPassColorAttachment {
- view: target,
- resolve_target: None,
- ops: wgpu::Operations {
- load: wgpu::LoadOp::Load,
- store: true,
- },
- })],
- depth_stencil_attachment: None,
- });
-
- let renderer = &mut self.renderers[self.layer];
+ let renderer = &self.renderers[layer];
renderer
- .render(&self.atlas, &mut render_pass)
+ .render(&self.atlas, render_pass)
.expect("Render text");
-
- self.layer += 1;
}
pub fn end_frame(&mut self) {
@@ -216,7 +202,7 @@ impl Pipeline {
.unwrap()
.with_render_cache_mut(|cache| cache.trim());
- self.layer = 0;
+ self.prepare_layer = 0;
}
pub fn measure(
diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index 572af1e8..1b537bf4 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -22,7 +22,6 @@ pub struct Pipeline {
layers: Vec<Layer>,
prepare_layer: usize,
- render_layer: usize,
}
#[derive(Debug)]
@@ -235,7 +234,7 @@ impl Layer {
}
fn render<'a>(
- &'a mut self,
+ &'a self,
solid: &'a solid::Pipeline,
#[cfg(not(target_arch = "wasm32"))] gradient: &'a gradient::Pipeline,
meshes: &[Mesh<'_>],
@@ -331,7 +330,6 @@ impl Pipeline {
layers: Vec::new(),
prepare_layer: 0,
- render_layer: 0,
}
}
@@ -373,6 +371,7 @@ impl Pipeline {
device: &wgpu::Device,
encoder: &mut wgpu::CommandEncoder,
target: &wgpu::TextureView,
+ layer: usize,
target_size: Size<u32>,
meshes: &[Mesh<'_>],
scale_factor: f32,
@@ -413,7 +412,7 @@ impl Pipeline {
depth_stencil_attachment: None,
});
- let layer = &mut self.layers[self.render_layer];
+ let layer = &mut self.layers[layer];
layer.render(
&self.solid,
@@ -425,8 +424,6 @@ impl Pipeline {
);
}
- self.render_layer += 1;
-
if let Some(blit) = &mut self.blit {
blit.draw(encoder, target);
}
@@ -434,7 +431,6 @@ impl Pipeline {
pub fn end_frame(&mut self) {
self.prepare_layer = 0;
- self.render_layer = 0;
}
}
diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs
index 6e1acc06..365cb603 100644
--- a/wgpu/src/window/compositor.rs
+++ b/wgpu/src/window/compositor.rs
@@ -190,39 +190,12 @@ impl<Theme> iced_graphics::window::Compositor for Compositor<Theme> {
.texture
.create_view(&wgpu::TextureViewDescriptor::default());
- let _ =
- encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
- label: Some(
- "iced_wgpu::window::Compositor render pass",
- ),
- color_attachments: &[Some(
- wgpu::RenderPassColorAttachment {
- view,
- resolve_target: None,
- ops: wgpu::Operations {
- load: wgpu::LoadOp::Clear({
- let [r, g, b, a] =
- background_color.into_linear();
-
- wgpu::Color {
- r: f64::from(r),
- g: f64::from(g),
- b: f64::from(b),
- a: f64::from(a),
- }
- }),
- store: true,
- },
- },
- )],
- depth_stencil_attachment: None,
- });
-
renderer.with_primitives(|backend, primitives| {
backend.present(
&self.device,
&self.queue,
&mut encoder,
+ Some(background_color),
view,
primitives,
viewport,