diff --git a/Cargo.lock b/Cargo.lock index 1663793bc9..e25fca7aaf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1491,7 +1491,7 @@ dependencies = [ [[package]] name = "blade-graphics" version = "0.4.0" -source = "git+https://github.com/kvark/blade?rev=f5766863de9dcc092e90fdbbc5e0007a99e7f9bf#f5766863de9dcc092e90fdbbc5e0007a99e7f9bf" +source = "git+https://github.com/kvark/blade?rev=e35b2d41f221a48b75f7cf2e78a81e7ecb7a383c#e35b2d41f221a48b75f7cf2e78a81e7ecb7a383c" dependencies = [ "ash", "ash-window", @@ -1521,7 +1521,7 @@ dependencies = [ [[package]] name = "blade-macros" version = "0.2.1" -source = "git+https://github.com/kvark/blade?rev=f5766863de9dcc092e90fdbbc5e0007a99e7f9bf#f5766863de9dcc092e90fdbbc5e0007a99e7f9bf" +source = "git+https://github.com/kvark/blade?rev=e35b2d41f221a48b75f7cf2e78a81e7ecb7a383c#e35b2d41f221a48b75f7cf2e78a81e7ecb7a383c" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index fa7b399865..a4134c6771 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -256,8 +256,8 @@ async-recursion = "1.0.0" async-tar = "0.4.2" async-trait = "0.1" bitflags = "2.4.2" -blade-graphics = { git = "https://github.com/kvark/blade", rev = "f5766863de9dcc092e90fdbbc5e0007a99e7f9bf" } -blade-macros = { git = "https://github.com/kvark/blade", rev = "f5766863de9dcc092e90fdbbc5e0007a99e7f9bf" } +blade-graphics = { git = "https://github.com/kvark/blade", rev = "e35b2d41f221a48b75f7cf2e78a81e7ecb7a383c" } +blade-macros = { git = "https://github.com/kvark/blade", rev = "e35b2d41f221a48b75f7cf2e78a81e7ecb7a383c" } cap-std = "3.0" chrono = { version = "0.4", features = ["serde"] } clap = { version = "4.4", features = ["derive"] } diff --git a/crates/gpui/src/platform/blade/blade_atlas.rs b/crates/gpui/src/platform/blade/blade_atlas.rs index 0334808b55..22b2e4f3f7 100644 --- a/crates/gpui/src/platform/blade/blade_atlas.rs +++ b/crates/gpui/src/platform/blade/blade_atlas.rs @@ -162,7 +162,7 @@ impl BladeAtlasState { usage = gpu::TextureUsage::COPY | gpu::TextureUsage::RESOURCE; } AtlasTextureKind::Polychrome => { - format = gpu::TextureFormat::Bgra8Unorm; + format = gpu::TextureFormat::Bgra8UnormSrgb; usage = gpu::TextureUsage::COPY | gpu::TextureUsage::RESOURCE; } AtlasTextureKind::Path => { diff --git a/crates/gpui/src/platform/blade/blade_renderer.rs b/crates/gpui/src/platform/blade/blade_renderer.rs index ff9c2742ee..b245089878 100644 --- a/crates/gpui/src/platform/blade/blade_renderer.rs +++ b/crates/gpui/src/platform/blade/blade_renderer.rs @@ -360,9 +360,7 @@ impl BladeRenderer { size: config.size, usage: gpu::TextureUsage::TARGET, display_sync: gpu::DisplaySync::Recent, - //Note: this matches the original logic of the Metal backend, - // but ultimaterly we need to switch to `Linear`. - color_space: gpu::ColorSpace::Srgb, + color_space: gpu::ColorSpace::Linear, allow_exclusive_full_screen: false, transparent: config.transparent, }; diff --git a/crates/gpui/src/platform/blade/shaders.wgsl b/crates/gpui/src/platform/blade/shaders.wgsl index 4dff403d89..4a4d924ea3 100644 --- a/crates/gpui/src/platform/blade/shaders.wgsl +++ b/crates/gpui/src/platform/blade/shaders.wgsl @@ -88,6 +88,14 @@ fn distance_from_clip_rect(unit_vertex: vec2, bounds: Bounds, clip_bounds: return distance_from_clip_rect_impl(position, clip_bounds); } +// https://gamedev.stackexchange.com/questions/92015/optimized-linear-to-srgb-glsl +fn srgb_to_linear(srgb: vec3) -> vec3 { + let cutoff = srgb < vec3(0.04045); + let higher = pow((srgb + vec3(0.055)) / vec3(1.055), vec3(2.4)); + let lower = srgb / vec3(12.92); + return select(higher, lower, cutoff); +} + fn hsla_to_rgba(hsla: Hsla) -> vec4 { let h = hsla.h * 6.0; // Now, it's an angle but scaled in [0, 6) range let s = hsla.s; @@ -97,8 +105,7 @@ fn hsla_to_rgba(hsla: Hsla) -> vec4 { let c = (1.0 - abs(2.0 * l - 1.0)) * s; let x = c * (1.0 - abs(h % 2.0 - 1.0)); let m = l - c / 2.0; - - var color = vec4(m, m, m, a); + var color = vec3(m); if (h >= 0.0 && h < 1.0) { color.r += c; @@ -120,7 +127,12 @@ fn hsla_to_rgba(hsla: Hsla) -> vec4 { color.b += x; } - return color; + // Input colors are assumed to be in sRGB space, + // but blending and rendering needs to happen in linear space. + // The output will be converted to sRGB by either the target + // texture format or the swapchain color space. + let linear = srgb_to_linear(color); + return vec4(linear, a); } fn over(below: vec4, above: vec4) -> vec4 { @@ -181,7 +193,8 @@ fn quad_sdf(point: vec2, bounds: Bounds, corner_radii: Corners) -> f32 { // target alpha compositing mode. fn blend_color(color: vec4, alpha_factor: f32) -> vec4 { let alpha = color.a * alpha_factor; - return select(vec4(color.rgb, alpha), vec4(color.rgb, 1.0) * alpha, globals.premultiplied_alpha != 0u); + let multiplier = select(1.0, alpha, globals.premultiplied_alpha != 0u); + return vec4(color.rgb * multiplier, alpha); } // --- quads --- //