summaryrefslogtreecommitdiffstats
path: root/glow/src
diff options
context:
space:
mode:
authorLibravatar shan <shankern@protonmail.com>2022-10-04 18:24:46 -0700
committerLibravatar shan <shankern@protonmail.com>2022-10-04 18:24:46 -0700
commit6e7b3ced0b1daf368e44e181ecdb4ae529877eb6 (patch)
treee530025c737d509b640172d595cff0a0809f5a40 /glow/src
parent5d0fffc626928177239336757507b986b081b878 (diff)
downloadiced-6e7b3ced0b1daf368e44e181ecdb4ae529877eb6.tar.gz
iced-6e7b3ced0b1daf368e44e181ecdb4ae529877eb6.tar.bz2
iced-6e7b3ced0b1daf368e44e181ecdb4ae529877eb6.zip
Reworked wgpu buffers, updated glow side to have proper transform location storage, attempting to fix visibility modifiers, implemented some of the feedback received in initial PR.
Diffstat (limited to 'glow/src')
-rw-r--r--glow/src/backend.rs2
-rw-r--r--glow/src/shader/common/gradient.frag1
-rw-r--r--glow/src/triangle.rs126
-rw-r--r--glow/src/triangle/gradient.rs92
-rw-r--r--glow/src/triangle/solid.rs62
5 files changed, 134 insertions, 149 deletions
diff --git a/glow/src/backend.rs b/glow/src/backend.rs
index 6fc4fb38..7333d513 100644
--- a/glow/src/backend.rs
+++ b/glow/src/backend.rs
@@ -99,7 +99,7 @@ impl Backend {
);
}
- if !layer.meshes.0.is_empty() {
+ if !layer.meshes.is_empty() {
let scaled = transformation
* Transformation::scale(scale_factor, scale_factor);
diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag
index 588f63e0..1afb557d 100644
--- a/glow/src/shader/common/gradient.frag
+++ b/glow/src/shader/common/gradient.frag
@@ -23,6 +23,7 @@ uniform uint color_stops_size;
uniform float color_stop_offsets[MAX_STOPS];
uniform vec4 color_stop_colors[MAX_STOPS];
+//TODO: rewrite without branching to make ALUs happy
void main() {
vec2 gradient_vec = vec2(gradient_end - gradient_start);
vec2 current_vec = vec2(raw_position.xy - gradient_start);
diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs
index 85d873fe..f16f8af4 100644
--- a/glow/src/triangle.rs
+++ b/glow/src/triangle.rs
@@ -2,23 +2,22 @@
mod gradient;
mod solid;
-use crate::program::{self, Shader};
-use crate::Transformation;
+use crate::{program, Transformation};
use glow::HasContext;
-use iced_graphics::layer::{Mesh, Meshes};
+use iced_graphics::layer::{attribute_count_of, Mesh};
use iced_graphics::shader;
use std::marker::PhantomData;
use crate::triangle::gradient::GradientProgram;
use crate::triangle::solid::SolidProgram;
pub use iced_graphics::triangle::{Mesh2D, Vertex2D};
+use shader::Shader;
#[derive(Debug)]
pub(crate) struct Pipeline {
vertex_array: <glow::Context as HasContext>::VertexArray,
vertices: Buffer<Vertex2D>,
indices: Buffer<u32>,
- current_transform: Transformation,
programs: TrianglePrograms,
}
@@ -68,7 +67,6 @@ impl Pipeline {
vertex_array,
vertices,
indices,
- current_transform: Transformation::identity(),
programs: TrianglePrograms {
solid: SolidProgram::new(gl, shader_version),
gradient: GradientProgram::new(gl, shader_version),
@@ -78,7 +76,7 @@ impl Pipeline {
pub fn draw(
&mut self,
- meshes: &Meshes<'_>,
+ meshes: &[Mesh<'_>],
gl: &glow::Context,
target_height: u32,
transformation: Transformation,
@@ -90,8 +88,8 @@ impl Pipeline {
gl.bind_vertex_array(Some(self.vertex_array))
}
- //count the total number of vertices & indices we need to handle for all meshes
- let (total_vertices, total_indices) = meshes.attribute_count();
+ //count the total amount of vertices & indices we need to handle
+ let (total_vertices, total_indices) = attribute_count_of(meshes);
// Then we ensure the current attribute buffers are big enough, resizing if necessary
unsafe {
@@ -100,25 +98,25 @@ impl Pipeline {
}
// We upload all the vertices and indices upfront
- let mut last_vertex = 0;
- let mut last_index = 0;
+ let mut vertex_offset = 0;
+ let mut index_offset = 0;
- for Mesh { buffers, .. } in meshes.0.iter() {
+ for mesh in meshes {
unsafe {
gl.buffer_sub_data_u8_slice(
glow::ARRAY_BUFFER,
- (last_vertex * std::mem::size_of::<Vertex2D>()) as i32,
- bytemuck::cast_slice(&buffers.vertices),
+ (vertex_offset * std::mem::size_of::<Vertex2D>()) as i32,
+ bytemuck::cast_slice(&mesh.buffers.vertices),
);
gl.buffer_sub_data_u8_slice(
glow::ELEMENT_ARRAY_BUFFER,
- (last_index * std::mem::size_of::<u32>()) as i32,
- bytemuck::cast_slice(&buffers.indices),
+ (index_offset * std::mem::size_of::<u32>()) as i32,
+ bytemuck::cast_slice(&mesh.buffers.indices),
);
- last_vertex += buffers.vertices.len();
- last_index += buffers.indices.len();
+ vertex_offset += mesh.buffers.vertices.len();
+ index_offset += mesh.buffers.indices.len();
}
}
@@ -126,22 +124,11 @@ impl Pipeline {
let mut last_vertex = 0;
let mut last_index = 0;
- for (index, Mesh {
- buffers,
- origin,
- clip_bounds,
- shader,
- }) in meshes.0.iter().enumerate()
- {
- let transform =
- transformation * Transformation::translate(origin.x, origin.y);
-
- if index == 0 {
- //set initial transform uniform for both programs
- self.programs.set_transforms(gl, transform);
- }
+ for mesh in meshes {
+ let transform = transformation
+ * Transformation::translate(mesh.origin.x, mesh.origin.y);
- let clip_bounds = (*clip_bounds * scale_factor).snap();
+ let clip_bounds = (mesh.clip_bounds * scale_factor).snap();
unsafe {
gl.scissor(
@@ -152,25 +139,25 @@ impl Pipeline {
clip_bounds.height as i32,
);
- let t = if self.current_transform != transform {
- self.current_transform = transform;
- Some(transform)
- } else {
- None
- };
-
- self.use_with_shader(gl, shader, t);
+ match mesh.shader {
+ Shader::Solid(color) => {
+ self.programs.solid.use_program(gl, &color, &transform);
+ }
+ Shader::Gradient(gradient) => {
+ self.programs.gradient.use_program(gl, &gradient, &transform);
+ }
+ }
gl.draw_elements_base_vertex(
glow::TRIANGLES,
- buffers.indices.len() as i32,
+ mesh.buffers.indices.len() as i32,
glow::UNSIGNED_INT,
(last_index * std::mem::size_of::<u32>()) as i32,
last_vertex as i32,
);
- last_vertex += buffers.vertices.len();
- last_index += buffers.indices.len();
+ last_vertex += mesh.buffers.vertices.len();
+ last_index += mesh.buffers.indices.len();
}
}
@@ -180,31 +167,6 @@ impl Pipeline {
gl.disable(glow::MULTISAMPLE);
}
}
-
- fn use_with_shader(
- &mut self,
- gl: &glow::Context,
- shader: &shader::Shader,
- transform: Option<Transformation>,
- ) {
- match shader {
- shader::Shader::Solid(color) => {
- unsafe { gl.use_program(Some(self.programs.solid.program)) }
- self.programs.solid.set_uniforms(gl, color, transform);
- }
- shader::Shader::Gradient(gradient) => {
- unsafe { gl.use_program(Some(self.programs.gradient.program)) }
- self.programs.gradient.set_uniforms(gl, gradient, transform);
- }
- }
- }
-}
-
-impl TrianglePrograms {
- pub fn set_transforms(&self, gl: &glow::Context, transform: Transformation) {
- update_transform(gl, self.solid.program, Some(transform));
- update_transform(gl, self.gradient.program, Some(transform));
- }
}
/// A simple shader program. Uses [`triangle.vert`] for its vertex shader and only binds position
@@ -215,14 +177,14 @@ pub(super) fn simple_triangle_program(
fragment_shader: &'static str,
) -> <glow::Context as HasContext>::Program {
unsafe {
- let vertex_shader = Shader::vertex(
+ let vertex_shader = program::Shader::vertex(
gl,
shader_version,
include_str!("shader/common/triangle.vert"),
);
let fragment_shader =
- Shader::fragment(gl, shader_version, fragment_shader);
+ program::Shader::fragment(gl, shader_version, fragment_shader);
program::create(
gl,
@@ -232,23 +194,17 @@ pub(super) fn simple_triangle_program(
}
}
-pub(super) fn update_transform(
+pub fn set_transform(
gl: &glow::Context,
- program: <glow::Context as HasContext>::Program,
- transform: Option<Transformation>
+ location: <glow::Context as HasContext>::UniformLocation,
+ transform: Transformation,
) {
- if let Some(t) = transform {
- let transform_location =
- unsafe { gl.get_uniform_location(program, "u_Transform") }
- .expect("Get transform location.");
-
- unsafe {
- gl.uniform_matrix_4_f32_slice(
- Some(&transform_location),
- false,
- t.as_ref(),
- );
- }
+ unsafe {
+ gl.uniform_matrix_4_f32_slice(
+ Some(&location),
+ false,
+ transform.as_ref()
+ );
}
}
diff --git a/glow/src/triangle/gradient.rs b/glow/src/triangle/gradient.rs
index d1b10d77..547871e2 100644
--- a/glow/src/triangle/gradient.rs
+++ b/glow/src/triangle/gradient.rs
@@ -1,18 +1,42 @@
use crate::program::Version;
-use crate::triangle::{simple_triangle_program, update_transform};
+use crate::triangle::{simple_triangle_program, set_transform};
use glow::{Context, HasContext, NativeProgram};
+use iced_graphics::gradient::Linear;
use iced_graphics::gradient::Gradient;
-use iced_graphics::widget::canvas::gradient::Linear;
use iced_graphics::Transformation;
#[derive(Debug)]
-pub(super) struct GradientProgram {
- pub(super) program: <Context as HasContext>::Program,
- pub(super) uniform_data: GradientUniformData,
+pub struct GradientProgram {
+ pub program: <Context as HasContext>::Program,
+ pub uniform_data: GradientUniformData,
+}
+
+#[derive(Debug)]
+pub struct GradientUniformData {
+ gradient: Gradient,
+ transform: Transformation,
+ uniform_locations: GradientUniformLocations,
+}
+
+#[derive(Debug)]
+struct GradientUniformLocations {
+ gradient_start_location: <Context as HasContext>::UniformLocation,
+ gradient_end_location: <Context as HasContext>::UniformLocation,
+ color_stops_size_location: <Context as HasContext>::UniformLocation,
+ //currently the maximum number of stops is 64 due to needing to allocate the
+ //memory for the array of stops with a const value in GLSL
+ color_stops_locations: [ColorStopLocation; 64],
+ transform_location: <Context as HasContext>::UniformLocation,
+}
+
+#[derive(Copy, Debug, Clone)]
+struct ColorStopLocation {
+ color: <Context as HasContext>::UniformLocation,
+ offset: <Context as HasContext>::UniformLocation,
}
impl GradientProgram {
- pub(super) fn new(gl: &Context, shader_version: &Version) -> Self {
+ pub fn new(gl: &Context, shader_version: &Version) -> Self {
let program = simple_triangle_program(
gl,
shader_version,
@@ -25,15 +49,17 @@ impl GradientProgram {
}
}
- pub(super) fn set_uniforms<'a>(
+ pub fn write_uniforms(
&mut self,
gl: &Context,
gradient: &Gradient,
- transform: Option<Transformation>,
+ transform: &Transformation,
) {
- update_transform(gl, self.program, transform);
+ if transform != &self.uniform_data.transform {
+ set_transform(gl, self.uniform_data.uniform_locations.transform_location, *transform);
+ }
- if &self.uniform_data.current_gradient != gradient {
+ if &self.uniform_data.gradient != gradient {
match gradient {
Gradient::Linear(linear) => {
let gradient_start: [f32; 2] = (linear.start).into();
@@ -104,31 +130,17 @@ impl GradientProgram {
}
}
- self.uniform_data.current_gradient = gradient.clone();
+ self.uniform_data.gradient = gradient.clone();
}
}
-}
-
-#[derive(Debug)]
-pub(super) struct GradientUniformData {
- current_gradient: Gradient,
- uniform_locations: GradientUniformLocations,
-}
-#[derive(Debug)]
-struct GradientUniformLocations {
- gradient_start_location: <Context as HasContext>::UniformLocation,
- gradient_end_location: <Context as HasContext>::UniformLocation,
- color_stops_size_location: <Context as HasContext>::UniformLocation,
- //currently the maximum number of stops is 64 due to needing to allocate the
- //memory for the array of stops with a const value in GLSL
- color_stops_locations: [ColorStopLocation; 64],
-}
+ pub fn use_program(&mut self, gl: &glow::Context, gradient: &Gradient, transform: &Transformation) {
+ unsafe {
+ gl.use_program(Some(self.program))
+ }
-#[derive(Copy, Debug, Clone)]
-struct ColorStopLocation {
- color: <Context as HasContext>::UniformLocation,
- offset: <Context as HasContext>::UniformLocation,
+ self.write_uniforms(gl, gradient, transform);
+ }
}
impl GradientUniformData {
@@ -153,10 +165,7 @@ impl GradientUniformData {
&format!("color_stop_offsets[{}]", index),
)
}
- .expect(&format!(
- "Gradient - Color stop offset with index {}",
- index
- ));
+ .expect("Gradient - Color stop offset location.");
let color = unsafe {
gl.get_uniform_location(
@@ -164,25 +173,28 @@ impl GradientUniformData {
&format!("color_stop_colors[{}]", index),
)
}
- .expect(&format!(
- "Gradient - Color stop colors with index {}",
- index
- ));
+ .expect("Gradient - Color stop color location.");
ColorStopLocation { color, offset }
});
+ let transform_location =
+ unsafe { gl.get_uniform_location(program, "u_Transform") }
+ .expect("Get transform location.");
+
GradientUniformData {
- current_gradient: Gradient::Linear(Linear {
+ gradient: Gradient::Linear(Linear {
start: Default::default(),
end: Default::default(),
color_stops: vec![],
}),
+ transform: Transformation::identity(),
uniform_locations: GradientUniformLocations {
gradient_start_location,
gradient_end_location,
color_stops_size_location,
color_stops_locations,
+ transform_location,
},
}
}
diff --git a/glow/src/triangle/solid.rs b/glow/src/triangle/solid.rs
index 3a33cea8..d5b73eb9 100644
--- a/glow/src/triangle/solid.rs
+++ b/glow/src/triangle/solid.rs
@@ -1,13 +1,38 @@
use crate::program::Version;
-use crate::triangle::{simple_triangle_program, update_transform};
+use crate::triangle::{set_transform, simple_triangle_program};
use crate::Color;
use glow::{Context, HasContext, NativeProgram};
use iced_graphics::Transformation;
#[derive(Debug)]
pub struct SolidProgram {
- pub(crate) program: <Context as HasContext>::Program,
- pub(crate) uniform_data: SolidUniformData,
+ program: <Context as HasContext>::Program,
+ uniform_data: SolidUniformData,
+}
+
+#[derive(Debug)]
+pub(crate) struct SolidUniformData {
+ pub color: Color,
+ pub color_location: <Context as HasContext>::UniformLocation,
+ pub transform: Transformation,
+ pub transform_location: <Context as HasContext>::UniformLocation,
+}
+
+impl SolidUniformData {
+ fn new(gl: &Context, program: NativeProgram) -> Self {
+ Self {
+ color: Color::TRANSPARENT,
+ color_location: unsafe {
+ gl.get_uniform_location(program, "color")
+ }
+ .expect("Solid - Color uniform location."),
+ transform: Transformation::identity(),
+ transform_location: unsafe {
+ gl.get_uniform_location(program, "u_Transform")
+ }
+ .expect("Get transform location."),
+ }
+ }
}
impl SolidProgram {
@@ -24,15 +49,17 @@ impl SolidProgram {
}
}
- pub fn set_uniforms<'a>(
+ pub fn write_uniforms(
&mut self,
gl: &Context,
color: &Color,
- transform: Option<Transformation>,
+ transform: &Transformation,
) {
- update_transform(gl, self.program, transform);
+ if transform != &self.uniform_data.transform {
+ set_transform(gl, self.uniform_data.transform_location, *transform)
+ }
- if &self.uniform_data.color != color {
+ if color != &self.uniform_data.color {
unsafe {
gl.uniform_4_f32(
Some(&self.uniform_data.color_location),
@@ -46,22 +73,11 @@ impl SolidProgram {
self.uniform_data.color = *color;
}
}
-}
-
-#[derive(Debug)]
-pub(crate) struct SolidUniformData {
- pub color: Color,
- pub color_location: <Context as HasContext>::UniformLocation,
-}
-impl SolidUniformData {
- fn new(gl: &Context, program: NativeProgram) -> Self {
- Self {
- color: Color::TRANSPARENT,
- color_location: unsafe {
- gl.get_uniform_location(program, "color")
- }
- .expect("Solid - Color uniform location."),
+ pub fn use_program(&mut self, gl: &glow::Context, color: &Color, transform: &Transformation) {
+ unsafe {
+ gl.use_program(Some(self.program))
}
+ self.write_uniforms(gl, color, transform)
}
-}
+} \ No newline at end of file