Incremental compilation and stable node IDs (#977)

* Generate stable node ids

* checkpoint

* Implement borrow tree

* Add eval function on borrow tree

* Refactor Node trait to fix lifetime issues

* Compiler infinite loop

* Impl compose pair

* Transition to double lifetime on trait

* Change node trait to use a generic arg for the input

* Start adapting node_macro

* Migrate more nodes to new macro

* Fix raster tests

* Port vector nodes

* Make Node trait object safe

* Fix FlatMapResultNode

* Translate most of gstd

* Fix DowncastBothNode

* Refactor node trait once again to allow for HRTB for type erased nodes

* Start working on type erased nodes

* Try getting DowncastBothNode to work

* Introduce Upcasting node + work on BorrowTree

* Make enough 'static to get the code to compile

* Transition DynamicExecutor to use borrow tree

* Make Compose Node use HRTB's

* Fix MapResultNode

* Disable blur test

* Add workaround for Composing type erased nodes

* Convert more nodes in the node_registry

* Convert more of the node_registry

* Add update tree fn and hook up to frontend

* Fix blur node

* Implement CacheNode

* Make frontend use graph compiler

* Fix document_node_types type declaration for most nodes

* Remove unused imports

* Move comment down

* Reuse nodes via borrow tree

* Deprecate trait based value in favor of TaggedValue

* Remove unsafe code in buffer creation

* Fix blur node

* Fix stable node id generation

* Fix types for Image adjustment document nodes

* Fix Imaginate Node

* Remove unused imports

* Remove log

* Fix off by one error

* Remove macro generated imaginate node entry

* Create parameterized add node

* Fix test case

* Remove link from layer_panel.rs

* Fix formatting
This commit is contained in:
Dennis Kobert
2023-02-07 20:06:24 +01:00
committed by Keavon Chambers
parent 77e69f4e5b
commit 620540d7cd
36 changed files with 1548 additions and 1869 deletions
@@ -284,7 +284,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
}
ClearLayerTree => {
// Send an empty layer tree
let data_buffer: RawBuffer = Self::default().serialize_root().into();
let data_buffer: RawBuffer = Self::default().serialize_root().as_slice().into();
responses.push_back(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer }.into());
// Clear the options bar
@@ -360,7 +360,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
DocumentHistoryBackward => self.undo(responses).unwrap_or_else(|e| warn!("{}", e)),
DocumentHistoryForward => self.redo(responses).unwrap_or_else(|e| warn!("{}", e)),
DocumentStructureChanged => {
let data_buffer: RawBuffer = self.serialize_root().into();
let data_buffer: RawBuffer = self.serialize_root().as_slice().into();
responses.push_back(FrontendMessage::UpdateDocumentLayerTreeStructure { data_buffer }.into())
}
DuplicateSelectedLayers => {
@@ -1,11 +1,11 @@
use super::{node_properties, FrontendGraphDataType, FrontendNodeType};
use crate::messages::layout::utility_types::layout_widget::LayoutGroup;
use graph_craft::concrete;
use graph_craft::document::value::*;
use graph_craft::document::*;
use graph_craft::document::{value::*, DocumentNodeImplementation};
use graph_craft::imaginate_input::ImaginateSamplingMethod;
use graph_craft::proto::{NodeIdentifier, Type};
use graph_craft::{concrete, generic};
use graphene_core::raster::Image;
use std::collections::VecDeque;
@@ -91,8 +91,8 @@ fn document_node_types() -> Vec<DocumentNodeType> {
1,
DocumentNode {
name: "BlurNode".to_string(),
inputs: vec![NodeInput::Node(0), NodeInput::Network, NodeInput::Network],
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::raster::BlurNode", &[])),
inputs: vec![NodeInput::Node(0), NodeInput::Network, NodeInput::Network, NodeInput::Node(0)],
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::raster::BlurNode", &[concrete!("Image")])),
metadata: Default::default(),
},
),
@@ -118,7 +118,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Identity",
category: "General",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]),
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[generic!("T")]),
inputs: &[DocumentInputType {
name: "In",
data_type: FrontendGraphDataType::General,
@@ -130,7 +130,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Image",
category: "Ignore",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]),
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[generic!("T")]),
inputs: &[DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), false)],
outputs: &[FrontendGraphDataType::Raster],
properties: |_document_node, _node_id, _context| node_properties::string_properties("A bitmap image embedded in this node"),
@@ -138,7 +138,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Input",
category: "Ignore",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]),
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[generic!("T")]),
inputs: &[DocumentInputType {
name: "In",
data_type: FrontendGraphDataType::Raster,
@@ -150,7 +150,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Output",
category: "Ignore",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]),
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[generic!("T")]),
inputs: &[DocumentInputType {
name: "In",
data_type: FrontendGraphDataType::Raster,
@@ -162,7 +162,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Grayscale",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::raster::GrayscaleNode", &[]),
identifier: NodeImplementation::proto("graphene_std::raster::GrayscaleNode", &[concrete!("Image")]),
inputs: &[DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true)],
outputs: &[FrontendGraphDataType::Raster],
properties: node_properties::no_properties,
@@ -171,7 +171,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "GpuImage",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::executor::MapGpuSingleImageNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto("graphene_std::executor::MapGpuSingleImageNode", &[concrete!("Image")]),
inputs: &[
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
DocumentInputType {
@@ -187,7 +187,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "QuantizeImage",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::quantization::GenerateQuantizationNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto("graphene_std::quantization::GenerateQuantizationNode", &[concrete!("Image")]),
inputs: &[
DocumentInputType {
name: "Image",
@@ -219,7 +219,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Invert RGB",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::raster::InvertRGBNode", &[]),
identifier: NodeImplementation::proto("graphene_std::raster::InvertRGBNode", &[concrete!("Image")]),
inputs: &[DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true)],
outputs: &[FrontendGraphDataType::Raster],
properties: node_properties::no_properties,
@@ -227,7 +227,10 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Hue/Saturation",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::raster::HueSaturationNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto(
"graphene_std::raster::HueSaturationNode<_, _, _>",
&[concrete!("Image"), concrete!("f64"), concrete!("f64"), concrete!("f64")],
),
inputs: &[
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
DocumentInputType::new("Hue Shift", TaggedValue::F64(0.), false),
@@ -240,7 +243,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Brightness/Contrast",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::raster::BrightnessContrastNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto("graphene_std::raster::BrightnessContrastNode<_, _>", &[concrete!("Image"), concrete!("f64"), concrete!("f64")]),
inputs: &[
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
DocumentInputType::new("Brightness", TaggedValue::F64(0.), false),
@@ -252,7 +255,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Gamma",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::raster::GammaNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto("graphene_std::raster::GammaNode<_>", &[concrete!("Image"), concrete!("f64")]),
inputs: &[
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
DocumentInputType::new("Gamma", TaggedValue::F64(1.), false),
@@ -263,7 +266,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Opacity",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::raster::OpacityNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto("graphene_std::raster::OpacityNode<_>", &[concrete!("Image"), concrete!("f64")]),
inputs: &[
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
DocumentInputType::new("Factor", TaggedValue::F64(1.), false),
@@ -274,7 +277,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Posterize",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::raster::PosterizeNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto("graphene_std::raster::PosterizeNode<_>", &[concrete!("Image"), concrete!("f64")]),
inputs: &[
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
DocumentInputType::new("Value", TaggedValue::F64(5.), false),
@@ -285,7 +288,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Exposure",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_std::raster::ExposureNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto("graphene_std::raster::ExposureNode<_>", &[concrete!("Image"), concrete!("f64")]),
inputs: &[
DocumentInputType::new("Image", TaggedValue::Image(Image::empty()), true),
DocumentInputType::new("Value", TaggedValue::F64(0.), false),
@@ -297,7 +300,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Add",
category: "Math",
identifier: NodeImplementation::proto("graphene_core::ops::AddNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto("graphene_core::ops::AddParameterNode<_>", &[concrete!("f64"), concrete!("f64")]),
inputs: &[
DocumentInputType::new("Input", TaggedValue::F64(0.), true),
DocumentInputType::new("Addend", TaggedValue::F64(0.), true),
@@ -324,7 +327,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
DocumentNodeType {
name: "Path Generator",
category: "Vector",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[concrete!("Any<'_>")]),
identifier: NodeImplementation::proto("graphene_core::ops::IdNode", &[generic!("T")]),
inputs: &[DocumentInputType {
name: "Path Data",
data_type: FrontendGraphDataType::Subpath,
@@ -363,7 +366,7 @@ static STATIC_NODES: &[DocumentNodeType] = &[
pub const IMAGINATE_NODE: DocumentNodeType = DocumentNodeType {
name: "Imaginate",
category: "Image Synthesis",
identifier: NodeImplementation::proto("graphene_std::raster::ImaginateNode", &[concrete!("&TypeErasedNode")]),
identifier: NodeImplementation::proto("graphene_std::raster::ImaginateNode<_>", &[concrete!("Image"), concrete!("Option<std::sync::Arc<Image>>")]),
inputs: &[
DocumentInputType::new("Input Image", TaggedValue::Image(Image::empty()), true),
DocumentInputType::new("Seed", TaggedValue::F64(0.), false),
@@ -373,7 +373,7 @@ pub fn imaginate_properties(document_node: &DocumentNode, node_id: NodeId, conte
panic!("Invalid status input")
};
let NodeInput::Value {tagged_value: TaggedValue::RcImage( cached_data),..} = cached_value else {
panic!("Invalid cached image input")
panic!("Invalid cached image input, recieved {:?}, index: {}", cached_value, cached_index)
};
let &NodeInput::Value {tagged_value: TaggedValue::F64( percent_complete),..} = complete_value else {
panic!("Invalid percent complete input")
@@ -9,15 +9,9 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, specta::Type)]
pub struct RawBuffer(Vec<u8>);
impl From<Vec<u64>> for RawBuffer {
fn from(iter: Vec<u64>) -> Self {
// https://github.com/rust-lang/rust-clippy/issues/4484
let v_from_raw: Vec<u8> = unsafe {
// prepare for an auto-forget of the initial vec:
let v_orig: &mut Vec<_> = &mut *std::mem::ManuallyDrop::new(iter);
Vec::from_raw_parts(v_orig.as_mut_ptr() as *mut u8, v_orig.len() * 8, v_orig.capacity() * 8)
// v_orig is never used again, so no aliasing issue
};
impl From<&[u64]> for RawBuffer {
fn from(iter: &[u64]) -> Self {
let v_from_raw: Vec<u8> = iter.iter().flat_map(|x| x.to_ne_bytes()).collect();
Self(v_from_raw)
}
}