summaryrefslogtreecommitdiffstats
path: root/glow
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-01-06 23:29:38 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2023-02-24 13:17:58 +0100
commitb9a9576207ddfc7afd89da30b7cfc7ca0d7e335c (patch)
treec0b4489f1e547fc335e6b82025891cefdc671274 /glow
parent573d27eb52bbfacf1b06983b4282f00eb5265bdc (diff)
downloadiced-b9a9576207ddfc7afd89da30b7cfc7ca0d7e335c.tar.gz
iced-b9a9576207ddfc7afd89da30b7cfc7ca0d7e335c.tar.bz2
iced-b9a9576207ddfc7afd89da30b7cfc7ca0d7e335c.zip
Remove `iced_glow`, `glyph-brush`, and `wgpu_glyph` dependencies
Diffstat (limited to 'glow')
-rw-r--r--glow/Cargo.toml51
-rw-r--r--glow/README.md51
-rw-r--r--glow/src/backend.rs280
-rw-r--r--glow/src/image.rs254
-rw-r--r--glow/src/image/storage.rs78
-rw-r--r--glow/src/lib.rs53
-rw-r--r--glow/src/program.rs133
-rw-r--r--glow/src/quad.rs74
-rw-r--r--glow/src/quad/compatibility.rs349
-rw-r--r--glow/src/quad/core.rs244
-rw-r--r--glow/src/settings.rs61
-rw-r--r--glow/src/shader/common/gradient.frag59
-rw-r--r--glow/src/shader/common/gradient.vert9
-rw-r--r--glow/src/shader/common/image.frag22
-rw-r--r--glow/src/shader/common/image.vert9
-rw-r--r--glow/src/shader/common/solid.frag18
-rw-r--r--glow/src/shader/common/solid.vert11
-rw-r--r--glow/src/shader/compatibility/quad.frag83
-rw-r--r--glow/src/shader/compatibility/quad.vert46
-rw-r--r--glow/src/shader/core/quad.frag95
-rw-r--r--glow/src/shader/core/quad.vert52
-rw-r--r--glow/src/text.rs257
-rw-r--r--glow/src/triangle.rs595
-rw-r--r--glow/src/window.rs4
-rw-r--r--glow/src/window/compositor.rs111
25 files changed, 0 insertions, 2999 deletions
diff --git a/glow/Cargo.toml b/glow/Cargo.toml
deleted file mode 100644
index 1a848ab7..00000000
--- a/glow/Cargo.toml
+++ /dev/null
@@ -1,51 +0,0 @@
-[package]
-name = "iced_glow"
-version = "0.7.0"
-authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
-edition = "2021"
-description = "A glow renderer for iced"
-license = "MIT AND OFL-1.1"
-repository = "https://github.com/iced-rs/iced"
-
-[features]
-svg = ["iced_graphics/svg"]
-image = ["iced_graphics/image"]
-png = ["iced_graphics/png"]
-jpeg = ["iced_graphics/jpeg"]
-jpeg_rayon = ["iced_graphics/jpeg_rayon"]
-gif = ["iced_graphics/gif"]
-webp = ["iced_graphics/webp"]
-pnm = ["iced_graphics/pnm"]
-ico = ["iced_graphics/ico"]
-bmp = ["iced_graphics/bmp"]
-hdr = ["iced_graphics/hdr"]
-dds = ["iced_graphics/dds"]
-farbfeld = ["iced_graphics/farbfeld"]
-canvas = ["iced_graphics/canvas"]
-qr_code = ["iced_graphics/qr_code"]
-default_system_font = ["iced_graphics/font-source"]
-
-[dependencies]
-glow = "0.11.1"
-glow_glyph = "0.5.0"
-glyph_brush = "0.7"
-euclid = "0.22"
-bytemuck = "1.4"
-log = "0.4"
-
-[dependencies.iced_native]
-version = "0.9"
-path = "../native"
-
-[dependencies.iced_graphics]
-version = "0.7"
-path = "../graphics"
-features = ["font-fallback", "font-icons", "opengl"]
-
-[dependencies.tracing]
-version = "0.1.6"
-optional = true
-
-[package.metadata.docs.rs]
-rustdoc-args = ["--cfg", "docsrs"]
-all-features = true
diff --git a/glow/README.md b/glow/README.md
deleted file mode 100644
index 95c9d62a..00000000
--- a/glow/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# `iced_glow`
-[![Documentation](https://docs.rs/iced_glow/badge.svg)][documentation]
-[![Crates.io](https://img.shields.io/crates/v/iced_glow.svg)](https://crates.io/crates/iced_glow)
-[![License](https://img.shields.io/crates/l/iced_glow.svg)](https://github.com/iced-rs/iced/blob/master/LICENSE)
-[![Discord Server](https://img.shields.io/discord/628993209984614400?label=&labelColor=6A7EC2&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.gg/3xZJ65GAhd)
-
-`iced_glow` is a [`glow`] renderer for [`iced_native`]. This renderer supports OpenGL 3.0+ and OpenGL ES 2.0.
-
-This renderer is mostly used as a fallback for hardware that doesn't support [`wgpu`] (Vulkan, Metal or DX12).
-
-Currently, `iced_glow` supports the following primitives:
-- Text, which is rendered using [`glow_glyph`]. No shaping at all.
-- Quads or rectangles, with rounded borders and a solid background color.
-- Clip areas, useful to implement scrollables or hide overflowing content.
-- Meshes of triangles, useful to draw geometry freely.
-
-<p align="center">
- <img alt="The native target" src="../docs/graphs/native.png" width="80%">
-</p>
-
-[documentation]: https://docs.rs/iced_glow
-[`iced_native`]: ../native
-[`glow`]: https://github.com/grovesNL/glow
-[`wgpu`]: https://github.com/gfx-rs/wgpu
-[`glow_glyph`]: https://github.com/hecrj/glow_glyph
-
-## Installation
-Add `iced_glow` as a dependency in your `Cargo.toml`:
-
-```toml
-iced_glow = "0.7"
-```
-
-__Iced moves fast and the `master` branch can contain breaking changes!__ If
-you want to learn about a specific release, check out [the release list].
-
-[the release list]: https://github.com/iced-rs/iced/releases
-
-## Current limitations
-
-The current implementation is quite naive, it uses:
-
-- A different pipeline/shader for each primitive
-- A very simplistic layer model: every `Clip` primitive will generate new layers
-- _Many_ render passes instead of preparing everything upfront
-- A glyph cache that is trimmed incorrectly when there are multiple layers (a [`glyph_brush`] limitation)
-
-Some of these issues are already being worked on! If you want to help, [get in touch!]
-
-[get in touch!]: ../CONTRIBUTING.md
-[`glyph_brush`]: https://github.com/alexheretic/glyph-brush
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`].
-//!
-//! ![The native path of the Iced ecosystem](https://github.com/iced-rs/iced/blob/0525d76ff94e828b7b21634fa94a747022001c83/docs/graphs/native.png?raw=true)
-//!
-//! [`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(&center_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);
- });
- }
-}