mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-08-04 05:18:19 +00:00
Lay groundwork for directly rendering to the canvas without a cpu roundrip (#1291)
* Add Texture handle type * Add Texture View to shader inputs * Implement basic rendering pipeline * Render first texture using render pipeline * Fix output color space * Precompute the rendering pipeline * Move gpu context creation to editor api * Port gpu-executor nodes to node registry * Fix canvas nodes and make code compile for non wasm targets * Pin wasm-bindgen version * Disable miri temoporarily for better ci times * Fix formatting * Remove unsafe block * Bump wasm-pack version * Bump wasm-bindgen version * Add gpu feature guard for push node * Make Into node async
This commit is contained in:
parent
0c93a62d55
commit
45b04f4eb9
33 changed files with 1574 additions and 339 deletions
|
@ -16,6 +16,8 @@ quantization = ["graphene-std/quantization"]
|
|||
graphene-core = { path = "../gcore", features = ["async", "std"] }
|
||||
graphene-std = { path = "../gstd" }
|
||||
graph-craft = { path = "../graph-craft" }
|
||||
gpu-executor = { path = "../gpu-executor" }
|
||||
wgpu-executor = { path = "../wgpu-executor" }
|
||||
dyn-any = { path = "../../libraries/dyn-any", features = [
|
||||
"log-bad-types",
|
||||
"glam",
|
||||
|
|
|
@ -8,15 +8,19 @@ use graphene_core::structural::Then;
|
|||
use graphene_core::value::{ClonedNode, CopiedNode, ValueNode};
|
||||
use graphene_core::vector::brush_stroke::BrushStroke;
|
||||
use graphene_core::vector::VectorData;
|
||||
use graphene_core::wasm_application_io::WasmSurfaceHandle;
|
||||
use graphene_core::wasm_application_io::*;
|
||||
use graphene_core::{application_io::SurfaceHandle, SurfaceFrame, WasmSurfaceHandleFrame};
|
||||
use graphene_core::{concrete, generic};
|
||||
use graphene_core::{fn_type, raster::*};
|
||||
use graphene_core::{Cow, NodeIdentifier, Type, TypeDescriptor};
|
||||
use graphene_core::{Node, NodeIO, NodeIOTypes};
|
||||
use graphene_std::any::{ComposeTypeErased, DowncastBothNode, DynAnyNode, FutureWrapperNode, IntoTypeErasedNode};
|
||||
use graphene_std::wasm_application_io::*;
|
||||
|
||||
#[cfg(feature = "gpu")]
|
||||
use gpu_executor::{GpuExecutor, ShaderInput, ShaderInputFrame};
|
||||
use graphene_std::raster::*;
|
||||
use graphene_std::wasm_application_io::WasmEditorApi;
|
||||
use wgpu_executor::WgpuExecutor;
|
||||
|
||||
use dyn_any::StaticType;
|
||||
use glam::{DAffine2, DVec2};
|
||||
|
@ -79,7 +83,7 @@ macro_rules! async_node {
|
|||
args.reverse();
|
||||
let node = <$path>::new($(graphene_std::any::input_node::<$type>(args.pop().expect("Not enough arguments provided to construct node"))),*);
|
||||
let any: DynAnyNode<$input, _, _> = graphene_std::any::DynAnyNode::new(graphene_core::value::ValueNode::new(node));
|
||||
any.into_type_erased()
|
||||
Box::new(any) as TypeErasedBox
|
||||
})
|
||||
},
|
||||
{
|
||||
|
@ -181,7 +185,7 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||
register_node!(graphene_core::ops::AddNode, input: (u32, u32), params: []),
|
||||
register_node!(graphene_core::ops::AddNode, input: (u32, &u32), params: []),
|
||||
register_node!(graphene_core::ops::CloneNode<_>, input: &ImageFrame<Color>, params: []),
|
||||
register_node!(graphene_core::ops::CloneNode<_>, input: &graphene_core::EditorApi, params: []),
|
||||
register_node!(graphene_core::ops::CloneNode<_>, input: &WasmEditorApi, params: []),
|
||||
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]),
|
||||
|
@ -190,9 +194,11 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||
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::SomeNode, input: graphene_core::EditorApi, params: []),
|
||||
register_node!(graphene_core::ops::IntoNode<_, ImageFrame<SRGBA8>>, input: ImageFrame<Color>, params: []),
|
||||
register_node!(graphene_core::ops::IntoNode<_, ImageFrame<Color>>, input: ImageFrame<SRGBA8>, params: []),
|
||||
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: []),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(graphene_core::ops::IntoNode<_, &WgpuExecutor>, input: WasmEditorApi, output: &WgpuExecutor, params: []),
|
||||
register_node!(graphene_std::raster::DownresNode<_>, input: ImageFrame<Color>, params: []),
|
||||
register_node!(graphene_std::raster::MaskImageNode<_, _, _>, input: ImageFrame<Color>, params: [ImageFrame<Color>]),
|
||||
register_node!(graphene_std::raster::MaskImageNode<_, _, _>, input: ImageFrame<Color>, params: [ImageFrame<Luma>]),
|
||||
|
@ -244,26 +250,68 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||
register_node!(graphene_std::raster::EmptyImageNode<_, _>, input: DAffine2, params: [Color]),
|
||||
register_node!(graphene_core::memo::MonitorNode<_>, input: ImageFrame<Color>, params: []),
|
||||
register_node!(graphene_core::memo::MonitorNode<_>, input: graphene_core::GraphicGroup, params: []),
|
||||
register_node!(graphene_core::wasm_application_io::CreateSurfaceNode, input: graphene_core::EditorApi, params: []),
|
||||
async_node!(graphene_std::wasm_application_io::CreateSurfaceNode, input: WasmEditorApi, output: Arc<SurfaceHandle<<graphene_std::wasm_application_io::WasmApplicationIo as graphene_core::application_io::ApplicationIo>::Surface>>, params: []),
|
||||
async_node!(
|
||||
graphene_core::wasm_application_io::DrawImageFrameNode<_>,
|
||||
graphene_std::wasm_application_io::DrawImageFrameNode<_>,
|
||||
input: ImageFrame<SRGBA8>,
|
||||
output: WasmSurfaceHandleFrame,
|
||||
params: [Arc<WasmSurfaceHandle>]
|
||||
),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(gpu_executor::UniformNode<_>, input: f32, output: ShaderInput<WgpuExecutor>, params: [&WgpuExecutor]),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(gpu_executor::StorageNode<_>, input: Vec<u8>, output: ShaderInput<WgpuExecutor>, params: [&WgpuExecutor]),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(
|
||||
gpu_executor::PushNode<_>,
|
||||
input: Vec<ShaderInput<WgpuExecutor>>,
|
||||
output: Vec<ShaderInput<WgpuExecutor>>,
|
||||
params: [ShaderInput<WgpuExecutor>]
|
||||
),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(gpu_executor::CreateOutputBufferNode<_, _>, input: usize, output: gpu_executor::ShaderInput<WgpuExecutor>, params: [&WgpuExecutor, Type]),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(gpu_executor::CreateComputePassNode<_, _, _>, input: gpu_executor::PipelineLayout<WgpuExecutor>, output: <WgpuExecutor as GpuExecutor>::CommandBuffer, params: [&WgpuExecutor, ShaderInput<WgpuExecutor>, gpu_executor::ComputePassDimensions]),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(gpu_executor::CreatePipelineLayoutNode<_, _, _, _>, input: <WgpuExecutor as GpuExecutor>::ShaderHandle, output: gpu_executor::PipelineLayout<WgpuExecutor>, params: [String, gpu_executor::Bindgroup<WgpuExecutor>, Arc<ShaderInput<WgpuExecutor>>]),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(
|
||||
gpu_executor::ExecuteComputePipelineNode<_>,
|
||||
input: <WgpuExecutor as GpuExecutor>::CommandBuffer,
|
||||
output: (),
|
||||
params: [&WgpuExecutor]
|
||||
),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(gpu_executor::ReadOutputBufferNode<_, _>, input: Arc<ShaderInput<WgpuExecutor>>, output: Vec<u8>, params: [&WgpuExecutor, ()]),
|
||||
#[cfg(all(feature = "gpu", target_arch = "wasm32"))]
|
||||
async_node!(gpu_executor::CreateGpuSurfaceNode, input: WasmEditorApi, output: Arc<SurfaceHandle<<WgpuExecutor as GpuExecutor>::Surface>>, params: []),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(gpu_executor::RenderTextureNode<_, _>, input: ShaderInputFrame<WgpuExecutor>, output: SurfaceFrame, params: [Arc<SurfaceHandle<<WgpuExecutor as GpuExecutor>::Surface>>, &WgpuExecutor]),
|
||||
#[cfg(feature = "gpu")]
|
||||
async_node!(
|
||||
gpu_executor::UploadTextureNode<_>,
|
||||
input: ImageFrame<Color>,
|
||||
output: ShaderInputFrame<WgpuExecutor>,
|
||||
params: [&WgpuExecutor]
|
||||
),
|
||||
#[cfg(feature = "gpu")]
|
||||
vec![(
|
||||
NodeIdentifier::new("graphene_std::executor::MapGpuSingleImageNode<_>"),
|
||||
|args| {
|
||||
Box::pin(async move {
|
||||
let document_node: DowncastBothNode<(), graph_craft::document::DocumentNode> = DowncastBothNode::new(args[0].clone());
|
||||
let editor_api: DowncastBothNode<(), WasmEditorApi> = DowncastBothNode::new(args[1].clone());
|
||||
//let document_node = ClonedNode::new(document_node.eval(()));
|
||||
let node = graphene_std::executor::MapGpuNode::new(document_node);
|
||||
let node = graphene_std::gpu_nodes::MapGpuNode::new(document_node, editor_api);
|
||||
let any: DynAnyNode<ImageFrame<Color>, _, _> = graphene_std::any::DynAnyNode::new(graphene_core::value::ValueNode::new(node));
|
||||
any.into_type_erased()
|
||||
})
|
||||
},
|
||||
NodeIOTypes::new(concrete!(ImageFrame<Color>), concrete!(ImageFrame<Color>), vec![fn_type!(graph_craft::document::DocumentNode)]),
|
||||
NodeIOTypes::new(
|
||||
concrete!(ImageFrame<Color>),
|
||||
concrete!(SurfaceFrame),
|
||||
vec![fn_type!(graph_craft::document::DocumentNode), fn_type!(WasmEditorApi)],
|
||||
),
|
||||
)],
|
||||
#[cfg(feature = "gpu")]
|
||||
vec![(
|
||||
|
@ -273,7 +321,7 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||
let background: DowncastBothNode<(), ImageFrame<Color>> = DowncastBothNode::new(args[0].clone());
|
||||
let blend_mode: DowncastBothNode<(), BlendMode> = DowncastBothNode::new(args[1].clone());
|
||||
let opacity: DowncastBothNode<(), f32> = DowncastBothNode::new(args[2].clone());
|
||||
let node = graphene_std::executor::BlendGpuImageNode::new(background, blend_mode, opacity);
|
||||
let node = graphene_std::gpu_nodes::BlendGpuImageNode::new(background, blend_mode, opacity);
|
||||
let any: DynAnyNode<ImageFrame<Color>, _, _> = graphene_std::any::DynAnyNode::new(graphene_core::value::ValueNode::new(node));
|
||||
|
||||
any.into_type_erased()
|
||||
|
@ -374,47 +422,39 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||
raster_node!(graphene_core::raster::PosterizeNode<_>, params: [f64]),
|
||||
raster_node!(graphene_core::raster::ExposureNode<_, _, _>, params: [f64, f64, f64]),
|
||||
register_node!(graphene_core::memo::LetNode<_>, input: Option<ImageFrame<Color>>, params: []),
|
||||
register_node!(graphene_core::memo::LetNode<_>, input: Option<graphene_core::EditorApi>, 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>]),
|
||||
async_node!(graphene_core::memo::EndLetNode<_>, input: WasmEditorApi, output: VectorData, params: [VectorData]),
|
||||
async_node!(
|
||||
graphene_core::memo::EndLetNode<_>,
|
||||
input: graphene_core::EditorApi,
|
||||
output: ImageFrame<Color>,
|
||||
params: [ImageFrame<Color>]
|
||||
),
|
||||
async_node!(graphene_core::memo::EndLetNode<_>, input: graphene_core::EditorApi, output: VectorData, params: [VectorData]),
|
||||
async_node!(
|
||||
graphene_core::memo::EndLetNode<_>,
|
||||
input: graphene_core::EditorApi,
|
||||
input: WasmEditorApi,
|
||||
output: graphene_core::GraphicGroup,
|
||||
params: [graphene_core::GraphicGroup]
|
||||
),
|
||||
async_node!(
|
||||
graphene_core::memo::EndLetNode<_>,
|
||||
input: graphene_core::EditorApi,
|
||||
input: WasmEditorApi,
|
||||
output: graphene_core::Artboard,
|
||||
params: [graphene_core::Artboard]
|
||||
),
|
||||
async_node!(
|
||||
graphene_core::memo::EndLetNode<_>,
|
||||
input: graphene_core::EditorApi,
|
||||
input: WasmEditorApi,
|
||||
output: WasmSurfaceHandleFrame,
|
||||
params: [WasmSurfaceHandleFrame]
|
||||
),
|
||||
async_node!(graphene_core::memo::EndLetNode<_>, input: WasmEditorApi, output: SurfaceFrame, params: [SurfaceFrame]),
|
||||
vec![(
|
||||
NodeIdentifier::new("graphene_core::memo::RefNode<_, _>"),
|
||||
|args| {
|
||||
Box::pin(async move {
|
||||
let node: DowncastBothNode<Option<graphene_core::EditorApi>, graphene_core::EditorApi> = graphene_std::any::DowncastBothNode::new(args[0].clone());
|
||||
let node: DowncastBothNode<Option<WasmEditorApi>, WasmEditorApi> = graphene_std::any::DowncastBothNode::new(args[0].clone());
|
||||
let node = <graphene_core::memo::RefNode<_, _>>::new(node);
|
||||
let any: DynAnyNode<(), _, _> = graphene_std::any::DynAnyNode::new(graphene_core::value::ValueNode::new(node));
|
||||
any.into_type_erased()
|
||||
})
|
||||
},
|
||||
NodeIOTypes::new(
|
||||
concrete!(()),
|
||||
concrete!(graphene_core::EditorApi),
|
||||
vec![fn_type!(Option<graphene_core::EditorApi>, graphene_core::EditorApi)],
|
||||
),
|
||||
NodeIOTypes::new(concrete!(()), concrete!(WasmEditorApi), vec![fn_type!(Option<WasmEditorApi>, WasmEditorApi)]),
|
||||
)],
|
||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: Image<Color>, params: [Image<Color>]),
|
||||
async_node!(graphene_core::memo::MemoNode<_, _>, input: (), output: ImageFrame<Color>, params: [ImageFrame<Color>]),
|
||||
|
@ -443,9 +483,9 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
|
|||
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: graphene_core::EditorApi, params: [String, graphene_core::text::Font, f64]),
|
||||
register_node!(graphene_core::text::TextGenerator<_, _, _>, input: WasmEditorApi, params: [String, graphene_core::text::Font, f64]),
|
||||
register_node!(graphene_std::brush::VectorPointsNode, input: VectorData, params: []),
|
||||
register_node!(graphene_core::ExtractImageFrame, input: graphene_core::EditorApi, 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]),
|
||||
register_node!(graphene_core::ConstructLayerNode<_, _, _, _, _, _, _>, input: ImageFrame<Color>, params: [String, BlendMode, f32, bool, bool, bool, graphene_core::GraphicGroup]),
|
||||
register_node!(graphene_core::ConstructLayerNode<_, _, _, _, _, _, _>, input: graphene_core::GraphicGroup, params: [String, BlendMode, f32, bool, bool, bool, graphene_core::GraphicGroup]),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue