diff options
Diffstat (limited to 'glow/src')
| -rw-r--r-- | glow/src/backend.rs | 280 | ||||
| -rw-r--r-- | glow/src/image.rs | 254 | ||||
| -rw-r--r-- | glow/src/image/storage.rs | 78 | ||||
| -rw-r--r-- | glow/src/lib.rs | 53 | ||||
| -rw-r--r-- | glow/src/program.rs | 133 | ||||
| -rw-r--r-- | glow/src/quad.rs | 74 | ||||
| -rw-r--r-- | glow/src/quad/compatibility.rs | 349 | ||||
| -rw-r--r-- | glow/src/quad/core.rs | 244 | ||||
| -rw-r--r-- | glow/src/settings.rs | 61 | ||||
| -rw-r--r-- | glow/src/shader/common/gradient.frag | 59 | ||||
| -rw-r--r-- | glow/src/shader/common/gradient.vert | 9 | ||||
| -rw-r--r-- | glow/src/shader/common/image.frag | 22 | ||||
| -rw-r--r-- | glow/src/shader/common/image.vert | 9 | ||||
| -rw-r--r-- | glow/src/shader/common/solid.frag | 18 | ||||
| -rw-r--r-- | glow/src/shader/common/solid.vert | 11 | ||||
| -rw-r--r-- | glow/src/shader/compatibility/quad.frag | 83 | ||||
| -rw-r--r-- | glow/src/shader/compatibility/quad.vert | 46 | ||||
| -rw-r--r-- | glow/src/shader/core/quad.frag | 95 | ||||
| -rw-r--r-- | glow/src/shader/core/quad.vert | 52 | ||||
| -rw-r--r-- | glow/src/text.rs | 257 | ||||
| -rw-r--r-- | glow/src/triangle.rs | 595 | ||||
| -rw-r--r-- | glow/src/window.rs | 4 | ||||
| -rw-r--r-- | glow/src/window/compositor.rs | 111 | 
23 files changed, 0 insertions, 2897 deletions
diff --git a/glow/src/backend.rs b/glow/src/backend.rs deleted file mode 100644 index 36a34eda..00000000 --- a/glow/src/backend.rs +++ /dev/null @@ -1,280 +0,0 @@ -#[cfg(any(feature = "image", feature = "svg"))] -use crate::image; -use crate::quad; -use crate::text; -use crate::{program, triangle}; -use crate::{Settings, Transformation, Viewport}; - -use iced_graphics::backend; -use iced_graphics::font; -use iced_graphics::{Layer, Primitive}; -use iced_native::alignment; -use iced_native::{Font, Size}; - -/// A [`glow`] graphics backend for [`iced`]. -/// -/// [`glow`]: https://github.com/grovesNL/glow -/// [`iced`]: https://github.com/iced-rs/iced -#[derive(Debug)] -pub struct Backend { -    #[cfg(any(feature = "image", feature = "svg"))] -    image_pipeline: image::Pipeline, -    quad_pipeline: quad::Pipeline, -    text_pipeline: text::Pipeline, -    triangle_pipeline: triangle::Pipeline, -    default_text_size: f32, -} - -impl Backend { -    /// Creates a new [`Backend`]. -    pub fn new(gl: &glow::Context, settings: Settings) -> Self { -        let text_pipeline = text::Pipeline::new( -            gl, -            settings.default_font, -            settings.text_multithreading, -        ); - -        let shader_version = program::Version::new(gl); - -        #[cfg(any(feature = "image", feature = "svg"))] -        let image_pipeline = image::Pipeline::new(gl, &shader_version); -        let quad_pipeline = quad::Pipeline::new(gl, &shader_version); -        let triangle_pipeline = triangle::Pipeline::new(gl, &shader_version); - -        Self { -            #[cfg(any(feature = "image", feature = "svg"))] -            image_pipeline, -            quad_pipeline, -            text_pipeline, -            triangle_pipeline, -            default_text_size: settings.default_text_size, -        } -    } - -    /// Draws the provided primitives in the default framebuffer. -    /// -    /// The text provided as overlay will be rendered on top of the primitives. -    /// This is useful for rendering debug information. -    pub fn present<T: AsRef<str>>( -        &mut self, -        gl: &glow::Context, -        primitives: &[Primitive], -        viewport: &Viewport, -        overlay_text: &[T], -    ) { -        let viewport_size = viewport.physical_size(); -        let scale_factor = viewport.scale_factor() as f32; -        let projection = viewport.projection(); - -        let mut layers = Layer::generate(primitives, viewport); -        layers.push(Layer::overlay(overlay_text, viewport)); - -        for layer in layers { -            self.flush( -                gl, -                scale_factor, -                projection, -                &layer, -                viewport_size.height, -            ); -        } - -        #[cfg(any(feature = "image", feature = "svg"))] -        self.image_pipeline.trim_cache(gl); -    } - -    fn flush( -        &mut self, -        gl: &glow::Context, -        scale_factor: f32, -        transformation: Transformation, -        layer: &Layer<'_>, -        target_height: u32, -    ) { -        let mut bounds = (layer.bounds * scale_factor).snap(); - -        if bounds.width < 1 || bounds.height < 1 { -            return; -        } - -        bounds.height = bounds.height.min(target_height); - -        if !layer.quads.is_empty() { -            self.quad_pipeline.draw( -                gl, -                target_height, -                &layer.quads, -                transformation, -                scale_factor, -                bounds, -            ); -        } - -        if !layer.meshes.is_empty() { -            let scaled = transformation -                * Transformation::scale(scale_factor, scale_factor); - -            self.triangle_pipeline.draw( -                &layer.meshes, -                gl, -                target_height, -                scaled, -                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.draw( -                gl, -                target_height, -                scaled, -                scale_factor, -                &layer.images, -                bounds, -            ); -        } - -        if !layer.text.is_empty() { -            for text in layer.text.iter() { -                // Target physical coordinates directly to avoid blurry text -                let text = glow_glyph::Section { -                    // TODO: We `round` here to avoid rerasterizing text when -                    // its position changes slightly. This can make text feel a -                    // bit "jumpy". We may be able to do better once we improve -                    // our text rendering/caching pipeline. -                    screen_position: ( -                        (text.bounds.x * scale_factor).round(), -                        (text.bounds.y * scale_factor).round(), -                    ), -                    // TODO: Fix precision issues with some scale factors. -                    // -                    // The `ceil` here can cause some words to render on the -                    // same line when they should not. -                    // -                    // Ideally, `wgpu_glyph` should be able to compute layout -                    // using logical positions, and then apply the proper -                    // scaling when rendering. This would ensure that both -                    // measuring and rendering follow the same layout rules. -                    bounds: ( -                        (text.bounds.width * scale_factor).ceil(), -                        (text.bounds.height * scale_factor).ceil(), -                    ), -                    text: vec![glow_glyph::Text { -                        text: text.content, -                        scale: glow_glyph::ab_glyph::PxScale { -                            x: text.size * scale_factor, -                            y: text.size * scale_factor, -                        }, -                        font_id: self.text_pipeline.find_font(text.font), -                        extra: glow_glyph::Extra { -                            color: text.color, -                            z: 0.0, -                        }, -                    }], -                    layout: glow_glyph::Layout::default() -                        .h_align(match text.horizontal_alignment { -                            alignment::Horizontal::Left => { -                                glow_glyph::HorizontalAlign::Left -                            } -                            alignment::Horizontal::Center => { -                                glow_glyph::HorizontalAlign::Center -                            } -                            alignment::Horizontal::Right => { -                                glow_glyph::HorizontalAlign::Right -                            } -                        }) -                        .v_align(match text.vertical_alignment { -                            alignment::Vertical::Top => { -                                glow_glyph::VerticalAlign::Top -                            } -                            alignment::Vertical::Center => { -                                glow_glyph::VerticalAlign::Center -                            } -                            alignment::Vertical::Bottom => { -                                glow_glyph::VerticalAlign::Bottom -                            } -                        }), -                }; - -                self.text_pipeline.queue(text); -            } - -            self.text_pipeline.draw_queued( -                gl, -                transformation, -                glow_glyph::Region { -                    x: bounds.x, -                    y: target_height - (bounds.y + bounds.height), -                    width: bounds.width, -                    height: bounds.height, -                }, -            ); -        } -    } -} - -impl iced_graphics::Backend for Backend { -    fn trim_measurements(&mut self) { -        self.text_pipeline.trim_measurement_cache() -    } -} - -impl backend::Text for Backend { -    const ICON_FONT: Font = font::ICONS; -    const CHECKMARK_ICON: char = font::CHECKMARK_ICON; -    const ARROW_DOWN_ICON: char = font::ARROW_DOWN_ICON; - -    fn default_size(&self) -> f32 { -        self.default_text_size -    } - -    fn measure( -        &self, -        contents: &str, -        size: f32, -        font: Font, -        bounds: Size, -    ) -> (f32, f32) { -        self.text_pipeline.measure(contents, size, font, bounds) -    } - -    fn hit_test( -        &self, -        contents: &str, -        size: f32, -        font: Font, -        bounds: Size, -        point: iced_native::Point, -        nearest_only: bool, -    ) -> Option<text::Hit> { -        self.text_pipeline.hit_test( -            contents, -            size, -            font, -            bounds, -            point, -            nearest_only, -        ) -    } -} - -#[cfg(feature = "image")] -impl backend::Image for Backend { -    fn dimensions(&self, handle: &iced_native::image::Handle) -> Size<u32> { -        self.image_pipeline.dimensions(handle) -    } -} - -#[cfg(feature = "svg")] -impl backend::Svg for Backend { -    fn viewport_dimensions( -        &self, -        handle: &iced_native::svg::Handle, -    ) -> Size<u32> { -        self.image_pipeline.viewport_dimensions(handle) -    } -} diff --git a/glow/src/image.rs b/glow/src/image.rs deleted file mode 100644 index d3a25b5b..00000000 --- a/glow/src/image.rs +++ /dev/null @@ -1,254 +0,0 @@ -mod storage; - -use storage::Storage; - -pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; - -use crate::program::{self, Shader}; -use crate::Transformation; - -#[cfg(feature = "image")] -use iced_graphics::image::raster; - -#[cfg(feature = "svg")] -use iced_graphics::image::vector; - -use iced_graphics::layer; -use iced_graphics::Rectangle; -use iced_graphics::Size; - -use glow::HasContext; - -use std::cell::RefCell; - -#[cfg(feature = "tracing")] -use tracing::info_span; - -#[derive(Debug)] -pub(crate) struct Pipeline { -    program: <glow::Context as HasContext>::Program, -    vertex_array: <glow::Context as HasContext>::VertexArray, -    vertex_buffer: <glow::Context as HasContext>::Buffer, -    transform_location: <glow::Context as HasContext>::UniformLocation, -    storage: Storage, -    #[cfg(feature = "image")] -    raster_cache: RefCell<raster::Cache<Storage>>, -    #[cfg(feature = "svg")] -    vector_cache: RefCell<vector::Cache<Storage>>, -} - -impl Pipeline { -    pub fn new( -        gl: &glow::Context, -        shader_version: &program::Version, -    ) -> Pipeline { -        let program = unsafe { -            let vertex_shader = Shader::vertex( -                gl, -                shader_version, -                include_str!("shader/common/image.vert"), -            ); -            let fragment_shader = Shader::fragment( -                gl, -                shader_version, -                include_str!("shader/common/image.frag"), -            ); - -            program::create( -                gl, -                &[vertex_shader, fragment_shader], -                &[(0, "i_Position")], -            ) -        }; - -        let transform_location = -            unsafe { gl.get_uniform_location(program, "u_Transform") } -                .expect("Get transform location"); - -        unsafe { -            gl.use_program(Some(program)); - -            let transform: [f32; 16] = Transformation::identity().into(); -            gl.uniform_matrix_4_f32_slice( -                Some(&transform_location), -                false, -                &transform, -            ); - -            gl.use_program(None); -        } - -        let vertex_buffer = -            unsafe { gl.create_buffer().expect("Create vertex buffer") }; -        let vertex_array = -            unsafe { gl.create_vertex_array().expect("Create vertex array") }; - -        unsafe { -            gl.bind_vertex_array(Some(vertex_array)); -            gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buffer)); - -            let vertices = &[0u8, 0, 1, 0, 0, 1, 1, 1]; -            gl.buffer_data_size( -                glow::ARRAY_BUFFER, -                vertices.len() as i32, -                glow::STATIC_DRAW, -            ); -            gl.buffer_sub_data_u8_slice( -                glow::ARRAY_BUFFER, -                0, -                bytemuck::cast_slice(vertices), -            ); - -            gl.enable_vertex_attrib_array(0); -            gl.vertex_attrib_pointer_f32( -                0, -                2, -                glow::UNSIGNED_BYTE, -                false, -                0, -                0, -            ); - -            gl.bind_buffer(glow::ARRAY_BUFFER, None); -            gl.bind_vertex_array(None); -        } - -        Pipeline { -            program, -            vertex_array, -            vertex_buffer, -            transform_location, -            storage: Storage::default(), -            #[cfg(feature = "image")] -            raster_cache: RefCell::new(raster::Cache::default()), -            #[cfg(feature = "svg")] -            vector_cache: RefCell::new(vector::Cache::default()), -        } -    } - -    #[cfg(feature = "image")] -    pub fn dimensions(&self, handle: &iced_native::image::Handle) -> Size<u32> { -        self.raster_cache.borrow_mut().load(handle).dimensions() -    } - -    #[cfg(feature = "svg")] -    pub fn viewport_dimensions( -        &self, -        handle: &iced_native::svg::Handle, -    ) -> Size<u32> { -        let mut cache = self.vector_cache.borrow_mut(); -        let svg = cache.load(handle); - -        svg.viewport_dimensions() -    } - -    pub fn draw( -        &mut self, -        mut gl: &glow::Context, -        target_height: u32, -        transformation: Transformation, -        _scale_factor: f32, -        images: &[layer::Image], -        layer_bounds: Rectangle<u32>, -    ) { -        #[cfg(feature = "tracing")] -        let _ = info_span!("Glow::Image", "DRAW").entered(); - -        unsafe { -            gl.use_program(Some(self.program)); -            gl.bind_vertex_array(Some(self.vertex_array)); -            gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vertex_buffer)); -            gl.enable(glow::SCISSOR_TEST); -        } - -        #[cfg(feature = "image")] -        let mut raster_cache = self.raster_cache.borrow_mut(); - -        #[cfg(feature = "svg")] -        let mut vector_cache = self.vector_cache.borrow_mut(); - -        for image in images { -            let (entry, bounds) = match &image { -                #[cfg(feature = "image")] -                layer::Image::Raster { handle, bounds } => ( -                    raster_cache.upload(handle, &mut gl, &mut self.storage), -                    bounds, -                ), -                #[cfg(not(feature = "image"))] -                layer::Image::Raster { handle: _, bounds } => (None, bounds), - -                #[cfg(feature = "svg")] -                layer::Image::Vector { -                    handle, -                    color, -                    bounds, -                } => { -                    let size = [bounds.width, bounds.height]; -                    ( -                        vector_cache.upload( -                            handle, -                            *color, -                            size, -                            _scale_factor, -                            &mut gl, -                            &mut self.storage, -                        ), -                        bounds, -                    ) -                } - -                #[cfg(not(feature = "svg"))] -                layer::Image::Vector { bounds, .. } => (None, bounds), -            }; - -            unsafe { -                gl.scissor( -                    layer_bounds.x as i32, -                    (target_height - (layer_bounds.y + layer_bounds.height)) -                        as i32, -                    layer_bounds.width as i32, -                    layer_bounds.height as i32, -                ); - -                if let Some(storage::Entry { texture, .. }) = entry { -                    gl.bind_texture(glow::TEXTURE_2D, Some(*texture)) -                } else { -                    continue; -                } - -                let translate = Transformation::translate(bounds.x, bounds.y); -                let scale = Transformation::scale(bounds.width, bounds.height); -                let transformation = transformation * translate * scale; -                let matrix: [f32; 16] = transformation.into(); -                gl.uniform_matrix_4_f32_slice( -                    Some(&self.transform_location), -                    false, -                    &matrix, -                ); - -                gl.draw_arrays(glow::TRIANGLE_STRIP, 0, 4); - -                gl.bind_texture(glow::TEXTURE_2D, None); -            } -        } - -        unsafe { -            gl.bind_buffer(glow::ARRAY_BUFFER, None); -            gl.bind_vertex_array(None); -            gl.use_program(None); -            gl.disable(glow::SCISSOR_TEST); -        } -    } - -    pub fn trim_cache(&mut self, mut gl: &glow::Context) { -        #[cfg(feature = "image")] -        self.raster_cache -            .borrow_mut() -            .trim(&mut self.storage, &mut gl); - -        #[cfg(feature = "svg")] -        self.vector_cache -            .borrow_mut() -            .trim(&mut self.storage, &mut gl); -    } -} diff --git a/glow/src/image/storage.rs b/glow/src/image/storage.rs deleted file mode 100644 index 9bc20641..00000000 --- a/glow/src/image/storage.rs +++ /dev/null @@ -1,78 +0,0 @@ -use iced_graphics::image; -use iced_graphics::Size; - -use glow::HasContext; - -#[derive(Debug, Default)] -pub struct Storage; - -impl image::Storage for Storage { -    type Entry = Entry; -    type State<'a> = &'a glow::Context; - -    fn upload( -        &mut self, -        width: u32, -        height: u32, -        data: &[u8], -        gl: &mut &glow::Context, -    ) -> Option<Self::Entry> { -        unsafe { -            let texture = gl.create_texture().expect("create texture"); -            gl.bind_texture(glow::TEXTURE_2D, Some(texture)); -            gl.tex_image_2d( -                glow::TEXTURE_2D, -                0, -                glow::SRGB8_ALPHA8 as i32, -                width as i32, -                height as i32, -                0, -                glow::RGBA, -                glow::UNSIGNED_BYTE, -                Some(data), -            ); -            gl.tex_parameter_i32( -                glow::TEXTURE_2D, -                glow::TEXTURE_WRAP_S, -                glow::CLAMP_TO_EDGE as _, -            ); -            gl.tex_parameter_i32( -                glow::TEXTURE_2D, -                glow::TEXTURE_WRAP_T, -                glow::CLAMP_TO_EDGE as _, -            ); -            gl.tex_parameter_i32( -                glow::TEXTURE_2D, -                glow::TEXTURE_MIN_FILTER, -                glow::LINEAR as _, -            ); -            gl.tex_parameter_i32( -                glow::TEXTURE_2D, -                glow::TEXTURE_MAG_FILTER, -                glow::LINEAR as _, -            ); -            gl.bind_texture(glow::TEXTURE_2D, None); - -            Some(Entry { -                size: Size::new(width, height), -                texture, -            }) -        } -    } - -    fn remove(&mut self, entry: &Entry, gl: &mut &glow::Context) { -        unsafe { gl.delete_texture(entry.texture) } -    } -} - -#[derive(Debug)] -pub struct Entry { -    size: Size<u32>, -    pub(super) texture: glow::NativeTexture, -} - -impl image::storage::Entry for Entry { -    fn size(&self) -> Size<u32> { -        self.size -    } -} diff --git a/glow/src/lib.rs b/glow/src/lib.rs deleted file mode 100644 index 9e7de0d9..00000000 --- a/glow/src/lib.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! A [`glow`] renderer for [`iced_native`]. -//! -//!  -//! -//! [`glow`]: https://github.com/grovesNL/glow -//! [`iced_native`]: https://github.com/iced-rs/iced/tree/0.8/native -#![doc( -    html_logo_url = "https://raw.githubusercontent.com/iced-rs/iced/9ab6923e943f784985e9ef9ca28b10278297225d/docs/logo.svg" -)] -#![deny( -    missing_debug_implementations, -    missing_docs, -    unused_results, -    clippy::extra_unused_lifetimes, -    clippy::from_over_into, -    clippy::needless_borrow, -    clippy::new_without_default, -    clippy::useless_conversion -)] -#![forbid(rust_2018_idioms)] -#![allow(clippy::inherent_to_string, clippy::type_complexity)] -#![cfg_attr(docsrs, feature(doc_cfg))] - -pub use glow; - -mod backend; -#[cfg(any(feature = "image", feature = "svg"))] -mod image; -mod program; -mod quad; -mod text; -mod triangle; - -pub mod settings; -pub mod window; - -pub use backend::Backend; -pub use settings::Settings; - -pub(crate) use iced_graphics::Transformation; - -pub use iced_graphics::{Error, Viewport}; -pub use iced_native::Theme; - -pub use iced_native::alignment; -pub use iced_native::{Alignment, Background, Color, Command, Length, Vector}; - -/// A [`glow`] graphics renderer for [`iced`]. -/// -/// [`glow`]: https://github.com/grovesNL/glow -/// [`iced`]: https://github.com/iced-rs/iced -pub type Renderer<Theme = iced_native::Theme> = -    iced_graphics::Renderer<Backend, Theme>; diff --git a/glow/src/program.rs b/glow/src/program.rs deleted file mode 100644 index 95437fcd..00000000 --- a/glow/src/program.rs +++ /dev/null @@ -1,133 +0,0 @@ -use glow::HasContext; - -/// The [`Version`] of a `Program`. -pub struct Version { -    vertex: String, -    fragment: String, -} - -impl Version { -    pub fn new(gl: &glow::Context) -> Version { -        let version = gl.version(); - -        let (vertex, fragment) = match ( -            version.major, -            version.minor, -            version.is_embedded, -        ) { -            // OpenGL 3.0+ -            (3, 0 | 1 | 2, false) => ( -                format!("#version 1{}0\n#extension GL_ARB_explicit_attrib_location : enable", version.minor + 3), -                format!( -                    "#version 1{}0\n#extension GL_ARB_explicit_attrib_location : enable\n#define HIGHER_THAN_300 1", -                    version.minor + 3 -                ), -            ), -            // OpenGL 3.3+ -            (3 | 4, _, false) => ( -                format!("#version {}{}0\n#extension GL_ARB_explicit_attrib_location : enable", version.major, version.minor), -                format!( -                    "#version {}{}0\n#extension GL_ARB_explicit_attrib_location : enable\n#define HIGHER_THAN_300 1", -                    version.major, version.minor -                ), -            ), -            // OpenGL ES 3.0+ -            (3, _, true) => ( -                format!("#version 3{}0 es", version.minor), -                format!( -                    "#version 3{}0 es\n#define HIGHER_THAN_300 1", -                    version.minor -                ), -            ), -            // OpenGL ES 2.0+ -            (2, _, true) => ( -                String::from( -                    "#version 100\n#define in attribute\n#define out varying", -                ), -                String::from("#version 100\n#define in varying"), -            ), -            // OpenGL 2.1 -            (2, _, false) => ( -                String::from( -                    "#version 120\n#define in attribute\n#define out varying", -                ), -                String::from("#version 120\n#define in varying"), -            ), -            // OpenGL 1.1+ -            _ => panic!("Incompatible context version: {version:?}"), -        }; - -        log::info!("Shader directive: {}", vertex.lines().next().unwrap()); - -        Version { vertex, fragment } -    } -} - -pub struct Shader(<glow::Context as HasContext>::Shader); - -impl Shader { -    fn compile(gl: &glow::Context, stage: u32, content: &str) -> Shader { -        unsafe { -            let shader = gl.create_shader(stage).expect("Cannot create shader"); - -            gl.shader_source(shader, content); -            gl.compile_shader(shader); - -            if !gl.get_shader_compile_status(shader) { -                panic!("{}", gl.get_shader_info_log(shader)); -            } - -            Shader(shader) -        } -    } - -    /// Creates a vertex [`Shader`]. -    pub fn vertex( -        gl: &glow::Context, -        version: &Version, -        content: &'static str, -    ) -> Self { -        let content = format!("{}\n{}", version.vertex, content); - -        Shader::compile(gl, glow::VERTEX_SHADER, &content) -    } - -    /// Creates a fragment [`Shader`]. -    pub fn fragment( -        gl: &glow::Context, -        version: &Version, -        content: &'static str, -    ) -> Self { -        let content = format!("{}\n{}", version.fragment, content); - -        Shader::compile(gl, glow::FRAGMENT_SHADER, &content) -    } -} - -pub unsafe fn create( -    gl: &glow::Context, -    shaders: &[Shader], -    attributes: &[(u32, &str)], -) -> <glow::Context as HasContext>::Program { -    let program = gl.create_program().expect("Cannot create program"); - -    for shader in shaders { -        gl.attach_shader(program, shader.0); -    } - -    for (i, name) in attributes { -        gl.bind_attrib_location(program, *i, name); -    } - -    gl.link_program(program); -    if !gl.get_program_link_status(program) { -        panic!("{}", gl.get_program_info_log(program)); -    } - -    for shader in shaders { -        gl.detach_shader(program, shader.0); -        gl.delete_shader(shader.0); -    } - -    program -} diff --git a/glow/src/quad.rs b/glow/src/quad.rs deleted file mode 100644 index 67d9a098..00000000 --- a/glow/src/quad.rs +++ /dev/null @@ -1,74 +0,0 @@ -mod compatibility; -mod core; - -use crate::program; -use crate::Transformation; -use glow::HasContext; -use iced_graphics::layer; -use iced_native::Rectangle; - -#[cfg(feature = "tracing")] -use tracing::info_span; - -#[derive(Debug)] -pub enum Pipeline { -    Core(core::Pipeline), -    Compatibility(compatibility::Pipeline), -} - -impl Pipeline { -    pub fn new( -        gl: &glow::Context, -        shader_version: &program::Version, -    ) -> Pipeline { -        let gl_version = gl.version(); - -        // OpenGL 3.0+ and OpenGL ES 3.0+ have instancing (which is what separates `core` from `compatibility`) -        if gl_version.major >= 3 { -            log::info!("Mode: core"); -            Pipeline::Core(core::Pipeline::new(gl, shader_version)) -        } else { -            log::info!("Mode: compatibility"); -            Pipeline::Compatibility(compatibility::Pipeline::new( -                gl, -                shader_version, -            )) -        } -    } - -    pub fn draw( -        &mut self, -        gl: &glow::Context, -        target_height: u32, -        instances: &[layer::Quad], -        transformation: Transformation, -        scale: f32, -        bounds: Rectangle<u32>, -    ) { -        #[cfg(feature = "tracing")] -        let _ = info_span!("Glow::Quad", "DRAW").enter(); - -        match self { -            Pipeline::Core(pipeline) => { -                pipeline.draw( -                    gl, -                    target_height, -                    instances, -                    transformation, -                    scale, -                    bounds, -                ); -            } -            Pipeline::Compatibility(pipeline) => { -                pipeline.draw( -                    gl, -                    target_height, -                    instances, -                    transformation, -                    scale, -                    bounds, -                ); -            } -        } -    } -} diff --git a/glow/src/quad/compatibility.rs b/glow/src/quad/compatibility.rs deleted file mode 100644 index e909162c..00000000 --- a/glow/src/quad/compatibility.rs +++ /dev/null @@ -1,349 +0,0 @@ -use crate::program::{self, Shader}; -use crate::Transformation; -use glow::HasContext; -use iced_graphics::layer; -use iced_native::Rectangle; - -// Only change `MAX_QUADS`, otherwise you could cause problems -// by splitting a triangle into different render passes. -const MAX_QUADS: usize = 100_000; -const MAX_VERTICES: usize = MAX_QUADS * 4; -const MAX_INDICES: usize = MAX_QUADS * 6; - -#[derive(Debug)] -pub struct Pipeline { -    program: <glow::Context as HasContext>::Program, -    vertex_array: <glow::Context as HasContext>::VertexArray, -    vertex_buffer: <glow::Context as HasContext>::Buffer, -    index_buffer: <glow::Context as HasContext>::Buffer, -    transform_location: <glow::Context as HasContext>::UniformLocation, -    scale_location: <glow::Context as HasContext>::UniformLocation, -    screen_height_location: <glow::Context as HasContext>::UniformLocation, -    current_transform: Transformation, -    current_scale: f32, -    current_target_height: u32, -} - -impl Pipeline { -    pub fn new( -        gl: &glow::Context, -        shader_version: &program::Version, -    ) -> Pipeline { -        let program = unsafe { -            let vertex_shader = Shader::vertex( -                gl, -                shader_version, -                include_str!("../shader/compatibility/quad.vert"), -            ); -            let fragment_shader = Shader::fragment( -                gl, -                shader_version, -                include_str!("../shader/compatibility/quad.frag"), -            ); - -            program::create( -                gl, -                &[vertex_shader, fragment_shader], -                &[ -                    (0, "i_Pos"), -                    (1, "i_Scale"), -                    (2, "i_Color"), -                    (3, "i_BorderColor"), -                    (4, "i_BorderRadius"), -                    (5, "i_BorderWidth"), -                ], -            ) -        }; - -        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)); - -            gl.uniform_matrix_4_f32_slice( -                Some(&transform_location), -                false, -                Transformation::identity().as_ref(), -            ); - -            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, vertex_buffer, index_buffer) = -            unsafe { create_buffers(gl, MAX_VERTICES) }; - -        Pipeline { -            program, -            vertex_array, -            vertex_buffer, -            index_buffer, -            transform_location, -            scale_location, -            screen_height_location, -            current_transform: Transformation::identity(), -            current_scale: 1.0, -            current_target_height: 0, -        } -    } - -    pub fn draw( -        &mut self, -        gl: &glow::Context, -        target_height: u32, -        instances: &[layer::Quad], -        transformation: Transformation, -        scale: f32, -        bounds: Rectangle<u32>, -    ) { -        // TODO: Remove this allocation (probably by changing the shader and removing the need of two `position`) -        let vertices: Vec<Vertex> = -            instances.iter().flat_map(Vertex::from_quad).collect(); - -        // TODO: Remove this allocation (or allocate only when needed) -        let indices: Vec<i32> = (0..instances.len().min(MAX_QUADS) as i32) -            .flat_map(|i| { -                [i * 4, 1 + i * 4, 2 + i * 4, 2 + i * 4, 1 + i * 4, 3 + i * 4] -            }) -            .cycle() -            .take(instances.len() * 6) -            .collect(); - -        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.vertex_buffer)); -            gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.index_buffer)); -        } - -        if transformation != self.current_transform { -            unsafe { -                gl.uniform_matrix_4_f32_slice( -                    Some(&self.transform_location), -                    false, -                    transformation.as_ref(), -                ); - -                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, -                ); -            } - -            self.current_target_height = target_height; -        } - -        let passes = vertices -            .chunks(MAX_VERTICES) -            .zip(indices.chunks(MAX_INDICES)); - -        for (vertices, indices) in passes { -            unsafe { -                gl.buffer_sub_data_u8_slice( -                    glow::ARRAY_BUFFER, -                    0, -                    bytemuck::cast_slice(vertices), -                ); - -                gl.buffer_sub_data_u8_slice( -                    glow::ELEMENT_ARRAY_BUFFER, -                    0, -                    bytemuck::cast_slice(indices), -                ); - -                gl.draw_elements( -                    glow::TRIANGLES, -                    indices.len() as i32, -                    glow::UNSIGNED_INT, -                    0, -                ); -            } -        } - -        unsafe { -            gl.bind_vertex_array(None); -            gl.use_program(None); -            gl.disable(glow::SCISSOR_TEST); -        } -    } -} - -unsafe fn create_buffers( -    gl: &glow::Context, -    size: usize, -) -> ( -    <glow::Context as HasContext>::VertexArray, -    <glow::Context as HasContext>::Buffer, -    <glow::Context as HasContext>::Buffer, -) { -    let vertex_array = gl.create_vertex_array().expect("Create vertex array"); -    let vertex_buffer = gl.create_buffer().expect("Create vertex buffer"); -    let index_buffer = gl.create_buffer().expect("Create index buffer"); - -    gl.bind_vertex_array(Some(vertex_array)); - -    gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(index_buffer)); -    gl.buffer_data_size( -        glow::ELEMENT_ARRAY_BUFFER, -        12 * size as i32, -        glow::DYNAMIC_DRAW, -    ); - -    gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buffer)); -    gl.buffer_data_size( -        glow::ARRAY_BUFFER, -        (size * Vertex::SIZE) as i32, -        glow::DYNAMIC_DRAW, -    ); - -    let stride = Vertex::SIZE as i32; - -    gl.enable_vertex_attrib_array(0); -    gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, stride, 0); - -    gl.enable_vertex_attrib_array(1); -    gl.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, stride, 4 * 2); - -    gl.enable_vertex_attrib_array(2); -    gl.vertex_attrib_pointer_f32(2, 4, glow::FLOAT, false, stride, 4 * (2 + 2)); - -    gl.enable_vertex_attrib_array(3); -    gl.vertex_attrib_pointer_f32( -        3, -        4, -        glow::FLOAT, -        false, -        stride, -        4 * (2 + 2 + 4), -    ); - -    gl.enable_vertex_attrib_array(4); -    gl.vertex_attrib_pointer_f32( -        4, -        4, -        glow::FLOAT, -        false, -        stride, -        4 * (2 + 2 + 4 + 4), -    ); - -    gl.enable_vertex_attrib_array(5); -    gl.vertex_attrib_pointer_f32( -        5, -        1, -        glow::FLOAT, -        false, -        stride, -        4 * (2 + 2 + 4 + 4 + 4), -    ); - -    gl.enable_vertex_attrib_array(6); -    gl.vertex_attrib_pointer_f32( -        6, -        2, -        glow::FLOAT, -        false, -        stride, -        4 * (2 + 2 + 4 + 4 + 4 + 1), -    ); - -    gl.bind_vertex_array(None); -    gl.bind_buffer(glow::ARRAY_BUFFER, None); -    gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None); - -    (vertex_array, vertex_buffer, index_buffer) -} - -/// The vertex of a colored rectangle with a border. -/// -/// This type can be directly uploaded to GPU memory. -#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] -#[repr(C)] -pub struct Vertex { -    /// The position of the [`Vertex`]. -    pub position: [f32; 2], - -    /// The size of the [`Vertex`]. -    pub size: [f32; 2], - -    /// The color of the [`Vertex`], in __linear RGB__. -    pub color: [f32; 4], - -    /// The border color of the [`Vertex`], in __linear RGB__. -    pub border_color: [f32; 4], - -    /// The border radius of the [`Vertex`]. -    pub border_radius: [f32; 4], - -    /// The border width of the [`Vertex`]. -    pub border_width: f32, - -    /// The __quad__ position of the [`Vertex`]. -    pub q_position: [f32; 2], -} - -impl Vertex { -    const SIZE: usize = std::mem::size_of::<Self>(); - -    fn from_quad(quad: &layer::Quad) -> [Vertex; 4] { -        let base = Vertex { -            position: quad.position, -            size: quad.size, -            color: quad.color, -            border_color: quad.color, -            border_radius: quad.border_radius, -            border_width: quad.border_width, -            q_position: [0.0, 0.0], -        }; - -        [ -            base, -            Self { -                q_position: [0.0, 1.0], -                ..base -            }, -            Self { -                q_position: [1.0, 0.0], -                ..base -            }, -            Self { -                q_position: [1.0, 1.0], -                ..base -            }, -        ] -    } -} diff --git a/glow/src/quad/core.rs b/glow/src/quad/core.rs deleted file mode 100644 index 89036530..00000000 --- a/glow/src/quad/core.rs +++ /dev/null @@ -1,244 +0,0 @@ -use crate::program::{self, Shader}; -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: <glow::Context as HasContext>::Program, -    vertex_array: <glow::Context as HasContext>::VertexArray, -    instances: <glow::Context as HasContext>::Buffer, -    transform_location: <glow::Context as HasContext>::UniformLocation, -    scale_location: <glow::Context as HasContext>::UniformLocation, -    screen_height_location: <glow::Context as HasContext>::UniformLocation, -    current_transform: Transformation, -    current_scale: f32, -    current_target_height: u32, -} - -impl Pipeline { -    pub fn new( -        gl: &glow::Context, -        shader_version: &program::Version, -    ) -> Pipeline { -        let program = unsafe { -            let vertex_shader = Shader::vertex( -                gl, -                shader_version, -                include_str!("../shader/core/quad.vert"), -            ); -            let fragment_shader = Shader::fragment( -                gl, -                shader_version, -                include_str!("../shader/core/quad.frag"), -            ); - -            program::create( -                gl, -                &[vertex_shader, fragment_shader], -                &[ -                    (0, "i_Pos"), -                    (1, "i_Scale"), -                    (2, "i_Color"), -                    (3, "i_BorderColor"), -                    (4, "i_BorderRadius"), -                    (5, "i_BorderWidth"), -                ], -            ) -        }; - -        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)); - -            gl.uniform_matrix_4_f32_slice( -                Some(&transform_location), -                false, -                Transformation::identity().as_ref(), -            ); - -            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, -        } -    } - -    pub fn draw( -        &mut self, -        gl: &glow::Context, -        target_height: u32, -        instances: &[layer::Quad], -        transformation: Transformation, -        scale: f32, -        bounds: Rectangle<u32>, -    ) { -        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 { -                gl.uniform_matrix_4_f32_slice( -                    Some(&self.transform_location), -                    false, -                    transformation.as_ref(), -                ); - -                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, -                ); -            } - -            self.current_target_height = target_height; -        } - -        for instances in instances.chunks(MAX_INSTANCES) { -            unsafe { -                gl.buffer_sub_data_u8_slice( -                    glow::ARRAY_BUFFER, -                    0, -                    bytemuck::cast_slice(instances), -                ); - -                gl.draw_arrays_instanced( -                    glow::TRIANGLE_STRIP, -                    0, -                    4, -                    instances.len() as i32, -                ); -            } -        } - -        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, -) -> ( -    <glow::Context as HasContext>::VertexArray, -    <glow::Context as HasContext>::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::<layer::Quad>()) as i32, -        glow::DYNAMIC_DRAW, -    ); - -    let stride = std::mem::size_of::<layer::Quad>() 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, -        4, -        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 + 4), -    ); -    gl.vertex_attrib_divisor(5, 1); - -    gl.bind_vertex_array(None); -    gl.bind_buffer(glow::ARRAY_BUFFER, None); - -    (vertex_array, buffer) -} diff --git a/glow/src/settings.rs b/glow/src/settings.rs deleted file mode 100644 index 6aaa0d55..00000000 --- a/glow/src/settings.rs +++ /dev/null @@ -1,61 +0,0 @@ -//! Configure a renderer. -pub use iced_graphics::Antialiasing; - -/// The settings of a [`Backend`]. -/// -/// [`Backend`]: crate::Backend -#[derive(Clone, Copy, PartialEq)] -pub struct Settings { -    /// The bytes of the font that will be used by default. -    /// -    /// If `None` is provided, a default system font will be chosen. -    pub default_font: Option<&'static [u8]>, - -    /// The default size of text. -    /// -    /// By default, it will be set to `20.0`. -    pub default_text_size: f32, - -    /// If enabled, spread text workload in multiple threads when multiple cores -    /// are available. -    /// -    /// By default, it is disabled. -    pub text_multithreading: bool, - -    /// The antialiasing strategy that will be used for triangle primitives. -    /// -    /// By default, it is `None`. -    pub antialiasing: Option<Antialiasing>, -} - -impl Default for Settings { -    fn default() -> Settings { -        Settings { -            default_font: None, -            default_text_size: 20.0, -            text_multithreading: false, -            antialiasing: None, -        } -    } -} - -impl std::fmt::Debug for Settings { -    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { -        f.debug_struct("Settings") -            // Instead of printing the font bytes, we simply show a `bool` indicating if using a default font or not. -            .field("default_font", &self.default_font.is_some()) -            .field("default_text_size", &self.default_text_size) -            .field("text_multithreading", &self.text_multithreading) -            .field("antialiasing", &self.antialiasing) -            .finish() -    } -} - -impl Settings { -    /// Creates new [`Settings`] using environment configuration. -    /// -    /// Currently, this is equivalent to calling [`Settings::default`]. -    pub fn from_env() -> Self { -        Self::default() -    } -} diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag deleted file mode 100644 index 9af0cb6e..00000000 --- a/glow/src/shader/common/gradient.frag +++ /dev/null @@ -1,59 +0,0 @@ -#ifdef GL_ES -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif -#endif - -#ifdef HIGHER_THAN_300 -layout (location = 0) out vec4 fragColor; -#define gl_FragColor fragColor -#endif - -in vec2 raw_position; - -uniform vec4 gradient_direction; -uniform int color_stops_size; -// GLSL does not support dynamically sized arrays without SSBOs so this is capped to 16 stops -//stored as color(vec4) -> offset(vec4) sequentially; -uniform vec4 color_stops[32]; - -//TODO: rewrite without branching to make ALUs happy -void main() { -    vec2 start = gradient_direction.xy; -    vec2 end = gradient_direction.zw; -    vec2 gradient_vec = vec2(end - start); -    vec2 current_vec = vec2(raw_position.xy - start); -    vec2 unit = normalize(gradient_vec); -    float coord_offset = dot(unit, current_vec) / length(gradient_vec); -    //if a gradient has a start/end stop that is identical, the mesh will have a transparent fill -    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0); - -    float min_offset = color_stops[1].x; -    float max_offset = color_stops[color_stops_size - 1].x; - -    for (int i = 0; i < color_stops_size - 2; i += 2) { -        float curr_offset = color_stops[i+1].x; -        float next_offset = color_stops[i+3].x; - -        if (coord_offset <= min_offset) { -            //current coordinate is before the first defined offset, set it to the start color -            gl_FragColor = color_stops[0]; -        } - -        if (curr_offset <= coord_offset && coord_offset <= next_offset) { -            //current fragment is between the current offset processing & the next one, interpolate colors -            gl_FragColor = mix(color_stops[i], color_stops[i+2], smoothstep( -                curr_offset, -                next_offset, -                coord_offset -            )); -        } - -        if (coord_offset >= max_offset) { -            //current coordinate is before the last defined offset, set it to the last color -            gl_FragColor = color_stops[color_stops_size - 2]; -        } -    } -} diff --git a/glow/src/shader/common/gradient.vert b/glow/src/shader/common/gradient.vert deleted file mode 100644 index fe505997..00000000 --- a/glow/src/shader/common/gradient.vert +++ /dev/null @@ -1,9 +0,0 @@ -uniform mat4 u_Transform; - -in vec2 i_Position; -out vec2 raw_position; - -void main() { -    gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0); -    raw_position = i_Position; -} diff --git a/glow/src/shader/common/image.frag b/glow/src/shader/common/image.frag deleted file mode 100644 index 5e05abdf..00000000 --- a/glow/src/shader/common/image.frag +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef GL_ES -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif -#endif - -uniform sampler2D tex; -in vec2 tex_pos; - -#ifdef HIGHER_THAN_300 -out vec4 fragColor; -#define gl_FragColor fragColor -#endif -#ifdef GL_ES -#define texture texture2D -#endif - -void main() { -    gl_FragColor = texture(tex, tex_pos); -} diff --git a/glow/src/shader/common/image.vert b/glow/src/shader/common/image.vert deleted file mode 100644 index 93e541f2..00000000 --- a/glow/src/shader/common/image.vert +++ /dev/null @@ -1,9 +0,0 @@ -uniform mat4 u_Transform; - -in vec2 i_Position; -out vec2 tex_pos; - -void main() { -    gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0); -    tex_pos = i_Position; -} diff --git a/glow/src/shader/common/solid.frag b/glow/src/shader/common/solid.frag deleted file mode 100644 index 174ffdd3..00000000 --- a/glow/src/shader/common/solid.frag +++ /dev/null @@ -1,18 +0,0 @@ -#ifdef GL_ES -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif -#endif - -#ifdef HIGHER_THAN_300 -out vec4 fragColor; -#define gl_FragColor fragColor -#endif - -in vec4 v_Color; - -void main() { -    gl_FragColor = v_Color; -} diff --git a/glow/src/shader/common/solid.vert b/glow/src/shader/common/solid.vert deleted file mode 100644 index 59ed88e5..00000000 --- a/glow/src/shader/common/solid.vert +++ /dev/null @@ -1,11 +0,0 @@ -uniform mat4 u_Transform; - -in vec2 i_Position; -in vec4 i_Color; - -out vec4 v_Color; - -void main() { -    gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0); -    v_Color = i_Color; -} diff --git a/glow/src/shader/compatibility/quad.frag b/glow/src/shader/compatibility/quad.frag deleted file mode 100644 index bb9d8122..00000000 --- a/glow/src/shader/compatibility/quad.frag +++ /dev/null @@ -1,83 +0,0 @@ -#ifdef GL_ES -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif -#endif - -uniform float u_ScreenHeight; - -varying vec4 v_Color; -varying vec4 v_BorderColor; -varying vec2 v_Pos; -varying vec2 v_Scale; -varying vec4 v_BorderRadius; -varying float v_BorderWidth; - -float _distance(vec2 frag_coord, vec2 position, vec2 size, float radius) -{ -    // TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN -    vec2 inner_size = size - vec2(radius, radius) * 2.0; -    vec2 top_left = position + vec2(radius, radius); -    vec2 bottom_right = top_left + inner_size; - -    vec2 top_left_distance = top_left - frag_coord; -    vec2 bottom_right_distance = frag_coord - bottom_right; - -    vec2 distance = vec2( -        max(max(top_left_distance.x, bottom_right_distance.x), 0.0), -        max(max(top_left_distance.y, bottom_right_distance.y), 0.0) -    ); - -    return sqrt(distance.x * distance.x + distance.y * distance.y); -} - -float selectBorderRadius(vec4 radi, vec2 position, vec2 center) -{ -    float rx = radi.x; -    float ry = radi.y; -    rx = position.x > center.x ? radi.y : radi.x; -    ry = position.x > center.x ? radi.z : radi.w; -    rx = position.y > center.y ? ry : rx; -    return rx; -} - -void main() { -    vec2 fragCoord = vec2(gl_FragCoord.x, u_ScreenHeight - gl_FragCoord.y); - -    float border_radius = selectBorderRadius( -        v_BorderRadius, -        fragCoord, -        (v_Pos + v_Scale * 0.5).xy -    ); - -    float internal_border = max(border_radius - v_BorderWidth, 0.0); - -    float internal_distance = _distance( -        fragCoord, -        v_Pos + vec2(v_BorderWidth), -        v_Scale - vec2(v_BorderWidth * 2.0), -        internal_border -    ); - -    float border_mix = smoothstep( -        max(internal_border - 0.5, 0.0), -        internal_border + 0.5, -        internal_distance -    ); - -    vec4 mixed_color = mix(v_Color, v_BorderColor, border_mix); - -    float d = _distance( -        fragCoord, -        v_Pos, -        v_Scale, -        border_radius -    ); - -    float radius_alpha = -        1.0 - smoothstep(max(border_radius - 0.5, 0.0), border_radius + 0.5, d); - -    gl_FragColor = vec4(mixed_color.xyz, mixed_color.w * radius_alpha); -} diff --git a/glow/src/shader/compatibility/quad.vert b/glow/src/shader/compatibility/quad.vert deleted file mode 100644 index 89931f06..00000000 --- a/glow/src/shader/compatibility/quad.vert +++ /dev/null @@ -1,46 +0,0 @@ -uniform mat4 u_Transform; -uniform float u_Scale; - -attribute vec2 i_Pos; -attribute vec2 i_Scale; -attribute vec4 i_Color; -attribute vec4 i_BorderColor; -attribute vec4 i_BorderRadius; -attribute float i_BorderWidth; -attribute vec2 q_Pos; - -varying vec4 v_Color; -varying vec4 v_BorderColor; -varying vec2 v_Pos; -varying vec2 v_Scale; -varying vec4 v_BorderRadius; -varying float v_BorderWidth; - - -void main() { -    vec2 p_Pos = i_Pos * u_Scale; -    vec2 p_Scale = i_Scale  * u_Scale; - -    vec4 i_BorderRadius = vec4( -        min(i_BorderRadius.x, min(i_Scale.x, i_Scale.y) / 2.0), -        min(i_BorderRadius.y, min(i_Scale.x, i_Scale.y) / 2.0), -        min(i_BorderRadius.z, min(i_Scale.x, i_Scale.y) / 2.0), -        min(i_BorderRadius.w, min(i_Scale.x, i_Scale.y) / 2.0) -    ); - -    mat4 i_Transform = mat4( -        vec4(p_Scale.x + 1.0, 0.0, 0.0, 0.0), -        vec4(0.0, p_Scale.y + 1.0, 0.0, 0.0), -        vec4(0.0, 0.0, 1.0, 0.0), -        vec4(p_Pos - vec2(0.5, 0.5), 0.0, 1.0) -    ); - -    v_Color = i_Color; -    v_BorderColor = i_BorderColor; -    v_Pos = p_Pos; -    v_Scale = p_Scale; -    v_BorderRadius = i_BorderRadius * u_Scale; -    v_BorderWidth = i_BorderWidth * u_Scale; - -    gl_Position = u_Transform * i_Transform * vec4(q_Pos, 0.0, 1.0); -} diff --git a/glow/src/shader/core/quad.frag b/glow/src/shader/core/quad.frag deleted file mode 100644 index 71147aa5..00000000 --- a/glow/src/shader/core/quad.frag +++ /dev/null @@ -1,95 +0,0 @@ -#ifdef GL_ES -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif -#endif - -#ifdef HIGHER_THAN_300 -out vec4 fragColor; -#define gl_FragColor fragColor -#endif - -uniform float u_ScreenHeight; - -in vec4 v_Color; -in vec4 v_BorderColor; -in vec2 v_Pos; -in vec2 v_Scale; -in vec4 v_BorderRadius; -in float v_BorderWidth; - -float fDistance(vec2 frag_coord, vec2 position, vec2 size, float radius) -{ -    // TODO: Try SDF approach: https://www.shadertoy.com/view/wd3XRN -    vec2 inner_size = size - vec2(radius, radius) * 2.0; -    vec2 top_left = position + vec2(radius, radius); -    vec2 bottom_right = top_left + inner_size; - -    vec2 top_left_distance = top_left - frag_coord; -    vec2 bottom_right_distance = frag_coord - bottom_right; - -    vec2 distance = vec2( -        max(max(top_left_distance.x, bottom_right_distance.x), 0.0), -        max(max(top_left_distance.y, bottom_right_distance.y), 0.0) -    ); - -    return sqrt(distance.x * distance.x + distance.y * distance.y); -} - -float selectBorderRadius(vec4 radi, vec2 position, vec2 center) -{ -    float rx = radi.x; -    float ry = radi.y; -    rx = position.x > center.x ? radi.y : radi.x; -    ry = position.x > center.x ? radi.z : radi.w; -    rx = position.y > center.y ? ry : rx; -    return rx; -} - -void main() { -    vec4 mixed_color; - -    vec2 fragCoord = vec2(gl_FragCoord.x, u_ScreenHeight - gl_FragCoord.y); - -    float border_radius = selectBorderRadius( -        v_BorderRadius, -        fragCoord, -        (v_Pos + v_Scale * 0.5).xy -    ); - -    // TODO: Remove branching (?) -    if(v_BorderWidth > 0.0) { -        float internal_border = max(border_radius - v_BorderWidth, 0.0); - -        float internal_distance = fDistance( -            fragCoord, -            v_Pos + vec2(v_BorderWidth), -            v_Scale - vec2(v_BorderWidth * 2.0), -            internal_border -        ); - -        float border_mix = smoothstep( -            max(internal_border - 0.5, 0.0), -            internal_border + 0.5, -            internal_distance -        ); - -        mixed_color = mix(v_Color, v_BorderColor, border_mix); -    } else { -        mixed_color = v_Color; -    } - -    float d = fDistance( -        fragCoord, -        v_Pos, -        v_Scale, -        border_radius -    ); - -    float radius_alpha = -        1.0 - smoothstep(max(border_radius - 0.5, 0.0), border_radius + 0.5, d); - -    gl_FragColor = vec4(mixed_color.xyz, mixed_color.w * radius_alpha); -} diff --git a/glow/src/shader/core/quad.vert b/glow/src/shader/core/quad.vert deleted file mode 100644 index 17c3e641..00000000 --- a/glow/src/shader/core/quad.vert +++ /dev/null @@ -1,52 +0,0 @@ -uniform mat4 u_Transform; -uniform float u_Scale; - -in vec2 i_Pos; -in vec2 i_Scale; -in vec4 i_Color; -in vec4 i_BorderColor; -in vec4 i_BorderRadius; -in float i_BorderWidth; - -out vec4 v_Color; -out vec4 v_BorderColor; -out vec2 v_Pos; -out vec2 v_Scale; -out vec4 v_BorderRadius; -out float v_BorderWidth; - -vec2 positions[4] = vec2[]( -    vec2(0.0, 0.0), -    vec2(0.0, 1.0), -    vec2(1.0, 0.0), -    vec2(1.0, 1.0) -); - -void main() { -    vec2 q_Pos = positions[gl_VertexID]; -    vec2 p_Pos = i_Pos * u_Scale; -    vec2 p_Scale = i_Scale  * u_Scale; - -    vec4 i_BorderRadius = vec4( -        min(i_BorderRadius.x, min(i_Scale.x, i_Scale.y) / 2.0), -        min(i_BorderRadius.y, min(i_Scale.x, i_Scale.y) / 2.0), -        min(i_BorderRadius.z, min(i_Scale.x, i_Scale.y) / 2.0), -        min(i_BorderRadius.w, min(i_Scale.x, i_Scale.y) / 2.0) -    ); - -    mat4 i_Transform = mat4( -        vec4(p_Scale.x + 1.0, 0.0, 0.0, 0.0), -        vec4(0.0, p_Scale.y + 1.0, 0.0, 0.0), -        vec4(0.0, 0.0, 1.0, 0.0), -        vec4(p_Pos - vec2(0.5, 0.5), 0.0, 1.0) -    ); - -    v_Color = i_Color; -    v_BorderColor = i_BorderColor; -    v_Pos = p_Pos; -    v_Scale = p_Scale; -    v_BorderRadius = i_BorderRadius * u_Scale; -    v_BorderWidth = i_BorderWidth * u_Scale; - -    gl_Position = u_Transform * i_Transform * vec4(q_Pos, 0.0, 1.0); -} diff --git a/glow/src/text.rs b/glow/src/text.rs deleted file mode 100644 index 37ccdece..00000000 --- a/glow/src/text.rs +++ /dev/null @@ -1,257 +0,0 @@ -use crate::Transformation; - -use iced_graphics::font; - -use glow_glyph::ab_glyph; -use std::{cell::RefCell, collections::HashMap}; - -pub use iced_native::text::Hit; - -#[derive(Debug)] -pub struct Pipeline { -    draw_brush: RefCell<glow_glyph::GlyphBrush>, -    draw_font_map: RefCell<HashMap<String, glow_glyph::FontId>>, -    measure_brush: RefCell<glyph_brush::GlyphBrush<()>>, -} - -impl Pipeline { -    pub fn new( -        gl: &glow::Context, -        default_font: Option<&[u8]>, -        multithreading: bool, -    ) -> Self { -        let default_font = default_font.map(|slice| slice.to_vec()); - -        // TODO: Font customization -        #[cfg(feature = "default_system_font")] -        let default_font = { -            default_font.or_else(|| { -                font::Source::new() -                    .load(&[font::Family::SansSerif, font::Family::Serif]) -                    .ok() -            }) -        }; - -        let default_font = -            default_font.unwrap_or_else(|| font::FALLBACK.to_vec()); - -        let font = ab_glyph::FontArc::try_from_vec(default_font) -            .unwrap_or_else(|_| { -                log::warn!( -                    "System font failed to load. Falling back to \ -                    embedded font..." -                ); - -                ab_glyph::FontArc::try_from_slice(font::FALLBACK) -                    .expect("Load fallback font") -            }); - -        let draw_brush_builder = -            glow_glyph::GlyphBrushBuilder::using_font(font.clone()) -                .initial_cache_size((2048, 2048)) -                .draw_cache_multithread(multithreading); - -        #[cfg(target_arch = "wasm32")] -        let draw_brush_builder = draw_brush_builder.draw_cache_align_4x4(true); - -        let draw_brush = draw_brush_builder.build(gl); - -        let measure_brush = -            glyph_brush::GlyphBrushBuilder::using_font(font).build(); - -        Pipeline { -            draw_brush: RefCell::new(draw_brush), -            draw_font_map: RefCell::new(HashMap::new()), -            measure_brush: RefCell::new(measure_brush), -        } -    } - -    pub fn queue(&mut self, section: glow_glyph::Section<'_>) { -        self.draw_brush.borrow_mut().queue(section); -    } - -    pub fn draw_queued( -        &mut self, -        gl: &glow::Context, -        transformation: Transformation, -        region: glow_glyph::Region, -    ) { -        self.draw_brush -            .borrow_mut() -            .draw_queued_with_transform_and_scissoring( -                gl, -                transformation.into(), -                region, -            ) -            .expect("Draw text"); -    } - -    pub fn measure( -        &self, -        content: &str, -        size: f32, -        font: iced_native::Font, -        bounds: iced_native::Size, -    ) -> (f32, f32) { -        use glow_glyph::GlyphCruncher; - -        let glow_glyph::FontId(font_id) = self.find_font(font); - -        let section = glow_glyph::Section { -            bounds: (bounds.width, bounds.height), -            text: vec![glow_glyph::Text { -                text: content, -                scale: size.into(), -                font_id: glow_glyph::FontId(font_id), -                extra: glow_glyph::Extra::default(), -            }], -            ..Default::default() -        }; - -        if let Some(bounds) = -            self.measure_brush.borrow_mut().glyph_bounds(section) -        { -            (bounds.width().ceil(), bounds.height().ceil()) -        } else { -            (0.0, 0.0) -        } -    } - -    pub fn hit_test( -        &self, -        content: &str, -        size: f32, -        font: iced_native::Font, -        bounds: iced_native::Size, -        point: iced_native::Point, -        nearest_only: bool, -    ) -> Option<Hit> { -        use glow_glyph::GlyphCruncher; - -        let glow_glyph::FontId(font_id) = self.find_font(font); - -        let section = glow_glyph::Section { -            bounds: (bounds.width, bounds.height), -            text: vec![glow_glyph::Text { -                text: content, -                scale: size.into(), -                font_id: glow_glyph::FontId(font_id), -                extra: glow_glyph::Extra::default(), -            }], -            ..Default::default() -        }; - -        let mut mb = self.measure_brush.borrow_mut(); - -        // The underlying type is FontArc, so clones are cheap. -        use ab_glyph::{Font, ScaleFont}; -        let font = mb.fonts()[font_id].clone().into_scaled(size); - -        // Implements an iterator over the glyph bounding boxes. -        let bounds = mb.glyphs(section).map( -            |glow_glyph::SectionGlyph { -                 byte_index, glyph, .. -             }| { -                ( -                    *byte_index, -                    iced_native::Rectangle::new( -                        iced_native::Point::new( -                            glyph.position.x - font.h_side_bearing(glyph.id), -                            glyph.position.y - font.ascent(), -                        ), -                        iced_native::Size::new( -                            font.h_advance(glyph.id), -                            font.ascent() - font.descent(), -                        ), -                    ), -                ) -            }, -        ); - -        // Implements computation of the character index based on the byte index -        // within the input string. -        let char_index = |byte_index| { -            let mut b_count = 0; -            for (i, utf8_len) in -                content.chars().map(|c| c.len_utf8()).enumerate() -            { -                if byte_index < (b_count + utf8_len) { -                    return i; -                } -                b_count += utf8_len; -            } - -            byte_index -        }; - -        if !nearest_only { -            for (idx, bounds) in bounds.clone() { -                if bounds.contains(point) { -                    return Some(Hit::CharOffset(char_index(idx))); -                } -            } -        } - -        let nearest = bounds -            .map(|(index, bounds)| (index, bounds.center())) -            .min_by(|(_, center_a), (_, center_b)| { -                center_a -                    .distance(point) -                    .partial_cmp(¢er_b.distance(point)) -                    .unwrap_or(std::cmp::Ordering::Greater) -            }); - -        nearest.map(|(idx, center)| { -            Hit::NearestCharOffset(char_index(idx), point - center) -        }) -    } - -    pub fn trim_measurement_cache(&mut self) { -        // TODO: We should probably use a `GlyphCalculator` for this. However, -        // it uses a lifetimed `GlyphCalculatorGuard` with side-effects on drop. -        // This makes stuff quite inconvenient. A manual method for trimming the -        // cache would make our lives easier. -        loop { -            let action = self -                .measure_brush -                .borrow_mut() -                .process_queued(|_, _| {}, |_| {}); - -            match action { -                Ok(_) => break, -                Err(glyph_brush::BrushError::TextureTooSmall { suggested }) => { -                    let (width, height) = suggested; - -                    self.measure_brush -                        .borrow_mut() -                        .resize_texture(width, height); -                } -            } -        } -    } - -    pub fn find_font(&self, font: iced_native::Font) -> glow_glyph::FontId { -        match font { -            iced_native::Font::Default => glow_glyph::FontId(0), -            iced_native::Font::External { name, bytes } => { -                if let Some(font_id) = self.draw_font_map.borrow().get(name) { -                    return *font_id; -                } - -                let font = ab_glyph::FontArc::try_from_slice(bytes) -                    .expect("Load font"); - -                let _ = self.measure_brush.borrow_mut().add_font(font.clone()); - -                let font_id = self.draw_brush.borrow_mut().add_font(font); - -                let _ = self -                    .draw_font_map -                    .borrow_mut() -                    .insert(String::from(name), font_id); - -                font_id -            } -        } -    } -} diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs deleted file mode 100644 index 42c88455..00000000 --- a/glow/src/triangle.rs +++ /dev/null @@ -1,595 +0,0 @@ -//! Draw meshes of triangles. -use crate::program; -use crate::Transformation; - -use iced_graphics::gradient::Gradient; -use iced_graphics::layer::mesh::{self, Mesh}; -use iced_graphics::triangle::{ColoredVertex2D, Vertex2D}; - -use glow::HasContext; -use std::marker::PhantomData; - -#[cfg(feature = "tracing")] -use tracing::info_span; - -const DEFAULT_VERTICES: usize = 1_000; -const DEFAULT_INDICES: usize = 1_000; - -#[derive(Debug)] -pub(crate) struct Pipeline { -    indices: Buffer<u32>, -    solid: solid::Program, -    gradient: gradient::Program, -} - -impl Pipeline { -    pub fn new(gl: &glow::Context, shader_version: &program::Version) -> Self { -        let mut indices = unsafe { -            Buffer::new( -                gl, -                glow::ELEMENT_ARRAY_BUFFER, -                glow::DYNAMIC_DRAW, -                DEFAULT_INDICES, -            ) -        }; - -        let solid = solid::Program::new(gl, shader_version); -        let gradient = gradient::Program::new(gl, shader_version); - -        unsafe { -            gl.bind_vertex_array(Some(solid.vertex_array)); -            indices.bind(gl, 0); - -            gl.bind_vertex_array(Some(gradient.vertex_array)); -            indices.bind(gl, 0); - -            gl.bind_vertex_array(None); -        } - -        Self { -            indices, -            solid, -            gradient, -        } -    } - -    pub fn draw( -        &mut self, -        meshes: &[Mesh<'_>], -        gl: &glow::Context, -        target_height: u32, -        transformation: Transformation, -        scale_factor: f32, -    ) { -        #[cfg(feature = "tracing")] -        let _ = info_span!("Glow::Triangle", "DRAW").enter(); - -        unsafe { -            gl.enable(glow::MULTISAMPLE); -            gl.enable(glow::SCISSOR_TEST); -        } - -        // Count the total amount of vertices & indices we need to handle -        let count = mesh::attribute_count_of(meshes); - -        // Then we ensure the current attribute buffers are big enough, resizing if necessary -        unsafe { -            self.indices.bind(gl, count.indices); -        } - -        // We upload all the vertices and indices upfront -        let mut solid_vertex_offset = 0; -        let mut gradient_vertex_offset = 0; -        let mut index_offset = 0; - -        for mesh in meshes { -            let indices = mesh.indices(); - -            unsafe { -                gl.buffer_sub_data_u8_slice( -                    glow::ELEMENT_ARRAY_BUFFER, -                    (index_offset * std::mem::size_of::<u32>()) as i32, -                    bytemuck::cast_slice(indices), -                ); - -                index_offset += indices.len(); -            } - -            match mesh { -                Mesh::Solid { buffers, .. } => { -                    unsafe { -                        self.solid.vertices.bind(gl, count.solid_vertices); - -                        gl.buffer_sub_data_u8_slice( -                            glow::ARRAY_BUFFER, -                            (solid_vertex_offset -                                * std::mem::size_of::<ColoredVertex2D>()) -                                as i32, -                            bytemuck::cast_slice(&buffers.vertices), -                        ); -                    } - -                    solid_vertex_offset += buffers.vertices.len(); -                } -                Mesh::Gradient { buffers, .. } => { -                    unsafe { -                        self.gradient -                            .vertices -                            .bind(gl, count.gradient_vertices); - -                        gl.buffer_sub_data_u8_slice( -                            glow::ARRAY_BUFFER, -                            (gradient_vertex_offset -                                * std::mem::size_of::<Vertex2D>()) -                                as i32, -                            bytemuck::cast_slice(&buffers.vertices), -                        ); -                    } - -                    gradient_vertex_offset += buffers.vertices.len(); -                } -            } -        } - -        // Then we draw each mesh using offsets -        let mut last_solid_vertex = 0; -        let mut last_gradient_vertex = 0; -        let mut last_index = 0; - -        for mesh in meshes { -            let indices = mesh.indices(); -            let origin = mesh.origin(); - -            let transform = -                transformation * Transformation::translate(origin.x, origin.y); - -            let clip_bounds = (mesh.clip_bounds() * scale_factor).snap(); - -            unsafe { -                gl.scissor( -                    clip_bounds.x as i32, -                    (target_height - (clip_bounds.y + clip_bounds.height)) -                        as i32, -                    clip_bounds.width as i32, -                    clip_bounds.height as i32, -                ); -            } - -            match mesh { -                Mesh::Solid { buffers, .. } => unsafe { -                    gl.use_program(Some(self.solid.program)); -                    gl.bind_vertex_array(Some(self.solid.vertex_array)); - -                    if transform != self.solid.uniforms.transform { -                        gl.uniform_matrix_4_f32_slice( -                            Some(&self.solid.uniforms.transform_location), -                            false, -                            transform.as_ref(), -                        ); - -                        self.solid.uniforms.transform = transform; -                    } - -                    gl.draw_elements_base_vertex( -                        glow::TRIANGLES, -                        indices.len() as i32, -                        glow::UNSIGNED_INT, -                        (last_index * std::mem::size_of::<u32>()) as i32, -                        last_solid_vertex as i32, -                    ); - -                    last_solid_vertex += buffers.vertices.len(); -                }, -                Mesh::Gradient { -                    buffers, gradient, .. -                } => unsafe { -                    gl.use_program(Some(self.gradient.program)); -                    gl.bind_vertex_array(Some(self.gradient.vertex_array)); - -                    if transform != self.gradient.uniforms.transform { -                        gl.uniform_matrix_4_f32_slice( -                            Some(&self.gradient.uniforms.locations.transform), -                            false, -                            transform.as_ref(), -                        ); - -                        self.gradient.uniforms.transform = transform; -                    } - -                    if &self.gradient.uniforms.gradient != *gradient { -                        match gradient { -                            Gradient::Linear(linear) => { -                                gl.uniform_4_f32( -                                    Some( -                                        &self -                                            .gradient -                                            .uniforms -                                            .locations -                                            .gradient_direction, -                                    ), -                                    linear.start.x, -                                    linear.start.y, -                                    linear.end.x, -                                    linear.end.y, -                                ); - -                                gl.uniform_1_i32( -                                    Some( -                                        &self -                                            .gradient -                                            .uniforms -                                            .locations -                                            .color_stops_size, -                                    ), -                                    (linear.color_stops.len() * 2) as i32, -                                ); - -                                let mut stops = [0.0; 128]; - -                                for (index, stop) in linear -                                    .color_stops -                                    .iter() -                                    .enumerate() -                                    .take(16) -                                { -                                    let [r, g, b, a] = stop.color.into_linear(); - -                                    stops[index * 8] = r; -                                    stops[(index * 8) + 1] = g; -                                    stops[(index * 8) + 2] = b; -                                    stops[(index * 8) + 3] = a; -                                    stops[(index * 8) + 4] = stop.offset; -                                    stops[(index * 8) + 5] = 0.; -                                    stops[(index * 8) + 6] = 0.; -                                    stops[(index * 8) + 7] = 0.; -                                } - -                                gl.uniform_4_f32_slice( -                                    Some( -                                        &self -                                            .gradient -                                            .uniforms -                                            .locations -                                            .color_stops, -                                    ), -                                    &stops, -                                ); -                            } -                        } - -                        self.gradient.uniforms.gradient = (*gradient).clone(); -                    } - -                    gl.draw_elements_base_vertex( -                        glow::TRIANGLES, -                        indices.len() as i32, -                        glow::UNSIGNED_INT, -                        (last_index * std::mem::size_of::<u32>()) as i32, -                        last_gradient_vertex as i32, -                    ); - -                    last_gradient_vertex += buffers.vertices.len(); -                }, -            } - -            last_index += indices.len(); -        } - -        unsafe { -            gl.bind_vertex_array(None); -            gl.disable(glow::SCISSOR_TEST); -            gl.disable(glow::MULTISAMPLE); -        } -    } -} - -#[derive(Debug)] -pub struct Buffer<T> { -    raw: <glow::Context as HasContext>::Buffer, -    target: u32, -    usage: u32, -    size: usize, -    phantom: PhantomData<T>, -} - -impl<T> Buffer<T> { -    pub unsafe fn new( -        gl: &glow::Context, -        target: u32, -        usage: u32, -        size: usize, -    ) -> Self { -        let raw = gl.create_buffer().expect("Create buffer"); - -        let mut buffer = Buffer { -            raw, -            target, -            usage, -            size: 0, -            phantom: PhantomData, -        }; - -        buffer.bind(gl, size); - -        buffer -    } - -    pub unsafe fn bind(&mut self, gl: &glow::Context, size: usize) { -        gl.bind_buffer(self.target, Some(self.raw)); - -        if self.size < size { -            gl.buffer_data_size( -                self.target, -                (size * std::mem::size_of::<T>()) as i32, -                self.usage, -            ); - -            self.size = size; -        } -    } -} - -mod solid { -    use crate::program; -    use crate::triangle; -    use glow::{Context, HasContext, NativeProgram}; -    use iced_graphics::triangle::ColoredVertex2D; -    use iced_graphics::Transformation; - -    #[derive(Debug)] -    pub struct Program { -        pub program: <Context as HasContext>::Program, -        pub vertex_array: <glow::Context as HasContext>::VertexArray, -        pub vertices: triangle::Buffer<ColoredVertex2D>, -        pub uniforms: Uniforms, -    } - -    impl Program { -        pub fn new(gl: &Context, shader_version: &program::Version) -> Self { -            let program = unsafe { -                let vertex_shader = program::Shader::vertex( -                    gl, -                    shader_version, -                    include_str!("shader/common/solid.vert"), -                ); - -                let fragment_shader = program::Shader::fragment( -                    gl, -                    shader_version, -                    include_str!("shader/common/solid.frag"), -                ); - -                program::create( -                    gl, -                    &[vertex_shader, fragment_shader], -                    &[(0, "i_Position"), (1, "i_Color")], -                ) -            }; - -            let vertex_array = unsafe { -                gl.create_vertex_array().expect("Create vertex array") -            }; - -            let vertices = unsafe { -                triangle::Buffer::new( -                    gl, -                    glow::ARRAY_BUFFER, -                    glow::DYNAMIC_DRAW, -                    super::DEFAULT_VERTICES, -                ) -            }; - -            unsafe { -                gl.bind_vertex_array(Some(vertex_array)); - -                let stride = std::mem::size_of::<ColoredVertex2D>() as i32; - -                gl.enable_vertex_attrib_array(0); -                gl.vertex_attrib_pointer_f32( -                    0, -                    2, -                    glow::FLOAT, -                    false, -                    stride, -                    0, -                ); - -                gl.enable_vertex_attrib_array(1); -                gl.vertex_attrib_pointer_f32( -                    1, -                    4, -                    glow::FLOAT, -                    false, -                    stride, -                    4 * 2, -                ); - -                gl.bind_vertex_array(None); -            }; - -            Self { -                program, -                vertex_array, -                vertices, -                uniforms: Uniforms::new(gl, program), -            } -        } -    } - -    #[derive(Debug)] -    pub struct Uniforms { -        pub transform: Transformation, -        pub transform_location: <Context as HasContext>::UniformLocation, -    } - -    impl Uniforms { -        fn new(gl: &Context, program: NativeProgram) -> Self { -            let transform = Transformation::identity(); -            let transform_location = -                unsafe { gl.get_uniform_location(program, "u_Transform") } -                    .expect("Solid - Get u_Transform."); - -            unsafe { -                gl.use_program(Some(program)); - -                gl.uniform_matrix_4_f32_slice( -                    Some(&transform_location), -                    false, -                    transform.as_ref(), -                ); - -                gl.use_program(None); -            } - -            Self { -                transform, -                transform_location, -            } -        } -    } -} - -mod gradient { -    use crate::program; -    use crate::triangle; -    use glow::{Context, HasContext, NativeProgram}; -    use iced_graphics::gradient::{self, Gradient}; -    use iced_graphics::triangle::Vertex2D; -    use iced_graphics::Transformation; - -    #[derive(Debug)] -    pub struct Program { -        pub program: <Context as HasContext>::Program, -        pub vertex_array: <glow::Context as HasContext>::VertexArray, -        pub vertices: triangle::Buffer<Vertex2D>, -        pub uniforms: Uniforms, -    } - -    impl Program { -        pub fn new(gl: &Context, shader_version: &program::Version) -> Self { -            let program = unsafe { -                let vertex_shader = program::Shader::vertex( -                    gl, -                    shader_version, -                    include_str!("shader/common/gradient.vert"), -                ); - -                let fragment_shader = program::Shader::fragment( -                    gl, -                    shader_version, -                    include_str!("shader/common/gradient.frag"), -                ); - -                program::create( -                    gl, -                    &[vertex_shader, fragment_shader], -                    &[(0, "i_Position")], -                ) -            }; - -            let vertex_array = unsafe { -                gl.create_vertex_array().expect("Create vertex array") -            }; - -            let vertices = unsafe { -                triangle::Buffer::new( -                    gl, -                    glow::ARRAY_BUFFER, -                    glow::DYNAMIC_DRAW, -                    super::DEFAULT_VERTICES, -                ) -            }; - -            unsafe { -                gl.bind_vertex_array(Some(vertex_array)); - -                let stride = std::mem::size_of::<Vertex2D>() as i32; - -                gl.enable_vertex_attrib_array(0); -                gl.vertex_attrib_pointer_f32( -                    0, -                    2, -                    glow::FLOAT, -                    false, -                    stride, -                    0, -                ); - -                gl.bind_vertex_array(None); -            }; - -            Self { -                program, -                vertex_array, -                vertices, -                uniforms: Uniforms::new(gl, program), -            } -        } -    } - -    #[derive(Debug)] -    pub struct Uniforms { -        pub gradient: Gradient, -        pub transform: Transformation, -        pub locations: Locations, -    } - -    #[derive(Debug)] -    pub struct Locations { -        pub gradient_direction: <Context as HasContext>::UniformLocation, -        pub color_stops_size: <Context as HasContext>::UniformLocation, -        //currently the maximum number of stops is 16 due to lack of SSBO in GL2.1 -        pub color_stops: <Context as HasContext>::UniformLocation, -        pub transform: <Context as HasContext>::UniformLocation, -    } - -    impl Uniforms { -        fn new(gl: &Context, program: NativeProgram) -> Self { -            let gradient_direction = unsafe { -                gl.get_uniform_location(program, "gradient_direction") -            } -            .expect("Gradient - Get gradient_direction."); - -            let color_stops_size = -                unsafe { gl.get_uniform_location(program, "color_stops_size") } -                    .expect("Gradient - Get color_stops_size."); - -            let color_stops = unsafe { -                gl.get_uniform_location(program, "color_stops") -                    .expect("Gradient - Get color_stops.") -            }; - -            let transform = Transformation::identity(); -            let transform_location = -                unsafe { gl.get_uniform_location(program, "u_Transform") } -                    .expect("Solid - Get u_Transform."); - -            unsafe { -                gl.use_program(Some(program)); - -                gl.uniform_matrix_4_f32_slice( -                    Some(&transform_location), -                    false, -                    transform.as_ref(), -                ); - -                gl.use_program(None); -            } - -            Self { -                gradient: Gradient::Linear(gradient::Linear { -                    start: Default::default(), -                    end: Default::default(), -                    color_stops: vec![], -                }), -                transform: Transformation::identity(), -                locations: Locations { -                    gradient_direction, -                    color_stops_size, -                    color_stops, -                    transform: transform_location, -                }, -            } -        } -    } -} diff --git a/glow/src/window.rs b/glow/src/window.rs deleted file mode 100644 index aac5fb9e..00000000 --- a/glow/src/window.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! Display rendering results on windows. -mod compositor; - -pub use compositor::Compositor; diff --git a/glow/src/window/compositor.rs b/glow/src/window/compositor.rs deleted file mode 100644 index 20756032..00000000 --- a/glow/src/window/compositor.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::{Backend, Color, Error, Renderer, Settings, Viewport}; - -use glow::HasContext; -use iced_graphics::{compositor, Antialiasing, Size}; - -use core::ffi::c_void; -use std::marker::PhantomData; - -/// A window graphics backend for iced powered by `glow`. -#[allow(missing_debug_implementations)] -pub struct Compositor<Theme> { -    gl: glow::Context, -    theme: PhantomData<Theme>, -} - -impl<Theme> iced_graphics::window::GLCompositor for Compositor<Theme> { -    type Settings = Settings; -    type Renderer = Renderer<Theme>; - -    unsafe fn new( -        settings: Self::Settings, -        loader_function: impl FnMut(&str) -> *const c_void, -    ) -> Result<(Self, Self::Renderer), Error> { -        let gl = glow::Context::from_loader_function(loader_function); - -        log::info!("{:#?}", settings); - -        let version = gl.version(); -        log::info!( -            "OpenGL version: {:?} (Embedded: {})", -            version, -            version.is_embedded -        ); - -        let renderer = gl.get_parameter_string(glow::RENDERER); -        log::info!("Renderer: {}", renderer); - -        // Enable auto-conversion from/to sRGB -        gl.enable(glow::FRAMEBUFFER_SRGB); - -        // Enable alpha blending -        gl.enable(glow::BLEND); -        gl.blend_func_separate( -            glow::SRC_ALPHA, -            glow::ONE_MINUS_SRC_ALPHA, -            glow::ONE, -            glow::ONE_MINUS_SRC_ALPHA, -        ); - -        // Disable multisampling by default -        gl.disable(glow::MULTISAMPLE); - -        let renderer = Renderer::new(Backend::new(&gl, settings)); - -        Ok(( -            Self { -                gl, -                theme: PhantomData, -            }, -            renderer, -        )) -    } - -    fn sample_count(settings: &Settings) -> u32 { -        settings -            .antialiasing -            .map(Antialiasing::sample_count) -            .unwrap_or(0) -    } - -    fn resize_viewport(&mut self, physical_size: Size<u32>) { -        unsafe { -            self.gl.viewport( -                0, -                0, -                physical_size.width as i32, -                physical_size.height as i32, -            ); -        } -    } - -    fn fetch_information(&self) -> compositor::Information { -        let adapter = unsafe { self.gl.get_parameter_string(glow::RENDERER) }; - -        compositor::Information { -            backend: format!("{:?}", self.gl.version()), -            adapter, -        } -    } - -    fn present<T: AsRef<str>>( -        &mut self, -        renderer: &mut Self::Renderer, -        viewport: &Viewport, -        color: Color, -        overlay: &[T], -    ) { -        let gl = &self.gl; - -        let [r, g, b, a] = color.into_linear(); - -        unsafe { -            gl.clear_color(r, g, b, a); -            gl.clear(glow::COLOR_BUFFER_BIT); -        } - -        renderer.with_primitives(|backend, primitive| { -            backend.present(gl, primitive, viewport, overlay); -        }); -    } -}  | 
