From faa7627ea41b1ce372bae7f0d2ae36e9b15a97a3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 31 May 2023 21:31:58 +0200 Subject: Introduce `web-colors` feature flag to enable sRGB linear blending This is how browsers perform color management. They treat gamma-corrected sRGB colors as if they were linear RGB. Correctness aside, this mode is introduced for legacy reasons. Most UI/UX tooling uses this color management as well, and many have created an intuition about how color should behave from interacting with a browser. This feature flag should facilitate application development with `iced` in those cases. More details: https://webcolorisstillbroken.com/ --- wgpu/Cargo.toml | 1 + wgpu/src/backend.rs | 3 ++- wgpu/src/geometry.rs | 7 ++++--- wgpu/src/layer.rs | 3 ++- wgpu/src/quad.rs | 5 +++-- wgpu/src/quad/solid.rs | 3 ++- wgpu/src/text.rs | 4 +++- wgpu/src/window/compositor.rs | 22 +++++++++++++--------- 8 files changed, 30 insertions(+), 18 deletions(-) (limited to 'wgpu') diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index b5401626..badd165b 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/iced-rs/iced" geometry = ["iced_graphics/geometry", "lyon"] image = ["iced_graphics/image"] svg = ["resvg"] +web-colors = ["iced_graphics/web-colors"] [dependencies] wgpu = "0.16" diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 844987f2..b524c615 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -1,6 +1,7 @@ use crate::core; use crate::core::{Color, Font, Point, Size}; use crate::graphics::backend; +use crate::graphics::color; use crate::graphics::{Primitive, Transformation, Viewport}; use crate::quad; use crate::text; @@ -239,7 +240,7 @@ impl Backend { load: match clear_color { Some(background_color) => wgpu::LoadOp::Clear({ let [r, g, b, a] = - background_color.into_linear(); + color::pack(background_color).components(); wgpu::Color { r: f64::from(r), diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs index 740ec20c..f81b5b2f 100644 --- a/wgpu/src/geometry.rs +++ b/wgpu/src/geometry.rs @@ -1,5 +1,6 @@ //! Build and draw geometry. use crate::core::{Point, Rectangle, Size, Vector}; +use crate::graphics::color; use crate::graphics::geometry::fill::{self, Fill}; use crate::graphics::geometry::{ LineCap, LineDash, LineJoin, Path, Stroke, Style, Text, @@ -68,7 +69,7 @@ impl BufferStack { (Style::Solid(color), Buffer::Solid(buffer)) => { Box::new(tessellation::BuffersBuilder::new( buffer, - TriangleVertex2DBuilder(color.into_linear()), + TriangleVertex2DBuilder(color::pack(*color)), )) } (Style::Gradient(gradient), Buffer::Gradient(buffer)) => { @@ -91,7 +92,7 @@ impl BufferStack { (Style::Solid(color), Buffer::Solid(buffer)) => { Box::new(tessellation::BuffersBuilder::new( buffer, - TriangleVertex2DBuilder(color.into_linear()), + TriangleVertex2DBuilder(color::pack(*color)), )) } (Style::Gradient(gradient), Buffer::Gradient(buffer)) => { @@ -526,7 +527,7 @@ impl tessellation::StrokeVertexConstructor } } -struct TriangleVertex2DBuilder([f32; 4]); +struct TriangleVertex2DBuilder(color::Packed); impl tessellation::FillVertexConstructor for TriangleVertex2DBuilder diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 1a870c15..71570e3d 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -11,6 +11,7 @@ pub use text::Text; use crate::core; use crate::core::alignment; use crate::core::{Color, Font, Point, Rectangle, Size, Vector}; +use crate::graphics::color; use crate::graphics::{Primitive, Viewport}; use crate::quad::{self, Quad}; @@ -150,7 +151,7 @@ impl<'a> Layer<'a> { bounds.y + translation.y, ], size: [bounds.width, bounds.height], - border_color: border_color.into_linear(), + border_color: color::pack(*border_color), border_radius: *border_radius, border_width: *border_width, }; diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs index 9c5ed05f..37d0c623 100644 --- a/wgpu/src/quad.rs +++ b/wgpu/src/quad.rs @@ -5,6 +5,7 @@ use gradient::Gradient; use solid::Solid; use crate::core::{Background, Rectangle}; +use crate::graphics::color; use crate::graphics::{self, Transformation}; use bytemuck::{Pod, Zeroable}; @@ -217,7 +218,7 @@ pub struct Quad { pub size: [f32; 2], /// The border color of the [`Quad`], in __linear RGB__. - pub border_color: [f32; 4], + pub border_color: color::Packed, /// The border radii of the [`Quad`]. pub border_radius: [f32; 4], @@ -250,7 +251,7 @@ impl Batch { let kind = match background { Background::Color(color) => { self.solids.push(Solid { - color: color.into_linear(), + color: color::pack(*color), quad, }); diff --git a/wgpu/src/quad/solid.rs b/wgpu/src/quad/solid.rs index f667c42c..f8f1e3a5 100644 --- a/wgpu/src/quad/solid.rs +++ b/wgpu/src/quad/solid.rs @@ -1,3 +1,4 @@ +use crate::graphics::color; use crate::quad::{self, Quad}; use crate::Buffer; @@ -9,7 +10,7 @@ use std::ops::Range; #[repr(C)] pub struct Solid { /// The background color data of the quad. - pub color: [f32; 4], + pub color: color::Packed, /// The [`Quad`] data of the [`Solid`]. pub quad: Quad, diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 714e0400..a12bc9f7 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -2,6 +2,7 @@ use crate::core::alignment; use crate::core::font::{self, Font}; use crate::core::text::{Hit, LineHeight, Shaping}; use crate::core::{Pixels, Point, Rectangle, Size}; +use crate::graphics::color; use crate::layer::Text; use rustc_hash::{FxHashMap, FxHashSet}; @@ -155,7 +156,8 @@ impl Pipeline { bottom: (clip_bounds.y + clip_bounds.height) as i32, }, default_color: { - let [r, g, b, a] = section.color.into_linear(); + let [r, g, b, a] = + color::pack(section.color).components(); glyphon::Color::rgba( (r * 255.0) as u8, diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs index 500458e8..2eaafde0 100644 --- a/wgpu/src/window/compositor.rs +++ b/wgpu/src/window/compositor.rs @@ -1,6 +1,7 @@ //! Connect a window with a renderer. use crate::core::Color; use crate::graphics; +use crate::graphics::color; use crate::graphics::compositor; use crate::graphics::{Error, Primitive, Viewport}; use crate::{Backend, Renderer, Settings}; @@ -69,16 +70,19 @@ impl Compositor { let format = compatible_surface.as_ref().and_then(|surface| { let capabilities = surface.get_capabilities(&adapter); - capabilities - .formats - .iter() - .copied() - .find(wgpu::TextureFormat::is_srgb) - .or_else(|| { - log::warn!("No sRGB format found!"); + let mut formats = capabilities.formats.iter().copied(); - capabilities.formats.first().copied() - }) + let format = if color::GAMMA_CORRECTION { + formats.find(wgpu::TextureFormat::is_srgb) + } else { + formats.find(|format| !wgpu::TextureFormat::is_srgb(format)) + }; + + format.or_else(|| { + log::warn!("No format found!"); + + capabilities.formats.first().copied() + }) })?; log::info!("Selected format: {:?}", format); -- cgit From f1b259a28fdb92ce62ceb6fcea9547b52ecc77d3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 31 May 2023 21:42:39 +0200 Subject: Avoid gamma correction when `web-colors` is enabled for images --- wgpu/src/image/atlas.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'wgpu') diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index 9b6dcc46..28bc4943 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -13,6 +13,7 @@ use allocator::Allocator; pub const SIZE: u32 = 2048; use crate::core::Size; +use crate::graphics::color; #[derive(Debug)] pub struct Atlas { @@ -35,7 +36,11 @@ impl Atlas { mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8UnormSrgb, + format: if color::GAMMA_CORRECTION { + wgpu::TextureFormat::Rgba8UnormSrgb + } else { + wgpu::TextureFormat::Rgba8Unorm + }, usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::TEXTURE_BINDING, -- cgit From c528f2129e5ce3b30e313f731588082c49beb30b Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Wed, 31 May 2023 21:45:12 +0200 Subject: Use proper gamma correction mode in `image::Atlas::grow` --- wgpu/src/image/atlas.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'wgpu') diff --git a/wgpu/src/image/atlas.rs b/wgpu/src/image/atlas.rs index 28bc4943..e3de1290 100644 --- a/wgpu/src/image/atlas.rs +++ b/wgpu/src/image/atlas.rs @@ -351,7 +351,11 @@ impl Atlas { mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8UnormSrgb, + format: if color::GAMMA_CORRECTION { + wgpu::TextureFormat::Rgba8UnormSrgb + } else { + wgpu::TextureFormat::Rgba8Unorm + }, usage: wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::TEXTURE_BINDING, -- cgit From b5fc0f4a3aa45d33d81d5799396f0b0770c4dff3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 1 Jun 2023 03:10:02 +0200 Subject: Use consistent color strategy in `glyphon` --- wgpu/Cargo.toml | 2 +- wgpu/src/text.rs | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'wgpu') diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml index badd165b..7e50dff2 100644 --- a/wgpu/Cargo.toml +++ b/wgpu/Cargo.toml @@ -45,7 +45,7 @@ path = "../graphics" [dependencies.glyphon] version = "0.2" git = "https://github.com/hecrj/glyphon.git" -rev = "cf7fe9df00499b868a6a94fa5fdb0a4ca368c9f9" +rev = "26f92369da3704988e3e27f0b35e705c6b2de203" [dependencies.glam] version = "0.24" diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index a12bc9f7..0d88865c 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -36,7 +36,16 @@ impl Pipeline { .into_iter(), )), renderers: Vec::new(), - atlas: glyphon::TextAtlas::new(device, queue, format), + atlas: glyphon::TextAtlas::new( + device, + queue, + format, + if color::GAMMA_CORRECTION { + glyphon::ColorMode::Accurate + } else { + glyphon::ColorMode::Web + }, + ), prepare_layer: 0, measurement_cache: RefCell::new(Cache::new()), render_cache: Cache::new(), -- cgit