Shaders: more `graster-nodes` no-std fixups (#3090)

* gcore-shaders: fix missing `num-traits/libm` features

* graster-nodes: fix missing cfg on use statements

* shaders: use unchecked Color constructors

* graster-nodes: remove async from shader nodes not needing it

* gcore-shaders: remove explicit fn pointer

* graster-nodes: make kurbo std-only

* graster-nodes: replace glam reexport with normal dep

* gcore: impl Display for ProtoNodeIdentifier

* unify glam workspace dep
This commit is contained in:
Firestar99 2025-08-26 20:25:05 +02:00 committed by GitHub
parent c5991c6f61
commit a744499f4f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 44 additions and 33 deletions

1
Cargo.lock generated
View File

@ -2023,6 +2023,7 @@ dependencies = [
"kurbo",
"ndarray",
"node-macro",
"num-traits",
"rand 0.9.1",
"rand_chacha 0.9.0",
"serde",

View File

@ -126,9 +126,9 @@ usvg = "0.44"
rand = { version = "0.9", default-features = false, features = ["std_rng"] }
rand_chacha = "0.9"
glam = { version = "0.29", default-features = false, features = [
"serde",
"nostd-libm",
"scalar-math",
"debug-glam-assert",
"bytemuck",
] }
base64 = "0.22"
image = { version = "0.25", default-features = false, features = [
@ -142,7 +142,7 @@ pretty_assertions = "1.4.1"
fern = { version = "0.7", features = ["colored"] }
num_enum = "0.7"
num-derive = "0.4"
num-traits = { version = "0.2", default-features = false, features = ["i128"] }
num-traits = { version = "0.2", default-features = false, features = ["libm"] }
specta = { version = "2.0.0-rc.22", features = [
"glam",
"derive",

View File

@ -7,7 +7,7 @@ authors = ["Graphite Authors <contact@graphite.rs>"]
license = "MIT OR Apache-2.0"
[features]
std = ["dep:dyn-any", "dep:serde", "dep:specta", "dep:log", "half/std", "half/serde"]
std = ["dep:dyn-any", "dep:serde", "dep:specta", "dep:log", "glam/debug-glam-assert", "glam/std", "glam/serde", "half/std", "half/serde", "num-traits/std"]
[dependencies]
# Local std dependencies
@ -15,7 +15,7 @@ dyn-any = { workspace = true, optional = true }
# Workspace dependencies
bytemuck = { workspace = true }
glam = { version = "0.29", default-features = false, features = ["nostd-libm", "scalar-math"] }
glam = { workspace = true }
half = { workspace = true, default-features = false }
num-derive = { workspace = true }
num-traits = { workspace = true }

View File

@ -1,6 +1,6 @@
use core::fmt::Display;
use core::hash::{Hash, Hasher};
#[cfg(target_arch = "spirv")]
#[cfg(not(feature = "std"))]
use num_traits::float::Float;
#[derive(Debug, Clone, Copy, PartialEq)]

View File

@ -3,7 +3,7 @@ use bytemuck::{Pod, Zeroable};
use core::fmt::Debug;
use glam::DVec2;
use num_derive::*;
#[cfg(target_arch = "spirv")]
#[cfg(not(feature = "std"))]
use num_traits::float::Float;
pub trait Linear {

View File

@ -4,9 +4,9 @@ use bytemuck::{Pod, Zeroable};
use core::fmt::Debug;
use core::hash::Hash;
use half::f16;
#[cfg(target_arch = "spirv")]
#[cfg(not(feature = "std"))]
use num_traits::Euclid;
#[cfg(target_arch = "spirv")]
#[cfg(not(feature = "std"))]
use num_traits::float::Float;
#[repr(C)]
@ -439,9 +439,9 @@ impl Color {
lightness + saturation - lightness * saturation
};
let temp2 = 2. * lightness - temp1;
#[cfg(not(target_arch = "spirv"))]
#[cfg(feature = "std")]
let rem = |x: f32| x.rem_euclid(1.);
#[cfg(target_arch = "spirv")]
#[cfg(not(feature = "std"))]
let rem = |x: f32| x.rem_euclid(&1.);
let mut red = rem(hue + 1. / 3.);
@ -700,7 +700,7 @@ impl Color {
if c_s <= 0.5 {
c_b - (1. - 2. * c_s) * c_b * (1. - c_b)
} else {
let d: fn(f32) -> f32 = |x| if x <= 0.25 { ((16. * x - 12.) * x + 4.) * x } else { x.sqrt() };
let d = |x: f32| if x <= 0.25 { ((16. * x - 12.) * x + 4.) * x } else { x.sqrt() };
c_b + (2. * c_s - 1.) * (d(c_b) - c_b)
}
}
@ -892,9 +892,9 @@ impl Color {
} else {
4. + (self.red - self.green) / (max_channel - min_channel)
} / 6.;
#[cfg(not(target_arch = "spirv"))]
#[cfg(feature = "std")]
let hue = hue.rem_euclid(1.);
#[cfg(target_arch = "spirv")]
#[cfg(not(feature = "std"))]
let hue = hue.rem_euclid(&1.);
[hue, saturation, lightness, self.alpha]

View File

@ -1,6 +1,7 @@
use std::any::TypeId;
pub use std::borrow::Cow;
use std::fmt::{Display, Formatter};
use std::ops::Deref;
#[macro_export]
@ -160,6 +161,12 @@ impl Deref for ProtoNodeIdentifier {
}
}
impl Display for ProtoNodeIdentifier {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("ProtoNodeIdentifier").field(&self.name).finish()
}
}
fn migrate_type_descriptor_names<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Cow<'static, str>, D::Error> {
use serde::Deserialize;

View File

@ -18,7 +18,9 @@ std = [
"dep:fastnoise-lite",
"dep:serde",
"dep:specta",
"dep:glam",
"dep:kurbo",
"glam/debug-glam-assert",
"glam/serde",
]
[dependencies]
@ -32,8 +34,8 @@ graphene-core = { workspace = true, optional = true }
# Workspace dependencies
bytemuck = { workspace = true }
# glam is reexported from gcore-shaders in no_std mode
glam = { workspace = true, optional = true }
glam = { workspace = true }
num-traits = { workspace = true }
# Workspace std dependencies
specta = { workspace = true, optional = true }
@ -43,7 +45,7 @@ rand = { workspace = true, optional = true }
rand_chacha = { workspace = true, optional = true }
fastnoise-lite = { workspace = true, optional = true }
serde = { workspace = true, optional = true }
kurbo = { workspace = true }
kurbo = { workspace = true, optional = true }
[dev-dependencies]
tokio = { workspace = true }

View File

@ -7,10 +7,13 @@ use core::fmt::Debug;
use graphene_core::gradient::GradientStops;
#[cfg(feature = "std")]
use graphene_core::raster_types::{CPU, Raster};
#[cfg(feature = "std")]
use graphene_core::table::Table;
use graphene_core_shaders::color::Color;
use graphene_core_shaders::context::Ctx;
use graphene_core_shaders::registry::types::{Angle, Percentage, SignedPercentage};
#[cfg(not(feature = "std"))]
use num_traits::float::Float;
// TODO: Implement the following:
// Color Balance
@ -125,7 +128,7 @@ fn make_opaque<T: Adjust<Color>>(
if color.a() == 0. {
return color.with_alpha(1.);
}
Color::from_rgbaf32(color.r() / color.a(), color.g() / color.a(), color.b() / color.a(), 1.).unwrap()
Color::from_rgbaf32_unchecked(color.r() / color.a(), color.g() / color.a(), color.b() / color.a(), 1.)
});
input
}
@ -295,7 +298,7 @@ fn levels<T: Adjust<Color>>(
// https://stackoverflow.com/a/55233732/775283
// Works the same for gamma and linear color
#[node_macro::node(name("Black & White"), category("Raster: Adjustment"), shader_node(PerPixelAdjust))]
async fn black_and_white<T: Adjust<Color>>(
fn black_and_white<T: Adjust<Color>>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,
@ -360,7 +363,7 @@ async fn black_and_white<T: Adjust<Color>>(
// TODO: Fix "Color" blend mode implementation so it matches the expected behavior perfectly (it's currently close)
let color = tint.with_luminance(luminance);
let color = Color::from_rgbaf32(color.r(), color.g(), color.b(), alpha_part).unwrap();
let color = Color::from_rgbaf32_unchecked(color.r(), color.g(), color.b(), alpha_part);
color.to_linear_srgb()
});
@ -371,7 +374,7 @@ async fn black_and_white<T: Adjust<Color>>(
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#:~:text=%27hue%20%27%20%3D%20Old,saturation%2C%20Photoshop%205.0
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#:~:text=0%20%3D%20Use%20other.-,Hue/Saturation,-Hue/Saturation%20settings
#[node_macro::node(name("Hue/Saturation"), category("Raster: Adjustment"), shader_node(PerPixelAdjust))]
async fn hue_saturation<T: Adjust<Color>>(
fn hue_saturation<T: Adjust<Color>>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,
@ -406,7 +409,7 @@ async fn hue_saturation<T: Adjust<Color>>(
// Aims for interoperable compatibility with:
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#:~:text=%27%20%3D%20Color%20Lookup-,%27nvrt%27%20%3D%20Invert,-%27post%27%20%3D%20Posterize
#[node_macro::node(category("Raster: Adjustment"), shader_node(PerPixelAdjust))]
async fn invert<T: Adjust<Color>>(
fn invert<T: Adjust<Color>>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,
@ -429,7 +432,7 @@ async fn invert<T: Adjust<Color>>(
// Aims for interoperable compatibility with:
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#:~:text=post%27%20%3D%20Posterize-,%27thrs%27%20%3D%20Threshold,-%27grdm%27%20%3D%20Gradient
#[node_macro::node(category("Raster: Adjustment"), shader_node(PerPixelAdjust))]
async fn threshold<T: Adjust<Color>>(
fn threshold<T: Adjust<Color>>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,
@ -475,7 +478,7 @@ async fn threshold<T: Adjust<Color>>(
// When both parameters are set, it is equivalent to running this adjustment twice, with only vibrance set and then only saturation set.
// (Except for some noise probably due to rounding error.)
#[node_macro::node(category("Raster: Adjustment"), shader_node(PerPixelAdjust))]
async fn vibrance<T: Adjust<Color>>(
fn vibrance<T: Adjust<Color>>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,
@ -641,7 +644,7 @@ pub enum DomainWarpType {
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#:~:text=%27mixr%27%20%3D%20Channel%20Mixer
// https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#:~:text=Lab%20color%20only-,Channel%20Mixer,-Key%20is%20%27mixr
#[node_macro::node(category("Raster: Adjustment"), properties("channel_mixer_properties"), shader_node(PerPixelAdjust))]
async fn channel_mixer<T: Adjust<Color>>(
fn channel_mixer<T: Adjust<Color>>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,
@ -770,7 +773,7 @@ pub enum SelectiveColorChoice {
// Algorithm based on:
// https://blog.pkh.me/p/22-understanding-selective-coloring-in-adobe-photoshop.html
#[node_macro::node(category("Raster: Adjustment"), properties("selective_color_properties"), shader_node(PerPixelAdjust))]
async fn selective_color<T: Adjust<Color>>(
fn selective_color<T: Adjust<Color>>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,
@ -913,7 +916,7 @@ async fn selective_color<T: Adjust<Color>>(
// https://www.axiomx.com/posterize.htm
// This algorithm produces fully accurate output in relation to the industry standard.
#[node_macro::node(category("Raster: Adjustment"), shader_node(PerPixelAdjust))]
async fn posterize<T: Adjust<Color>>(
fn posterize<T: Adjust<Color>>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,
@ -947,7 +950,7 @@ async fn posterize<T: Adjust<Color>>(
// Algorithm based on:
// https://geraldbakker.nl/psnumbers/exposure.html
#[node_macro::node(category("Raster: Adjustment"), properties("exposure_properties"), shader_node(PerPixelAdjust))]
async fn exposure<T: Adjust<Color>>(
fn exposure<T: Adjust<Color>>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,

View File

@ -3,6 +3,7 @@ use crate::adjust::Adjust;
use graphene_core::gradient::GradientStops;
#[cfg(feature = "std")]
use graphene_core::raster_types::{CPU, Raster};
#[cfg(feature = "std")]
use graphene_core::table::Table;
use graphene_core_shaders::Ctx;
use graphene_core_shaders::blending::BlendMode;
@ -132,7 +133,7 @@ pub fn apply_blend_mode(foreground: Color, background: Color, blend_mode: BlendM
}
#[node_macro::node(category("Raster"), shader_node(PerPixelAdjust))]
async fn blend<T: Blend<Color> + Send>(
fn blend<T: Blend<Color> + Send>(
_: impl Ctx,
#[implementations(
Table<Raster<CPU>>,

View File

@ -1,8 +1,5 @@
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
pub use graphene_core_shaders::glam;
pub mod adjust;
pub mod adjustments;
pub mod blending_nodes;