From 381052c50e8c3458a681ec4f2df6c74a40baf5d2 Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 4 Nov 2021 19:26:49 -0300 Subject: Split `quad::Pipeline` into `core` and `compatibility` --- glow/src/quad.rs | 234 +++++++------------------------------------------------ 1 file changed, 28 insertions(+), 206 deletions(-) (limited to 'glow/src/quad.rs') diff --git a/glow/src/quad.rs b/glow/src/quad.rs index a8fbb9e5..5438024c 100644 --- a/glow/src/quad.rs +++ b/glow/src/quad.rs @@ -1,77 +1,24 @@ -use crate::program; +mod compatibility; +mod core; + use crate::Transformation; use glow::HasContext; use iced_graphics::layer; use iced_native::Rectangle; -const MAX_INSTANCES: usize = 100_000; - #[derive(Debug)] -pub struct Pipeline { - program: ::Program, - vertex_array: ::VertexArray, - instances: ::Buffer, - transform_location: ::UniformLocation, - scale_location: ::UniformLocation, - screen_height_location: ::UniformLocation, - current_transform: Transformation, - current_scale: f32, - current_target_height: u32, +pub enum Pipeline { + Core(core::Pipeline), + Compatibility(compatibility::Pipeline), } impl Pipeline { pub fn new(gl: &glow::Context) -> Pipeline { - let program = unsafe { - program::create( - gl, - &[ - (glow::VERTEX_SHADER, include_str!("shader/quad.vert")), - (glow::FRAGMENT_SHADER, include_str!("shader/quad.frag")), - ], - ) - }; - - let transform_location = - unsafe { gl.get_uniform_location(program, "u_Transform") } - .expect("Get transform location"); - - let scale_location = - unsafe { gl.get_uniform_location(program, "u_Scale") } - .expect("Get scale location"); - - let screen_height_location = - unsafe { gl.get_uniform_location(program, "u_ScreenHeight") } - .expect("Get target height location"); - - unsafe { - gl.use_program(Some(program)); - - let matrix: [f32; 16] = Transformation::identity().into(); - gl.uniform_matrix_4_f32_slice( - Some(&transform_location), - false, - &matrix, - ); - - gl.uniform_1_f32(Some(&scale_location), 1.0); - gl.uniform_1_f32(Some(&screen_height_location), 0.0); - - gl.use_program(None); - } - - let (vertex_array, instances) = - unsafe { create_instance_buffer(gl, MAX_INSTANCES) }; - - Pipeline { - program, - vertex_array, - instances, - transform_location, - scale_location, - screen_height_location, - current_transform: Transformation::identity(), - current_scale: 1.0, - current_target_height: 0, + let version = gl.version(); + if version.is_embedded || version.major == 2 { + Pipeline::Compatibility(compatibility::Pipeline::new(gl)) + } else { + Pipeline::Core(core::Pipeline::new(gl)) } } @@ -84,152 +31,27 @@ impl Pipeline { scale: f32, bounds: Rectangle, ) { - unsafe { - gl.enable(glow::SCISSOR_TEST); - gl.scissor( - bounds.x as i32, - (target_height - (bounds.y + bounds.height)) as i32, - bounds.width as i32, - bounds.height as i32, - ); - - gl.use_program(Some(self.program)); - gl.bind_vertex_array(Some(self.vertex_array)); - gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.instances)); - } - - if transformation != self.current_transform { - unsafe { - let matrix: [f32; 16] = transformation.into(); - gl.uniform_matrix_4_f32_slice( - Some(&self.transform_location), - false, - &matrix, - ); - - self.current_transform = transformation; - } - } - - if scale != self.current_scale { - unsafe { - gl.uniform_1_f32(Some(&self.scale_location), scale); - } - - self.current_scale = scale; - } - - if target_height != self.current_target_height { - unsafe { - gl.uniform_1_f32( - Some(&self.screen_height_location), - target_height as f32, + match self { + Pipeline::Core(pipeline) => { + pipeline.draw( + gl, + target_height, + instances, + transformation, + scale, + bounds, ); } - - self.current_target_height = target_height; - } - - let mut i = 0; - let total = instances.len(); - - while i < total { - let end = (i + MAX_INSTANCES).min(total); - let amount = end - i; - - unsafe { - gl.buffer_sub_data_u8_slice( - glow::ARRAY_BUFFER, - 0, - bytemuck::cast_slice(&instances[i..end]), - ); - - gl.draw_arrays_instanced( - glow::TRIANGLE_STRIP, - 0, - 4, - amount as i32, + Pipeline::Compatibility(pipeline) => { + pipeline.draw( + gl, + target_height, + instances, + transformation, + scale, + bounds, ); } - - i += MAX_INSTANCES; - } - - unsafe { - gl.bind_vertex_array(None); - gl.use_program(None); - gl.disable(glow::SCISSOR_TEST); } } } - -unsafe fn create_instance_buffer( - gl: &glow::Context, - size: usize, -) -> ( - ::VertexArray, - ::Buffer, -) { - let vertex_array = gl.create_vertex_array().expect("Create vertex array"); - let buffer = gl.create_buffer().expect("Create instance buffer"); - - gl.bind_vertex_array(Some(vertex_array)); - gl.bind_buffer(glow::ARRAY_BUFFER, Some(buffer)); - gl.buffer_data_size( - glow::ARRAY_BUFFER, - (size * std::mem::size_of::()) as i32, - glow::DYNAMIC_DRAW, - ); - - let stride = std::mem::size_of::() as i32; - - gl.enable_vertex_attrib_array(0); - gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, stride, 0); - gl.vertex_attrib_divisor(0, 1); - - gl.enable_vertex_attrib_array(1); - gl.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, stride, 4 * 2); - gl.vertex_attrib_divisor(1, 1); - - gl.enable_vertex_attrib_array(2); - gl.vertex_attrib_pointer_f32(2, 4, glow::FLOAT, false, stride, 4 * (2 + 2)); - gl.vertex_attrib_divisor(2, 1); - - gl.enable_vertex_attrib_array(3); - gl.vertex_attrib_pointer_f32( - 3, - 4, - glow::FLOAT, - false, - stride, - 4 * (2 + 2 + 4), - ); - gl.vertex_attrib_divisor(3, 1); - - gl.enable_vertex_attrib_array(4); - gl.vertex_attrib_pointer_f32( - 4, - 1, - glow::FLOAT, - false, - stride, - 4 * (2 + 2 + 4 + 4), - ); - gl.vertex_attrib_divisor(4, 1); - - gl.enable_vertex_attrib_array(5); - gl.vertex_attrib_pointer_f32( - 5, - 1, - glow::FLOAT, - false, - stride, - 4 * (2 + 2 + 4 + 4 + 1), - ); - gl.vertex_attrib_divisor(5, 1); - - gl.bind_vertex_array(None); - gl.bind_buffer(glow::ARRAY_BUFFER, None); - - (vertex_array, buffer) -} -- cgit From 94bb03c33c161015c200cd77bc6b2d73531d0917 Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 10 Nov 2021 11:18:57 -0300 Subject: Log debugging info --- glow/src/quad.rs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'glow/src/quad.rs') diff --git a/glow/src/quad.rs b/glow/src/quad.rs index 5438024c..75740c7e 100644 --- a/glow/src/quad.rs +++ b/glow/src/quad.rs @@ -16,8 +16,10 @@ impl Pipeline { pub fn new(gl: &glow::Context) -> Pipeline { let version = gl.version(); if version.is_embedded || version.major == 2 { + log::info!("Mode: compatibility"); Pipeline::Compatibility(compatibility::Pipeline::new(gl)) } else { + log::info!("Mode: core"); Pipeline::Core(core::Pipeline::new(gl)) } } -- cgit From e31566d430093fb084da2e7f4f4ed1b66326edef Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 11 Nov 2021 01:10:47 -0300 Subject: Improve shader version selection --- glow/src/quad.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'glow/src/quad.rs') diff --git a/glow/src/quad.rs b/glow/src/quad.rs index 75740c7e..e965f3c9 100644 --- a/glow/src/quad.rs +++ b/glow/src/quad.rs @@ -13,14 +13,22 @@ pub enum Pipeline { } impl Pipeline { - pub fn new(gl: &glow::Context) -> Pipeline { + pub fn new( + gl: &glow::Context, + shader_version: &(String, String), + ) -> Pipeline { let version = gl.version(); - if version.is_embedded || version.major == 2 { - log::info!("Mode: compatibility"); - Pipeline::Compatibility(compatibility::Pipeline::new(gl)) - } else { + + // OpenGL 3.0+ and OpenGL ES 3.0+ have instancing (which is what separates `core` from `compatibility`) + if version.major >= 3 { log::info!("Mode: core"); - Pipeline::Core(core::Pipeline::new(gl)) + Pipeline::Core(core::Pipeline::new(gl, shader_version)) + } else { + log::info!("Mode: compatibility"); + Pipeline::Compatibility(compatibility::Pipeline::new( + gl, + shader_version, + )) } } -- cgit From 424e1d3fda3c9e1764b567a3b05d33a9ed589fda Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 19 Jan 2022 22:04:53 -0300 Subject: Add `Shader` and `Version` to simplify and constrain `program::create` --- glow/src/quad.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'glow/src/quad.rs') diff --git a/glow/src/quad.rs b/glow/src/quad.rs index e965f3c9..d9f1c6ae 100644 --- a/glow/src/quad.rs +++ b/glow/src/quad.rs @@ -1,6 +1,7 @@ mod compatibility; mod core; +use crate::program; use crate::Transformation; use glow::HasContext; use iced_graphics::layer; @@ -15,12 +16,12 @@ pub enum Pipeline { impl Pipeline { pub fn new( gl: &glow::Context, - shader_version: &(String, String), + shader_version: &program::Version, ) -> Pipeline { - let version = gl.version(); + let gl_version = gl.version(); // OpenGL 3.0+ and OpenGL ES 3.0+ have instancing (which is what separates `core` from `compatibility`) - if version.major >= 3 { + if gl_version.major >= 3 { log::info!("Mode: core"); Pipeline::Core(core::Pipeline::new(gl, shader_version)) } else { -- cgit