mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-22 10:28:11 +08:00
Make hue saturation node work on the gpu + make f32 default for user inputs
This commit is contained in:
committed by
Keavon Chambers
parent
fea9f8ea24
commit
4abad688a2
@@ -35,6 +35,7 @@ async fn main() {
|
||||
}
|
||||
|
||||
async fn post_compile_spirv(State(state): State<Arc<AppState>>, Json(compile_request): Json<CompileRequest>) -> Result<Vec<u8>, StatusCode> {
|
||||
println!("compile request: {:?}", compile_request);
|
||||
if let Some(result) = state.cache.read().unwrap().get(&compile_request) {
|
||||
return result.clone();
|
||||
}
|
||||
@@ -44,6 +45,9 @@ async fn post_compile_spirv(State(state): State<Arc<AppState>>, Json(compile_req
|
||||
eprintln!("compilation failed: {}", e);
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
});
|
||||
if result.is_err() {
|
||||
return result;
|
||||
}
|
||||
state.cache.write().unwrap().insert(compile_request, result.clone());
|
||||
result
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ pub struct LevelsNode<InputStart, InputMid, InputEnd, OutputStart, OutputEnd> {
|
||||
|
||||
// From https://stackoverflow.com/questions/39510072/algorithm-for-adjustment-of-image-levels
|
||||
#[node_macro::node_fn(LevelsNode)]
|
||||
fn levels_node(color: Color, input_start: f64, input_mid: f64, input_end: f64, output_start: f64, output_end: f64) -> Color {
|
||||
fn levels_node(color: Color, input_start: f32, input_mid: f32, input_end: f32, output_start: f32, output_end: f32) -> Color {
|
||||
let color = color.to_gamma_srgb();
|
||||
|
||||
// Input Range (Range: 0-1)
|
||||
@@ -286,7 +286,7 @@ pub struct GrayscaleNode<Tint, Reds, Yellows, Greens, Cyans, Blues, Magentas> {
|
||||
// From <https://stackoverflow.com/a/55233732/775283>
|
||||
// Works the same for gamma and linear color
|
||||
#[node_macro::node_fn(GrayscaleNode)]
|
||||
fn grayscale_color_node(color: Color, tint: Color, reds: f64, yellows: f64, greens: f64, cyans: f64, blues: f64, magentas: f64) -> Color {
|
||||
fn grayscale_color_node(color: Color, tint: Color, reds: f32, yellows: f32, greens: f32, cyans: f32, blues: f32, magentas: f32) -> Color {
|
||||
let color = color.to_gamma_srgb();
|
||||
|
||||
let reds = reds as f32 / 100.;
|
||||
@@ -329,7 +329,7 @@ pub struct HueSaturationNode<Hue, Saturation, Lightness> {
|
||||
}
|
||||
|
||||
#[node_macro::node_fn(HueSaturationNode)]
|
||||
fn hue_shift_color_node(color: Color, hue_shift: f64, saturation_shift: f64, lightness_shift: f64) -> Color {
|
||||
fn hue_shift_color_node(color: Color, hue_shift: f32, saturation_shift: f32, lightness_shift: f32) -> Color {
|
||||
let color = color.to_gamma_srgb();
|
||||
|
||||
let [hue, saturation, lightness, alpha] = color.to_hsla();
|
||||
@@ -379,7 +379,7 @@ pub struct ThresholdNode<MinLuminance, MaxLuminance, LuminanceCalc> {
|
||||
}
|
||||
|
||||
#[node_macro::node_fn(ThresholdNode)]
|
||||
fn threshold_node(color: Color, min_luminance: f64, max_luminance: f64, luminance_calc: LuminanceCalculation) -> Color {
|
||||
fn threshold_node(color: Color, min_luminance: f32, max_luminance: f32, luminance_calc: LuminanceCalculation) -> Color {
|
||||
let min_luminance = Color::srgb_to_linear(min_luminance as f32 / 100.);
|
||||
let max_luminance = Color::srgb_to_linear(max_luminance as f32 / 100.);
|
||||
|
||||
@@ -405,7 +405,7 @@ pub struct BlendNode<BlendMode, Opacity> {
|
||||
}
|
||||
|
||||
#[node_macro::node_fn(BlendNode)]
|
||||
fn blend_node(input: (Color, Color), blend_mode: BlendMode, opacity: f64) -> Color {
|
||||
fn blend_node(input: (Color, Color), blend_mode: BlendMode, opacity: f32) -> Color {
|
||||
blend_colors(input.0, input.1, blend_mode, opacity as f32 / 100.)
|
||||
}
|
||||
|
||||
@@ -461,7 +461,7 @@ pub struct VibranceNode<Vibrance> {
|
||||
// Modified from https://stackoverflow.com/questions/33966121/what-is-the-algorithm-for-vibrance-filters
|
||||
// The results of this implementation are very close to correct, but not quite perfect
|
||||
#[node_macro::node_fn(VibranceNode)]
|
||||
fn vibrance_node(color: Color, vibrance: f64) -> Color {
|
||||
fn vibrance_node(color: Color, vibrance: f32) -> Color {
|
||||
let vibrance = vibrance as f32 / 100.;
|
||||
// Slow the effect down by half when it's negative, since artifacts begin appearing past -50%.
|
||||
// So this scales the 0% to -50% range to 0% to -100%.
|
||||
@@ -553,22 +553,22 @@ pub struct ChannelMixerNode<Monochrome, MonochromeR, MonochromeG, MonochromeB, M
|
||||
fn channel_mixer_node(
|
||||
color: Color,
|
||||
monochrome: bool,
|
||||
monochrome_r: f64,
|
||||
monochrome_g: f64,
|
||||
monochrome_b: f64,
|
||||
monochrome_c: f64,
|
||||
red_r: f64,
|
||||
red_g: f64,
|
||||
red_b: f64,
|
||||
red_c: f64,
|
||||
green_r: f64,
|
||||
green_g: f64,
|
||||
green_b: f64,
|
||||
green_c: f64,
|
||||
blue_r: f64,
|
||||
blue_g: f64,
|
||||
blue_b: f64,
|
||||
blue_c: f64,
|
||||
monochrome_r: f32,
|
||||
monochrome_g: f32,
|
||||
monochrome_b: f32,
|
||||
monochrome_c: f32,
|
||||
red_r: f32,
|
||||
red_g: f32,
|
||||
red_b: f32,
|
||||
red_c: f32,
|
||||
green_r: f32,
|
||||
green_g: f32,
|
||||
green_b: f32,
|
||||
green_c: f32,
|
||||
blue_r: f32,
|
||||
blue_g: f32,
|
||||
blue_b: f32,
|
||||
blue_c: f32,
|
||||
) -> Color {
|
||||
let color = color.to_gamma_srgb();
|
||||
|
||||
@@ -690,42 +690,42 @@ pub struct SelectiveColorNode<Absolute, RC, RM, RY, RK, YC, YM, YY, YK, GC, GM,
|
||||
fn selective_color_node(
|
||||
color: Color,
|
||||
mode: RelativeAbsolute,
|
||||
r_c: f64,
|
||||
r_m: f64,
|
||||
r_y: f64,
|
||||
r_k: f64,
|
||||
y_c: f64,
|
||||
y_m: f64,
|
||||
y_y: f64,
|
||||
y_k: f64,
|
||||
g_c: f64,
|
||||
g_m: f64,
|
||||
g_y: f64,
|
||||
g_k: f64,
|
||||
c_c: f64,
|
||||
c_m: f64,
|
||||
c_y: f64,
|
||||
c_k: f64,
|
||||
b_c: f64,
|
||||
b_m: f64,
|
||||
b_y: f64,
|
||||
b_k: f64,
|
||||
m_c: f64,
|
||||
m_m: f64,
|
||||
m_y: f64,
|
||||
m_k: f64,
|
||||
w_c: f64,
|
||||
w_m: f64,
|
||||
w_y: f64,
|
||||
w_k: f64,
|
||||
n_c: f64,
|
||||
n_m: f64,
|
||||
n_y: f64,
|
||||
n_k: f64,
|
||||
k_c: f64,
|
||||
k_m: f64,
|
||||
k_y: f64,
|
||||
k_k: f64,
|
||||
r_c: f32,
|
||||
r_m: f32,
|
||||
r_y: f32,
|
||||
r_k: f32,
|
||||
y_c: f32,
|
||||
y_m: f32,
|
||||
y_y: f32,
|
||||
y_k: f32,
|
||||
g_c: f32,
|
||||
g_m: f32,
|
||||
g_y: f32,
|
||||
g_k: f32,
|
||||
c_c: f32,
|
||||
c_m: f32,
|
||||
c_y: f32,
|
||||
c_k: f32,
|
||||
b_c: f32,
|
||||
b_m: f32,
|
||||
b_y: f32,
|
||||
b_k: f32,
|
||||
m_c: f32,
|
||||
m_m: f32,
|
||||
m_y: f32,
|
||||
m_k: f32,
|
||||
w_c: f32,
|
||||
w_m: f32,
|
||||
w_y: f32,
|
||||
w_k: f32,
|
||||
n_c: f32,
|
||||
n_m: f32,
|
||||
n_y: f32,
|
||||
n_k: f32,
|
||||
k_c: f32,
|
||||
k_m: f32,
|
||||
k_y: f32,
|
||||
k_k: f32,
|
||||
) -> Color {
|
||||
let color = color.to_gamma_srgb();
|
||||
|
||||
@@ -775,7 +775,7 @@ fn selective_color_node(
|
||||
// Skip this color parameter group...
|
||||
// ...if it's unchanged from the default of zero offset on all CMYK paramters, or...
|
||||
// ...if this pixel's color isn't in the range affected by this color parameter group
|
||||
if (c < f64::EPSILON && m < f64::EPSILON && y < f64::EPSILON && k < f64::EPSILON) || (!pixel_color_range(color_parameter_group)) {
|
||||
if (c < f32::EPSILON && m < f32::EPSILON && y < f32::EPSILON && k < f32::EPSILON) || (!pixel_color_range(color_parameter_group)) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
@@ -807,7 +807,7 @@ pub struct OpacityNode<O> {
|
||||
}
|
||||
|
||||
#[node_macro::node_fn(OpacityNode)]
|
||||
fn image_opacity(color: Color, opacity_multiplier: f64) -> Color {
|
||||
fn image_opacity(color: Color, opacity_multiplier: f32) -> Color {
|
||||
let opacity_multiplier = opacity_multiplier as f32 / 100.;
|
||||
Color::from_rgbaf32_unchecked(color.r(), color.g(), color.b(), color.a() * opacity_multiplier)
|
||||
}
|
||||
@@ -820,7 +820,7 @@ pub struct PosterizeNode<P> {
|
||||
// Based on http://www.axiomx.com/posterize.htm
|
||||
// This algorithm is perfectly accurate.
|
||||
#[node_macro::node_fn(PosterizeNode)]
|
||||
fn posterize(color: Color, posterize_value: f64) -> Color {
|
||||
fn posterize(color: Color, posterize_value: f32) -> Color {
|
||||
let color = color.to_gamma_srgb();
|
||||
|
||||
let posterize_value = posterize_value as f32;
|
||||
@@ -841,7 +841,7 @@ pub struct ExposureNode<Exposure, Offset, GammaCorrection> {
|
||||
|
||||
// Based on https://geraldbakker.nl/psnumbers/exposure.html
|
||||
#[node_macro::node_fn(ExposureNode)]
|
||||
fn exposure(color: Color, exposure: f64, offset: f64, gamma_correction: f64) -> Color {
|
||||
fn exposure(color: Color, exposure: f32, offset: f32, gamma_correction: f32) -> Color {
|
||||
let adjusted = color
|
||||
// Exposure
|
||||
.map_rgb(|c: f32| c * 2_f32.powf(exposure as f32))
|
||||
|
||||
@@ -15,7 +15,7 @@ pub struct TextGenerator<Text, FontName, Size> {
|
||||
}
|
||||
|
||||
#[node_fn(TextGenerator)]
|
||||
fn generate_text<'a: 'input, T>(editor: EditorApi<'a, T>, text: String, font_name: Font, font_size: f64) -> crate::vector::VectorData {
|
||||
fn generate_text<'a: 'input, T>(editor: EditorApi<'a, T>, text: String, font_name: Font, font_size: f32) -> crate::vector::VectorData {
|
||||
let buzz_face = editor.font_cache.get(&font_name).map(|data| load_face(data));
|
||||
crate::vector::VectorData::from_subpaths(to_path(&text, buzz_face, font_size, None))
|
||||
crate::vector::VectorData::from_subpaths(to_path(&text, buzz_face, font_size as f64, None))
|
||||
}
|
||||
|
||||
@@ -78,10 +78,10 @@ pub struct TransformNode<Translation, Rotation, Scale, Shear, Pivot> {
|
||||
}
|
||||
|
||||
#[node_macro::node_fn(TransformNode)]
|
||||
pub(crate) fn transform_vector_data<Data: TransformMut>(mut data: Data, translate: DVec2, rotate: f64, scale: DVec2, shear: DVec2, pivot: DVec2) -> Data {
|
||||
pub(crate) fn transform_vector_data<Data: TransformMut>(mut data: Data, translate: DVec2, rotate: f32, scale: DVec2, shear: DVec2, pivot: DVec2) -> Data {
|
||||
let pivot = DAffine2::from_translation(data.local_pivot(pivot));
|
||||
|
||||
let modification = pivot * DAffine2::from_scale_angle_translation(scale, rotate, translate) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.]) * pivot.inverse();
|
||||
let modification = pivot * DAffine2::from_scale_angle_translation(scale, rotate as f64, translate) * DAffine2::from_cols_array(&[1., shear.y, shear.x, 1., 0., 0.]) * pivot.inverse();
|
||||
let data_transform = data.transform_mut();
|
||||
*data_transform = modification * (*data_transform);
|
||||
|
||||
|
||||
@@ -53,21 +53,21 @@ pub struct SetStrokeNode<Color, Weight, DashLengths, DashOffset, LineCap, LineJo
|
||||
fn set_vector_data_stroke(
|
||||
mut vector_data: VectorData,
|
||||
color: Option<Color>,
|
||||
weight: f64,
|
||||
weight: f32,
|
||||
dash_lengths: Vec<f32>,
|
||||
dash_offset: f64,
|
||||
dash_offset: f32,
|
||||
line_cap: super::style::LineCap,
|
||||
line_join: super::style::LineJoin,
|
||||
miter_limit: f64,
|
||||
miter_limit: f32,
|
||||
) -> VectorData {
|
||||
vector_data.style.set_stroke(Stroke {
|
||||
color,
|
||||
weight,
|
||||
weight: weight as f64,
|
||||
dash_lengths,
|
||||
dash_offset,
|
||||
dash_offset: dash_offset as f64,
|
||||
line_cap,
|
||||
line_join,
|
||||
line_join_miter_limit: miter_limit,
|
||||
line_join_miter_limit: miter_limit as f64,
|
||||
});
|
||||
vector_data
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ impl SpirVCompiler for GpuCompiler {
|
||||
|
||||
pub fn serialize_gpu(networks: &[ProtoNetwork], io: &ShaderIO) -> anyhow::Result<String> {
|
||||
fn nid(id: &u64) -> String {
|
||||
format!("n{id}")
|
||||
format!("n{id:0x}")
|
||||
}
|
||||
|
||||
dbg!(&io);
|
||||
@@ -216,9 +216,10 @@ pub fn compile(dir: &Path) -> Result<spirv_builder::CompileResult, spirv_builder
|
||||
.release(true)
|
||||
.spirv_metadata(SpirvMetadata::Full)
|
||||
.capability(spirv_builder::Capability::Float64)
|
||||
.extra_arg("no-early-report-zombies")
|
||||
.extra_arg("no-infer-storage-classes")
|
||||
.extra_arg("spirt-passes=qptr")
|
||||
//.extra_arg("no-early-report-zombies")
|
||||
//.extra_arg("no-infer-storage-classes")
|
||||
//.extra_arg("spirt-passes=qptr,reduce")
|
||||
.extra_arg("spirt-passes=reduce")
|
||||
.build()?;
|
||||
|
||||
Ok(result)
|
||||
|
||||
@@ -654,10 +654,13 @@ impl NodeNetwork {
|
||||
|
||||
/// Recursively dissolve non-primitive document nodes and return a single flattened network of nodes.
|
||||
pub fn flatten_with_fns(&mut self, node: NodeId, map_ids: impl Fn(NodeId, NodeId) -> NodeId + Copy, gen_id: impl Fn() -> NodeId + Copy) {
|
||||
let (id, mut node) = self
|
||||
self.resolve_extract_nodes();
|
||||
let Some((id, mut node)) = self
|
||||
.nodes
|
||||
.remove_entry(&node)
|
||||
.unwrap_or_else(|| panic!("The node which was supposed to be flattened does not exist in the network, id {} network {:#?}", node, self));
|
||||
.remove_entry(&node) else {
|
||||
warn!("The node which was supposed to be flattened does not exist in the network, id {} network {:#?}", node, self);
|
||||
return;
|
||||
};
|
||||
|
||||
if self.disabled.contains(&id) {
|
||||
node.implementation = DocumentNodeImplementation::Unresolved("graphene_core::ops::IdNode".into());
|
||||
@@ -665,7 +668,7 @@ impl NodeNetwork {
|
||||
self.nodes.insert(id, node);
|
||||
return;
|
||||
}
|
||||
log::debug!("Flattening node {:?}", &node);
|
||||
log::debug!("Flattening node {:?}", &node.name);
|
||||
|
||||
// replace value inputs with value nodes
|
||||
for input in &mut node.inputs {
|
||||
@@ -846,7 +849,10 @@ impl NodeNetwork {
|
||||
let mut input_node = self.nodes.remove(&node_id).unwrap();
|
||||
node.implementation = DocumentNodeImplementation::Unresolved("graphene_core::value::ClonedNode".into());
|
||||
if let Some(input) = input_node.inputs.get_mut(0) {
|
||||
*input = NodeInput::Network(input.ty());
|
||||
*input = match &input {
|
||||
NodeInput::Node { .. } => NodeInput::Network(generic!(T)),
|
||||
ni => NodeInput::Network(ni.ty()),
|
||||
};
|
||||
}
|
||||
|
||||
for input in input_node.inputs.iter_mut() {
|
||||
|
||||
@@ -9,9 +9,8 @@ pub struct Compiler {}
|
||||
|
||||
impl Compiler {
|
||||
pub fn compile(&self, mut network: NodeNetwork, resolve_inputs: bool) -> impl Iterator<Item = ProtoNetwork> {
|
||||
let node_ids = network.nodes.keys().copied().collect::<Vec<_>>();
|
||||
println!("flattening");
|
||||
network.resolve_extract_nodes();
|
||||
let node_ids = network.nodes.keys().copied().collect::<Vec<_>>();
|
||||
for id in node_ids {
|
||||
network.flatten(id);
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ impl Hash for ConstructionArgs {
|
||||
impl ConstructionArgs {
|
||||
pub fn new_function_args(&self) -> Vec<String> {
|
||||
match self {
|
||||
ConstructionArgs::Nodes(nodes) => nodes.iter().map(|n| format!("&n{}", n.0)).collect(),
|
||||
ConstructionArgs::Nodes(nodes) => nodes.iter().map(|n| format!("n{:0x}", n.0)).collect(),
|
||||
ConstructionArgs::Value(value) => vec![value.to_primitive_string()],
|
||||
ConstructionArgs::Inline(inline) => vec![inline.expr.clone()],
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ default = ["wgpu"]
|
||||
wgpu = ["wgpu-executor", "gpu", "graphene-std/wgpu"]
|
||||
wayland = ["graphene-std/wayland"]
|
||||
profiling = ["wgpu-executor/profiling"]
|
||||
passthrough = ["wgpu-executor/passthrough"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -601,7 +601,7 @@
|
||||
{
|
||||
"Value": {
|
||||
"tagged_value": {
|
||||
"F64": 0.0
|
||||
"F32": 0.0
|
||||
},
|
||||
"exposed": false
|
||||
}
|
||||
|
||||
@@ -191,10 +191,10 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: &u32, params: [u32]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: u32, params: [&u32]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: &u32, params: [&u32]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: f64, params: [f64]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f64, params: [f64]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: f64, params: [&f64]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f64, params: [&f64]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: f32, params: [f32]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f32, params: [f32]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: f32, params: [&f32]),
|
||||
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f32, params: [&f32]),
|
||||
register_node!(graphene_core::ops::SomeNode, input: WasmEditorApi, params: []),
|
||||
async_node!(graphene_core::ops::IntoNode<_, ImageFrame<SRGBA8>>, input: ImageFrame<Color>, output: ImageFrame<SRGBA8>, params: []),
|
||||
async_node!(graphene_core::ops::IntoNode<_, ImageFrame<Color>>, input: ImageFrame<SRGBA8>, output: ImageFrame<Color>, params: []),
|
||||
@@ -355,7 +355,7 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
raster_node!(graphene_core::raster::ExtractChannelNode<_>, params: [RedGreenBlue]),
|
||||
raster_node!(graphene_core::raster::ExtractAlphaNode<>, params: []),
|
||||
raster_node!(graphene_core::raster::ExtractOpaqueNode<>, params: []),
|
||||
raster_node!(graphene_core::raster::LevelsNode<_, _, _, _, _>, params: [f64, f64, f64, f64, f64]),
|
||||
raster_node!(graphene_core::raster::LevelsNode<_, _, _, _, _>, params: [f32, f32, f32, f32, f32]),
|
||||
register_node!(graphene_std::image_segmentation::ImageSegmentationNode<_>, input: ImageFrame<Color>, params: [ImageFrame<Color>]),
|
||||
register_node!(graphene_core::raster::IndexNode<_>, input: Vec<ImageFrame<Color>>, params: [u32]),
|
||||
vec![(
|
||||
@@ -364,7 +364,7 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
Box::pin(async move {
|
||||
let image: DowncastBothNode<(), ImageFrame<Color>> = DowncastBothNode::new(args[0].clone());
|
||||
let blend_mode: DowncastBothNode<(), BlendMode> = DowncastBothNode::new(args[1].clone());
|
||||
let opacity: DowncastBothNode<(), f64> = DowncastBothNode::new(args[2].clone());
|
||||
let opacity: DowncastBothNode<(), f32> = DowncastBothNode::new(args[2].clone());
|
||||
let blend_node = graphene_core::raster::BlendNode::new(CopiedNode::new(blend_mode.eval(()).await), CopiedNode::new(opacity.eval(()).await));
|
||||
let node = graphene_std::raster::BlendImageNode::new(image, blend_node);
|
||||
let any: DynAnyNode<ImageFrame<Color>, _, _> = graphene_std::any::DynAnyNode::new(node);
|
||||
@@ -374,21 +374,21 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
NodeIOTypes::new(
|
||||
concrete!(ImageFrame<Color>),
|
||||
concrete!(ImageFrame<Color>),
|
||||
vec![fn_type!(ImageFrame<Color>), fn_type!(BlendMode), fn_type!(f64)],
|
||||
vec![fn_type!(ImageFrame<Color>), fn_type!(BlendMode), fn_type!(f32)],
|
||||
),
|
||||
)],
|
||||
raster_node!(graphene_core::raster::GrayscaleNode<_, _, _, _, _, _, _>, params: [Color, f64, f64, f64, f64, f64, f64]),
|
||||
raster_node!(graphene_core::raster::HueSaturationNode<_, _, _>, params: [f64, f64, f64]),
|
||||
raster_node!(graphene_core::raster::GrayscaleNode<_, _, _, _, _, _, _>, params: [Color, f32, f32, f32, f32, f32, f32]),
|
||||
raster_node!(graphene_core::raster::HueSaturationNode<_, _, _>, params: [f32, f32, f32]),
|
||||
raster_node!(graphene_core::raster::InvertRGBNode, params: []),
|
||||
raster_node!(graphene_core::raster::ThresholdNode<_, _, _>, params: [f64, f64, LuminanceCalculation]),
|
||||
raster_node!(graphene_core::raster::VibranceNode<_>, params: [f64]),
|
||||
raster_node!(graphene_core::raster::ThresholdNode<_, _, _>, params: [f32, f32, LuminanceCalculation]),
|
||||
raster_node!(graphene_core::raster::VibranceNode<_>, params: [f32]),
|
||||
raster_node!(
|
||||
graphene_core::raster::ChannelMixerNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>,
|
||||
params: [bool, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64]
|
||||
params: [bool, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32]
|
||||
),
|
||||
raster_node!(
|
||||
graphene_core::raster::SelectiveColorNode<_, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _>,
|
||||
params: [RelativeAbsolute, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64, f64]
|
||||
params: [RelativeAbsolute, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32]
|
||||
),
|
||||
vec![(
|
||||
NodeIdentifier::new("graphene_core::raster::BrightnessContrastNode<_, _, _>"),
|
||||
@@ -396,9 +396,9 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
Box::pin(async move {
|
||||
use graphene_core::raster::brightness_contrast::*;
|
||||
|
||||
let brightness: DowncastBothNode<(), f64> = DowncastBothNode::new(args[0].clone());
|
||||
let brightness: DowncastBothNode<(), f32> = DowncastBothNode::new(args[0].clone());
|
||||
let brightness = ClonedNode::new(brightness.eval(()).await as f32);
|
||||
let contrast: DowncastBothNode<(), f64> = DowncastBothNode::new(args[1].clone());
|
||||
let contrast: DowncastBothNode<(), f32> = DowncastBothNode::new(args[1].clone());
|
||||
let contrast = ClonedNode::new(contrast.eval(()).await as f32);
|
||||
let use_legacy: DowncastBothNode<(), bool> = DowncastBothNode::new(args[2].clone());
|
||||
|
||||
@@ -417,11 +417,11 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
}
|
||||
})
|
||||
},
|
||||
NodeIOTypes::new(concrete!(ImageFrame<Color>), concrete!(ImageFrame<Color>), vec![fn_type!(f64), fn_type!(f64), fn_type!(bool)]),
|
||||
NodeIOTypes::new(concrete!(ImageFrame<Color>), concrete!(ImageFrame<Color>), vec![fn_type!(f32), fn_type!(f32), fn_type!(bool)]),
|
||||
)],
|
||||
raster_node!(graphene_core::raster::OpacityNode<_>, params: [f64]),
|
||||
raster_node!(graphene_core::raster::PosterizeNode<_>, params: [f64]),
|
||||
raster_node!(graphene_core::raster::ExposureNode<_, _, _>, params: [f64, f64, f64]),
|
||||
raster_node!(graphene_core::raster::OpacityNode<_>, params: [f32]),
|
||||
raster_node!(graphene_core::raster::PosterizeNode<_>, params: [f32]),
|
||||
raster_node!(graphene_core::raster::ExposureNode<_, _, _>, params: [f32, f32, f32]),
|
||||
register_node!(graphene_core::memo::LetNode<_>, input: Option<ImageFrame<Color>>, params: []),
|
||||
register_node!(graphene_core::memo::LetNode<_>, input: Option<WasmEditorApi>, params: []),
|
||||
async_node!(graphene_core::memo::EndLetNode<_>, input: WasmEditorApi, output: ImageFrame<Color>, params: [ImageFrame<Color>]),
|
||||
@@ -479,18 +479,18 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
vec![
|
||||
fn_type!(WasmEditorApi),
|
||||
fn_type!(ImaginateController),
|
||||
fn_type!(f64),
|
||||
fn_type!(f32),
|
||||
fn_type!(Option<DVec2>),
|
||||
fn_type!(u32),
|
||||
fn_type!(ImaginateSamplingMethod),
|
||||
fn_type!(f64),
|
||||
fn_type!(f32),
|
||||
fn_type!(String),
|
||||
fn_type!(String),
|
||||
fn_type!(bool),
|
||||
fn_type!(f64),
|
||||
fn_type!(f32),
|
||||
fn_type!(Option<Vec<u64>>),
|
||||
fn_type!(bool),
|
||||
fn_type!(f64),
|
||||
fn_type!(f32),
|
||||
fn_type!(ImaginateMaskStartingFill),
|
||||
fn_type!(bool),
|
||||
fn_type!(bool),
|
||||
@@ -516,22 +516,22 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
||||
raster_node!(graphene_core::quantization::QuantizeNode<_>, params: [QuantizationChannels]),
|
||||
raster_node!(graphene_core::quantization::DeQuantizeNode<_>, params: [QuantizationChannels]),
|
||||
register_node!(graphene_core::ops::CloneNode<_>, input: &QuantizationChannels, params: []),
|
||||
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: VectorData, params: [DVec2, f64, DVec2, DVec2, DVec2]),
|
||||
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: ImageFrame<Color>, params: [DVec2, f64, DVec2, DVec2, DVec2]),
|
||||
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: WasmSurfaceHandleFrame, params: [DVec2, f64, DVec2, DVec2, DVec2]),
|
||||
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: VectorData, params: [DVec2, f32, DVec2, DVec2, DVec2]),
|
||||
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: ImageFrame<Color>, params: [DVec2, f32, DVec2, DVec2, DVec2]),
|
||||
register_node!(graphene_core::transform::TransformNode<_, _, _, _, _>, input: WasmSurfaceHandleFrame, params: [DVec2, f32, DVec2, DVec2, DVec2]),
|
||||
register_node!(graphene_core::transform::SetTransformNode<_>, input: VectorData, params: [VectorData]),
|
||||
register_node!(graphene_core::transform::SetTransformNode<_>, input: ImageFrame<Color>, params: [ImageFrame<Color>]),
|
||||
register_node!(graphene_core::transform::SetTransformNode<_>, input: VectorData, params: [DAffine2]),
|
||||
register_node!(graphene_core::transform::SetTransformNode<_>, input: ImageFrame<Color>, params: [DAffine2]),
|
||||
register_node!(graphene_core::vector::SetFillNode<_, _, _, _, _, _, _>, input: VectorData, params: [graphene_core::vector::style::FillType, Option<graphene_core::Color>, graphene_core::vector::style::GradientType, DVec2, DVec2, DAffine2, Vec<(f64, Option<graphene_core::Color>)>]),
|
||||
register_node!(graphene_core::vector::SetStrokeNode<_, _, _, _, _, _, _>, input: VectorData, params: [Option<graphene_core::Color>, f64, Vec<f32>, f64, graphene_core::vector::style::LineCap, graphene_core::vector::style::LineJoin, f64]),
|
||||
register_node!(graphene_core::vector::SetStrokeNode<_, _, _, _, _, _, _>, input: VectorData, params: [Option<graphene_core::Color>, f32, Vec<f32>, f32, graphene_core::vector::style::LineCap, graphene_core::vector::style::LineJoin, f32]),
|
||||
register_node!(graphene_core::vector::generator_nodes::UnitCircleGenerator, input: (), params: []),
|
||||
register_node!(
|
||||
graphene_core::vector::generator_nodes::PathGenerator<_>,
|
||||
input: Vec<graphene_core::vector::bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>,
|
||||
params: [Vec<graphene_core::uuid::ManipulatorGroupId>]
|
||||
),
|
||||
register_node!(graphene_core::text::TextGenerator<_, _, _>, input: WasmEditorApi, params: [String, graphene_core::text::Font, f64]),
|
||||
register_node!(graphene_core::text::TextGenerator<_, _, _>, input: WasmEditorApi, params: [String, graphene_core::text::Font, f32]),
|
||||
register_node!(graphene_std::brush::VectorPointsNode, input: VectorData, params: []),
|
||||
register_node!(graphene_core::ExtractImageFrame, input: WasmEditorApi, params: []),
|
||||
register_node!(graphene_core::ConstructLayerNode<_, _, _, _, _, _, _>, input: graphene_core::vector::VectorData, params: [String, BlendMode, f32, bool, bool, bool, graphene_core::GraphicGroup]),
|
||||
|
||||
@@ -7,6 +7,7 @@ license = "MIT OR Apache-2.0"
|
||||
[features]
|
||||
default = []
|
||||
profiling = ["nvtx"]
|
||||
passthrough = []
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
||||
@@ -19,17 +19,16 @@ impl Context {
|
||||
// `request_adapter` instantiates the general connection to the GPU
|
||||
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions::default()).await?;
|
||||
|
||||
//let limits = adapter.limits();
|
||||
|
||||
//log::trace!("Adapter limits: {:?}", limits);
|
||||
|
||||
// `request_device` instantiates the feature specific connection to the GPU, defining some parameters,
|
||||
// `features` being the available features.
|
||||
let (device, queue) = adapter
|
||||
.request_device(
|
||||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
#[cfg(not(feature = "passthrough"))]
|
||||
features: wgpu::Features::empty(),
|
||||
#[cfg(feature = "passthrough")]
|
||||
features: wgpu::Features::SPIRV_SHADER_PASSTHROUGH,
|
||||
limits: Default::default(),
|
||||
},
|
||||
None,
|
||||
|
||||
@@ -118,10 +118,18 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
||||
type Window = Arc<winit::window::Window>;
|
||||
|
||||
fn load_shader(&self, shader: Shader) -> Result<Self::ShaderHandle> {
|
||||
#[cfg(not(feature = "passthrough"))]
|
||||
let shader_module = self.context.device.create_shader_module(wgpu::ShaderModuleDescriptor {
|
||||
label: Some(shader.name),
|
||||
source: wgpu::ShaderSource::SpirV(shader.source),
|
||||
});
|
||||
#[cfg(feature = "passthrough")]
|
||||
let shader_module = unsafe {
|
||||
self.context.device.create_shader_module_spirv(&wgpu::ShaderModuleDescriptorSpirV {
|
||||
label: Some(shader.name),
|
||||
source: shader.source,
|
||||
})
|
||||
};
|
||||
Ok(ShaderModuleWrapper(shader_module))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user