mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-24 08:05:04 +00:00
Upgrade several Rust dependencies (#1613)
`specta` from Hypercube's fork commit to latest upstream commit `wasm-bindgen` 0.2.87 -> 0.2.91 `spirv-std` from 0.9 to not-yet-merged commit in https://github.com/EmbarkStudios/rust-gpu/pull/1115 `wgpu` 0.17 -> 0.19 `winit` 0.28.6 -> 0.29 `vello` and `vello_svg` from latest upstream commit to not-yet-merged commit in https://github.com/linebender/vello/pull/427 `resvg` 0.36.0 -> 0.39 `glam` 0.24 -> 0.25 `rustybuzz` 0.8.0 -> 0.10.0 `js-sys` and `web-sys` 0.3.55 -> 0.3.67 `usvg` 0.36.0 -> 0.39 `spirv` 0.2.0 -> 0.3 * Update a couple of dependencies * More test fixing… * Use upstream Specta instead of fork * Update comments in Cargo.toml --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
80bffd39bf
commit
6f6fb3bcd4
20 changed files with 879 additions and 893 deletions
1527
Cargo.lock
generated
1527
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
37
Cargo.toml
37
Cargo.toml
|
@ -20,26 +20,22 @@ members = [
|
|||
"libraries/bezier-rs",
|
||||
"website/other/bezier-rs-demos/wasm",
|
||||
]
|
||||
|
||||
resolver = "2"
|
||||
|
||||
exclude = ["node-graph/gpu-compiler"]
|
||||
|
||||
[workspace.dependencies]
|
||||
# We are using this fork because:
|
||||
# - They specify glam=0.22 whereas we use glam=0.24 so the encoding doesn't work.
|
||||
# - Their current release doesn't allow doc comments and produces a compile error.
|
||||
# See: https://github.com/GraphiteEditor/Graphite/pull/1346/files/a2206401b5b4cf669e71df57f6c95c67336802c8#r1280201659
|
||||
specta = { git = "https://github.com/0HyperCube/specta.git", rev = "c47a22b4c0863d27bc47529f300de3969480c66d", features = [
|
||||
specta = { git = "https://github.com/oscartbeaumont/specta.git", features = [
|
||||
"glam",
|
||||
"typescript",
|
||||
] }
|
||||
rustc-hash = "1.1.0"
|
||||
# wasm-bindgen upgrades may break various things so we pin the version
|
||||
wasm-bindgen = "=0.2.87"
|
||||
wasm-bindgen = "=0.2.91"
|
||||
dyn-any = { path = "libraries/dyn-any", features = ["derive", "glam"] }
|
||||
graphene-core = { path = "node-graph/gcore" }
|
||||
graph-craft = { path = "node-graph/graph-craft", features = ["serde"] }
|
||||
spirv-std = { version = "0.9" }
|
||||
# Remove the `rev` commit hash field once this merges: https://github.com/EmbarkStudios/rust-gpu/pull/1115 (and consider switching to a release version upon the next release)
|
||||
spirv-std = { git = "https://github.com/EmbarkStudios/rust-gpu.git", rev = "08e7559012ab6645cf36f6cce84426f9e34b88d9" }
|
||||
bytemuck = { version = "1.13", features = ["derive"] }
|
||||
async-trait = { version = "0.1" }
|
||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||
|
@ -61,33 +57,34 @@ chrono = "^0.4.23"
|
|||
ron = "0.8"
|
||||
fastnoise-lite = "1.1.0"
|
||||
wgpu-types = "0.17"
|
||||
wgpu = "0.17"
|
||||
wgpu = "0.19"
|
||||
wasm-bindgen-futures = { version = "0.4.36" }
|
||||
winit = "0.28.6"
|
||||
winit = "0.29"
|
||||
url = "2.4.0"
|
||||
tokio = { version = "1.29", features = ["fs", "io-std"] }
|
||||
vello = { git = "https://github.com/linebender/vello", version = "0.0.1" }
|
||||
vello_svg = { git = "https://github.com/linebender/vello", version = "0.0.1" }
|
||||
resvg = { version = "0.36.0" }
|
||||
# Remove the `rev` commit hash field once this merges: https://github.com/linebender/vello/pull/427
|
||||
vello = { git = "https://github.com/linebender/vello.git", rev = "f075f58fc50c569daf5ca720fe81b5fee946ce7f", version = "0.0.1" }
|
||||
vello_svg = { git = "https://github.com/linebender/vello.git", rev = "f075f58fc50c569daf5ca720fe81b5fee946ce7f", version = "0.0.1" }
|
||||
resvg = { version = "0.39" }
|
||||
rand = { version = "0.8.5", default-features = false }
|
||||
rand_chacha = { version = "0.3.1" }
|
||||
bezier-rs = { path = "libraries/bezier-rs", features = ["dyn-any"] }
|
||||
kurbo = { git = "https://github.com/linebender/kurbo.git", features = [
|
||||
"serde",
|
||||
] }
|
||||
glam = { version = "0.24", default-features = false, features = ["serde"] }
|
||||
glam = { version = "0.25", default-features = false, features = ["serde"] }
|
||||
node-macro = { path = "node-graph/node-macro" }
|
||||
base64 = { version = "0.21" }
|
||||
image = { version = "0.24", default-features = false, features = ["png"] }
|
||||
rustybuzz = { version = "0.8.0" }
|
||||
rustybuzz = { version = "0.10.0" }
|
||||
num-derive = { version = "0.4" }
|
||||
num-traits = { version = "0.2.15", default-features = false, features = [
|
||||
"i128",
|
||||
] }
|
||||
js-sys = { version = "0.3.55" }
|
||||
web-sys = { version = "0.3.55" }
|
||||
usvg = "0.36.0"
|
||||
spirv = "0.2.0"
|
||||
js-sys = { version = "=0.3.67" }
|
||||
web-sys = { version = "=0.3.67" }
|
||||
usvg = "0.39"
|
||||
spirv = "0.3"
|
||||
fern = { version = "0.6", features = ["colored"] }
|
||||
|
||||
[profile.dev.package.graphite-editor]
|
||||
|
|
|
@ -5,31 +5,26 @@
|
|||
#[test]
|
||||
fn generate_ts_types() {
|
||||
use crate::messages::prelude::FrontendMessage;
|
||||
use specta::{
|
||||
ts::{export_datatype, BigIntExportBehavior, ExportConfiguration},
|
||||
DefOpts, NamedType, Type, TypeDefs,
|
||||
};
|
||||
use specta::ts::{export_named_datatype, BigIntExportBehavior, ExportConfig};
|
||||
use specta::{NamedType, TypeMap};
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
||||
let config = ExportConfiguration::new().bigint(BigIntExportBehavior::Number);
|
||||
let config = ExportConfig::new().bigint(BigIntExportBehavior::Number);
|
||||
|
||||
let mut type_map = TypeDefs::new();
|
||||
let mut type_map = TypeMap::default();
|
||||
|
||||
let datatype = FrontendMessage::named_data_type(
|
||||
DefOpts {
|
||||
parent_inline: false,
|
||||
type_map: &mut type_map,
|
||||
},
|
||||
&FrontendMessage::definition_generics().into_iter().map(Into::into).collect::<Vec<_>>(),
|
||||
)
|
||||
.unwrap();
|
||||
let datatype = FrontendMessage::definition_named_data_type(&mut type_map);
|
||||
|
||||
let mut export = String::new();
|
||||
|
||||
export += &export_datatype(&config, &datatype).unwrap();
|
||||
export += &export_named_datatype(&config, &datatype, &type_map).unwrap();
|
||||
|
||||
type_map.values().flatten().flat_map(|v| export_datatype(&config, v)).for_each(|e| export += &format!("\n\n{e}"));
|
||||
type_map
|
||||
.iter()
|
||||
.map(|(_, v)| v)
|
||||
.flat_map(|v| export_named_datatype(&config, v, &type_map))
|
||||
.for_each(|e| export += &format!("\n\n{e}"));
|
||||
|
||||
let mut file = File::create("../types.ts").unwrap();
|
||||
|
||||
|
|
|
@ -457,8 +457,9 @@ impl WidgetHolder {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, specta::Type)]
|
||||
pub struct WidgetCallback<T> {
|
||||
#[specta(skip)]
|
||||
pub callback: Arc<dyn Fn(&T) -> Message + 'static + Send + Sync>,
|
||||
}
|
||||
|
||||
|
|
|
@ -41,6 +41,8 @@ pub enum Message {
|
|||
|
||||
/// Provides an impl of `specta::Type` for `MessageDiscriminant`, the struct created by `impl_message`.
|
||||
/// Specta isn't integrated with `impl_message`, so a remote impl must be provided using this struct.
|
||||
#[derive(specta::Type)]
|
||||
#[specta(inline, remote = "MessageDiscriminant")]
|
||||
pub struct MessageDiscriminantDef(pub u8);
|
||||
impl specta::Type for MessageDiscriminant {
|
||||
fn inline(_type_map: &mut specta::TypeMap, _generics: specta::Generics) -> specta::DataType {
|
||||
specta::DataType::Any
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ use graphene_core::{Artboard, Color};
|
|||
use transform_utils::LayerBounds;
|
||||
|
||||
use glam::{DAffine2, DVec2, IVec2};
|
||||
use usvg::NodeExt;
|
||||
|
||||
pub mod transform_utils;
|
||||
|
||||
|
@ -761,7 +760,6 @@ impl MessageHandler<GraphOperationMessage, GraphOperationHandlerData<'_>> for Gr
|
|||
parent,
|
||||
insert_index,
|
||||
} => {
|
||||
use usvg::TreeParsing;
|
||||
let tree = match usvg::Tree::from_str(&svg, &usvg::Options::default()) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
|
@ -774,7 +772,7 @@ impl MessageHandler<GraphOperationMessage, GraphOperationHandlerData<'_>> for Gr
|
|||
};
|
||||
let mut modify_inputs = ModifyInputsContext::new(document_network, document_metadata, node_graph, responses);
|
||||
|
||||
import_usvg_node(&mut modify_inputs, &tree.root, transform, id, parent, insert_index);
|
||||
import_usvg_node(&mut modify_inputs, &usvg::Node::Group(Box::new(tree.root)), transform, id, parent, insert_index);
|
||||
load_network_structure(document_network, document_metadata, selected_nodes, collapsed);
|
||||
}
|
||||
}
|
||||
|
@ -803,14 +801,14 @@ fn import_usvg_node(modify_inputs: &mut ModifyInputsContext, node: &usvg::Node,
|
|||
return;
|
||||
};
|
||||
modify_inputs.layer_node = Some(layer);
|
||||
match &*node.borrow() {
|
||||
usvg::NodeKind::Group(_group) => {
|
||||
for child in node.children() {
|
||||
match node {
|
||||
usvg::Node::Group(group) => {
|
||||
for child in &group.children {
|
||||
import_usvg_node(modify_inputs, &child, transform, NodeId(generate_uuid()), LayerNodeIdentifier::new_unchecked(layer), -1);
|
||||
}
|
||||
modify_inputs.layer_node = Some(layer);
|
||||
}
|
||||
usvg::NodeKind::Path(path) => {
|
||||
usvg::Node::Path(path) => {
|
||||
let subpaths = convert_usvg_path(path);
|
||||
let bounds = subpaths.iter().filter_map(|subpath| subpath.bounding_box()).reduce(Quad::combine_bounds).unwrap_or_default();
|
||||
let transformed_bounds = subpaths
|
||||
|
@ -836,10 +834,10 @@ fn import_usvg_node(modify_inputs: &mut ModifyInputsContext, node: &usvg::Node,
|
|||
);
|
||||
apply_usvg_stroke(&path.stroke, modify_inputs);
|
||||
}
|
||||
usvg::NodeKind::Image(_image) => {
|
||||
usvg::Node::Image(_image) => {
|
||||
warn!("Skip image")
|
||||
}
|
||||
usvg::NodeKind::Text(text) => {
|
||||
usvg::Node::Text(text) => {
|
||||
let font = Font::new(crate::consts::DEFAULT_FONT_FAMILY.to_string(), crate::consts::DEFAULT_FONT_STYLE.to_string());
|
||||
modify_inputs.insert_text(text.chunks.iter().map(|chunk| chunk.text.clone()).collect(), font, 24., layer);
|
||||
modify_inputs.fill_set(Fill::Solid(Color::BLACK));
|
||||
|
|
|
@ -1490,7 +1490,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||
name: "Render Texture".to_string(),
|
||||
inputs: vec![
|
||||
NodeInput::Network(concrete!(ShaderInputFrame<WgpuExecutor>)),
|
||||
NodeInput::Network(concrete!(Arc<SurfaceHandle<<WgpuExecutor as GpuExecutor>::Surface>>)),
|
||||
NodeInput::Network(concrete!(Arc<SurfaceHandle<<WgpuExecutor as GpuExecutor>::Surface<'_>>>)),
|
||||
NodeInput::node(NodeId(0), 0),
|
||||
],
|
||||
implementation: DocumentNodeImplementation::Unresolved(ProtoNodeIdentifier::new("gpu_executor::RenderTextureNode<_, _>")),
|
||||
|
|
|
@ -19,6 +19,7 @@ pub fn empty_provider() -> OverlayProvider {
|
|||
pub struct OverlayContext {
|
||||
// Serde functionality isn't used but is required by the message system macros
|
||||
#[serde(skip, default = "overlay_canvas_context")]
|
||||
#[specta(skip)]
|
||||
pub render_context: web_sys::CanvasRenderingContext2d,
|
||||
pub size: DVec2,
|
||||
}
|
||||
|
|
|
@ -28,10 +28,10 @@ wasm-bindgen = { workspace = true }
|
|||
serde-wasm-bindgen = "0.6"
|
||||
js-sys = { workspace = true }
|
||||
wasm-bindgen-futures = { workspace = true }
|
||||
ron = { version = "0.8", optional = true }
|
||||
ron = { workspace = true, optional = true }
|
||||
bezier-rs = { workspace = true }
|
||||
# We don't have wgpu on multiple threads (yet) https://github.com/gfx-rs/wgpu/blob/trunk/CHANGELOG.md#wgpu-types-now-send-sync-on-wasm
|
||||
wgpu = { version = "0.17", features = ["fragile-send-sync-non-atomic-wasm"] }
|
||||
wgpu = { workspace = true, features = ["fragile-send-sync-non-atomic-wasm"] }
|
||||
meval = "0.2.0"
|
||||
|
||||
[dependencies.web-sys]
|
||||
|
|
|
@ -14,8 +14,8 @@ repository = "https://github.com/GraphiteEditor/Graphite/tree/master/libraries/b
|
|||
documentation = "https://graphite.rs/libraries/bezier-rs/"
|
||||
|
||||
[dependencies]
|
||||
glam = { version = "0.24", features = ["serde"] }
|
||||
glam = { version = "0.25", features = ["serde"] }
|
||||
|
||||
dyn-any = { version = "0.3.0", path = "../dyn-any", optional = true }
|
||||
serde = { version = "1.0", workspace = true, optional = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
log = { workspace = true, optional = true }
|
||||
|
|
|
@ -14,7 +14,7 @@ documentation = "https://docs.rs/dyn-any"
|
|||
[dependencies]
|
||||
dyn-any-derive = { path = "derive", version = "0.3.0", optional = true }
|
||||
log = { version = "0.4", optional = true }
|
||||
glam = { version = "0.24", optional = true, default-features = false }
|
||||
glam = { version = "0.25", optional = true, default-features = false }
|
||||
|
||||
[features]
|
||||
derive = ["dyn-any-derive"]
|
||||
|
|
|
@ -233,7 +233,7 @@ impl GraphicGroup {
|
|||
};
|
||||
|
||||
pub fn to_usvg_tree(&self, resolution: UVec2, viewbox: [DVec2; 2]) -> usvg::Tree {
|
||||
let root_node = usvg::Node::new(usvg::NodeKind::Group(usvg::Group::default()));
|
||||
let mut root_node = usvg::Group::default();
|
||||
let tree = usvg::Tree {
|
||||
size: usvg::Size::from_wh(resolution.x as f32, resolution.y as f32).unwrap(),
|
||||
view_box: usvg::ViewBox {
|
||||
|
@ -244,7 +244,7 @@ impl GraphicGroup {
|
|||
};
|
||||
|
||||
for element in self.iter() {
|
||||
root_node.append(element.to_usvg_node());
|
||||
root_node.children.push(element.to_usvg_node());
|
||||
}
|
||||
tree
|
||||
}
|
||||
|
@ -283,20 +283,20 @@ impl GraphicElement {
|
|||
}
|
||||
let path = builder.finish().unwrap();
|
||||
let mut path = usvg::Path::new(path.into());
|
||||
path.transform = transform;
|
||||
path.abs_transform = transform;
|
||||
// TODO: use proper style
|
||||
path.fill = None;
|
||||
path.stroke = Some(usvg::Stroke::default());
|
||||
usvg::Node::new(usvg::NodeKind::Path(path))
|
||||
usvg::Node::Path(Box::new(path))
|
||||
}
|
||||
GraphicElement::ImageFrame(image_frame) => {
|
||||
if image_frame.image.width * image_frame.image.height == 0 {
|
||||
return usvg::Node::new(usvg::NodeKind::Group(usvg::Group::default()));
|
||||
return usvg::Node::Group(Box::new(usvg::Group::default()));
|
||||
}
|
||||
let png = image_frame.image.to_png();
|
||||
usvg::Node::new(usvg::NodeKind::Image(usvg::Image {
|
||||
usvg::Node::Image(Box::new(usvg::Image {
|
||||
id: String::new(),
|
||||
transform: to_transform(image_frame.transform),
|
||||
abs_transform: to_transform(image_frame.transform),
|
||||
visibility: usvg::Visibility::Visible,
|
||||
view_box: usvg::ViewBox {
|
||||
rect: usvg::NonZeroRect::from_xywh(0., 0., 1., 1.).unwrap(),
|
||||
|
@ -304,14 +304,13 @@ impl GraphicElement {
|
|||
},
|
||||
rendering_mode: usvg::ImageRendering::OptimizeSpeed,
|
||||
kind: usvg::ImageKind::PNG(png.into()),
|
||||
bounding_box: None,
|
||||
}))
|
||||
}
|
||||
GraphicElement::Text(text) => usvg::Node::new(usvg::NodeKind::Text(usvg::Text {
|
||||
GraphicElement::Text(text) => usvg::Node::Text(Box::new(usvg::Text {
|
||||
id: String::new(),
|
||||
transform: usvg::Transform::identity(),
|
||||
abs_transform: usvg::Transform::identity(),
|
||||
rendering_mode: usvg::TextRendering::OptimizeSpeed,
|
||||
positions: Vec::new(),
|
||||
rotate: Vec::new(),
|
||||
writing_mode: usvg::WritingMode::LeftToRight,
|
||||
chunks: vec![usvg::TextChunk {
|
||||
text: text.clone(),
|
||||
|
@ -321,17 +320,25 @@ impl GraphicElement {
|
|||
spans: vec![],
|
||||
text_flow: usvg::TextFlow::Linear,
|
||||
}],
|
||||
dx: Vec::new(),
|
||||
dy: Vec::new(),
|
||||
rotate: Vec::new(),
|
||||
bounding_box: None,
|
||||
abs_bounding_box: None,
|
||||
stroke_bounding_box: None,
|
||||
abs_stroke_bounding_box: None,
|
||||
flattened: None,
|
||||
})),
|
||||
GraphicElement::GraphicGroup(group) => {
|
||||
let group_element = usvg::Node::new(usvg::NodeKind::Group(usvg::Group::default()));
|
||||
let mut group_element = usvg::Group::default();
|
||||
|
||||
for element in group.iter() {
|
||||
group_element.append(element.to_usvg_node());
|
||||
group_element.children.push(element.to_usvg_node());
|
||||
}
|
||||
group_element
|
||||
usvg::Node::Group(Box::new(group_element))
|
||||
}
|
||||
// TODO
|
||||
GraphicElement::Artboard(_board) => usvg::Node::new(usvg::NodeKind::Group(usvg::Group::default())),
|
||||
GraphicElement::Artboard(_board) => usvg::Node::Group(Box::new(usvg::Group::default())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ use bezier_rs::Subpath;
|
|||
|
||||
use base64::Engine;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use usvg::TreeParsing;
|
||||
|
||||
/// Represents a clickable target for the layer
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -216,18 +215,21 @@ pub trait GraphicElementRendered {
|
|||
let opt = usvg::Options::default();
|
||||
|
||||
let tree = usvg::Tree::from_str(&svg, &opt).expect("Failed to parse SVG");
|
||||
tree.root.clone()
|
||||
usvg::Node::Group(Box::new(tree.root.clone()))
|
||||
}
|
||||
|
||||
fn to_usvg_tree(&self, resolution: glam::UVec2, viewbox: [DVec2; 2]) -> usvg::Tree {
|
||||
let root_node = self.to_usvg_node();
|
||||
let root = match self.to_usvg_node() {
|
||||
usvg::Node::Group(root_node) => *root_node,
|
||||
_ => usvg::Group::default(),
|
||||
};
|
||||
usvg::Tree {
|
||||
size: usvg::Size::from_wh(resolution.x as f32, resolution.y as f32).unwrap(),
|
||||
view_box: usvg::ViewBox {
|
||||
rect: usvg::NonZeroRect::from_ltrb(viewbox[0].x as f32, viewbox[0].y as f32, viewbox[1].x as f32, viewbox[1].y as f32).unwrap(),
|
||||
aspect: usvg::AspectRatio::default(),
|
||||
},
|
||||
root: root_node.clone(),
|
||||
root,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -275,11 +277,11 @@ impl GraphicElementRendered for GraphicGroup {
|
|||
}
|
||||
|
||||
fn to_usvg_node(&self) -> usvg::Node {
|
||||
let root_node = usvg::Node::new(usvg::NodeKind::Group(usvg::Group::default()));
|
||||
let mut root_node = usvg::Group::default();
|
||||
for element in self.iter() {
|
||||
root_node.append(element.to_usvg_node());
|
||||
root_node.children.push(element.to_usvg_node());
|
||||
}
|
||||
root_node
|
||||
usvg::Node::Group(Box::new(root_node))
|
||||
}
|
||||
|
||||
fn contains_artboard(&self) -> bool {
|
||||
|
@ -358,11 +360,11 @@ impl GraphicElementRendered for VectorData {
|
|||
}
|
||||
let path = builder.finish().unwrap();
|
||||
let mut path = usvg::Path::new(path.into());
|
||||
path.transform = transform;
|
||||
path.abs_transform = transform;
|
||||
// TODO: use proper style
|
||||
path.fill = None;
|
||||
path.stroke = Some(usvg::Stroke::default());
|
||||
usvg::Node::new(usvg::NodeKind::Path(path))
|
||||
usvg::Node::Path(Box::new(path))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,12 +501,12 @@ impl GraphicElementRendered for ImageFrame<Color> {
|
|||
fn to_usvg_node(&self) -> usvg::Node {
|
||||
let image_frame = self;
|
||||
if image_frame.image.width * image_frame.image.height == 0 {
|
||||
return usvg::Node::new(usvg::NodeKind::Group(usvg::Group::default()));
|
||||
return usvg::Node::Group(Box::new(usvg::Group::default()));
|
||||
}
|
||||
let png = image_frame.image.to_png();
|
||||
usvg::Node::new(usvg::NodeKind::Image(usvg::Image {
|
||||
usvg::Node::Image(Box::new(usvg::Image {
|
||||
id: String::new(),
|
||||
transform: to_transform(image_frame.transform),
|
||||
abs_transform: to_transform(image_frame.transform),
|
||||
visibility: usvg::Visibility::Visible,
|
||||
view_box: usvg::ViewBox {
|
||||
rect: usvg::NonZeroRect::from_xywh(0., 0., 1., 1.).unwrap(),
|
||||
|
@ -512,6 +514,7 @@ impl GraphicElementRendered for ImageFrame<Color> {
|
|||
},
|
||||
rendering_mode: usvg::ImageRendering::OptimizeSpeed,
|
||||
kind: usvg::ImageKind::PNG(png.into()),
|
||||
bounding_box: None,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -594,12 +597,10 @@ impl<T: Primitive> GraphicElementRendered for T {
|
|||
|
||||
fn to_usvg_node(&self) -> usvg::Node {
|
||||
let text = self;
|
||||
usvg::Node::new(usvg::NodeKind::Text(usvg::Text {
|
||||
usvg::Node::Text(Box::new(usvg::Text {
|
||||
id: String::new(),
|
||||
transform: usvg::Transform::identity(),
|
||||
abs_transform: usvg::Transform::identity(),
|
||||
rendering_mode: usvg::TextRendering::OptimizeSpeed,
|
||||
positions: Vec::new(),
|
||||
rotate: Vec::new(),
|
||||
writing_mode: usvg::WritingMode::LeftToRight,
|
||||
chunks: vec![usvg::TextChunk {
|
||||
text: text.to_string(),
|
||||
|
@ -609,6 +610,14 @@ impl<T: Primitive> GraphicElementRendered for T {
|
|||
spans: vec![],
|
||||
text_flow: usvg::TextFlow::Linear,
|
||||
}],
|
||||
dx: Vec::new(),
|
||||
dy: Vec::new(),
|
||||
rotate: Vec::new(),
|
||||
bounding_box: None,
|
||||
abs_bounding_box: None,
|
||||
stroke_bounding_box: None,
|
||||
abs_stroke_bounding_box: None,
|
||||
flattened: None,
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ pub trait GpuExecutor {
|
|||
type BufferHandle: Send + Sync;
|
||||
type TextureHandle: Send + Sync;
|
||||
type TextureView: Send + Sync;
|
||||
type Surface: Send + Sync;
|
||||
type Surface<'window>: Send + Sync;
|
||||
type Window;
|
||||
type CommandBuffer;
|
||||
|
||||
|
@ -55,10 +55,10 @@ pub trait GpuExecutor {
|
|||
fn create_texture_view(&self, texture: ShaderInput<Self>) -> Result<ShaderInput<Self>>;
|
||||
fn create_output_buffer(&self, len: usize, ty: Type, cpu_readable: bool) -> Result<ShaderInput<Self>>;
|
||||
fn create_compute_pass(&self, layout: &PipelineLayout<Self>, read_back: Option<Arc<ShaderInput<Self>>>, instances: ComputePassDimensions) -> Result<Self::CommandBuffer>;
|
||||
fn create_render_pass(&self, texture: Arc<ShaderInput<Self>>, canvas: Arc<SurfaceHandle<Self::Surface>>) -> Result<()>;
|
||||
fn create_render_pass(&self, texture: Arc<ShaderInput<Self>>, canvas: Arc<SurfaceHandle<Self::Surface<'_>>>) -> Result<()>;
|
||||
fn execute_compute_pipeline(&self, encoder: Self::CommandBuffer) -> Result<()>;
|
||||
fn read_output_buffer(&self, buffer: Arc<ShaderInput<Self>>) -> ReadBackFuture;
|
||||
fn create_surface(&self, window: SurfaceHandle<Self::Window>) -> Result<SurfaceHandle<Self::Surface>>;
|
||||
fn create_surface(&self, window: SurfaceHandle<Self::Window>) -> Result<SurfaceHandle<Self::Surface<'_>>>;
|
||||
}
|
||||
|
||||
pub trait SpirVCompiler {
|
||||
|
@ -110,7 +110,7 @@ impl GpuExecutor for DummyExecutor {
|
|||
type BufferHandle = ();
|
||||
type TextureHandle = ();
|
||||
type TextureView = ();
|
||||
type Surface = ();
|
||||
type Surface<'window> = ();
|
||||
type Window = ();
|
||||
type CommandBuffer = ();
|
||||
|
||||
|
@ -142,7 +142,7 @@ impl GpuExecutor for DummyExecutor {
|
|||
todo!()
|
||||
}
|
||||
|
||||
fn create_render_pass(&self, _texture: Arc<ShaderInput<Self>>, _canvas: Arc<SurfaceHandle<Self::Surface>>) -> Result<()> {
|
||||
fn create_render_pass(&self, _texture: Arc<ShaderInput<Self>>, _canvas: Arc<SurfaceHandle<Self::Surface<'_>>>) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ impl GpuExecutor for DummyExecutor {
|
|||
todo!()
|
||||
}
|
||||
|
||||
fn create_surface(&self, _window: SurfaceHandle<Self::Window>) -> Result<SurfaceHandle<Self::Surface>> {
|
||||
fn create_surface(&self, _window: SurfaceHandle<Self::Window>) -> Result<SurfaceHandle<Self::Surface<'_>>> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
@ -496,7 +496,7 @@ async fn read_output_buffer_node<'a: 'input, E: 'a + GpuExecutor>(buffer: Arc<Sh
|
|||
pub struct CreateGpuSurfaceNode {}
|
||||
|
||||
#[node_macro::node_fn(CreateGpuSurfaceNode)]
|
||||
async fn create_gpu_surface<'a: 'input, E: 'a + GpuExecutor<Window = Io::Surface>, Io: ApplicationIo<Executor = E>>(editor_api: EditorApi<'a, Io>) -> Arc<SurfaceHandle<E::Surface>> {
|
||||
async fn create_gpu_surface<'a: 'input, E: 'a + GpuExecutor<Window = Io::Surface>, Io: ApplicationIo<Executor = E>>(editor_api: EditorApi<'a, Io>) -> Arc<SurfaceHandle<E::Surface<'a>>> {
|
||||
let canvas = editor_api.application_io.create_surface();
|
||||
let executor = editor_api.application_io.gpu_executor().unwrap();
|
||||
Arc::new(executor.create_surface(canvas).unwrap())
|
||||
|
@ -529,7 +529,7 @@ where
|
|||
}
|
||||
|
||||
#[node_macro::node_fn(RenderTextureNode)]
|
||||
async fn render_texture_node<'a: 'input, E: 'a + GpuExecutor>(image: ShaderInputFrame<E>, surface: Arc<SurfaceHandle<E::Surface>>, executor: &'a E) -> SurfaceFrame {
|
||||
async fn render_texture_node<'a: 'input, E: 'a + GpuExecutor>(image: ShaderInputFrame<E>, surface: Arc<SurfaceHandle<E::Surface<'input>>>, executor: &'a E) -> SurfaceFrame {
|
||||
let surface_id = surface.surface_id;
|
||||
log::trace!("rendering to surface {surface_id:?}");
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ struct InternalImaginateControl {
|
|||
status: Mutex<ImaginateStatus>,
|
||||
trigger_regenerate: AtomicBool,
|
||||
#[serde(skip)]
|
||||
#[specta(skip)]
|
||||
termination_sender: Mutex<Option<Box<dyn ImaginateTerminationHandle>>>,
|
||||
}
|
||||
|
||||
|
|
|
@ -141,9 +141,9 @@ impl ApplicationIo for WasmApplicationIo {
|
|||
use winit::platform::wayland::EventLoopBuilderExtWayland;
|
||||
|
||||
#[cfg(feature = "wayland")]
|
||||
let event_loop = winit::event_loop::EventLoopBuilder::new().with_any_thread(true).build();
|
||||
let event_loop = winit::event_loop::EventLoopBuilder::new().with_any_thread(true).build().unwrap();
|
||||
#[cfg(not(feature = "wayland"))]
|
||||
let event_loop = winit::event_loop::EventLoop::new();
|
||||
let event_loop = winit::event_loop::EventLoop::new().unwrap();
|
||||
let window = winit::window::WindowBuilder::new()
|
||||
.with_title("Graphite")
|
||||
.with_inner_size(winit::dpi::PhysicalSize::new(800, 600))
|
||||
|
@ -336,11 +336,9 @@ fn render_canvas(
|
|||
if let Some(exec) = editor.application_io.gpu_executor() {
|
||||
todo!()
|
||||
} else {
|
||||
let rtree = resvg::Tree::from_usvg(&usvg_tree);
|
||||
|
||||
let pixmap_size = rtree.size.to_int_size();
|
||||
let pixmap_size = usvg_tree.size.to_int_size();
|
||||
let mut pixmap = resvg::tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();
|
||||
rtree.render(resvg::tiny_skia::Transform::default(), &mut pixmap.as_mut());
|
||||
resvg::render(&usvg_tree, resvg::tiny_skia::Transform::default(), &mut pixmap.as_mut());
|
||||
let array: Clamped<&[u8]> = Clamped(pixmap.data());
|
||||
let context = canvas.get_context("2d").unwrap().unwrap().dyn_into::<CanvasRenderingContext2d>().unwrap();
|
||||
let image_data = web_sys::ImageData::new_with_u8_clamped_array_and_sh(array, pixmap_size.width(), pixmap_size.height()).expect("Failed to construct ImageData");
|
||||
|
|
|
@ -369,9 +369,10 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
|
|||
#[cfg(feature = "gpu")]
|
||||
async_node!(gpu_executor::ReadOutputBufferNode<_, _>, input: Arc<ShaderInput<WgpuExecutor>>, output: Vec<u8>, params: [&WgpuExecutor, ()]),
|
||||
#[cfg(feature = "gpu")]
|
||||
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]),
|
||||
async_node!(gpu_executor::CreateGpuSurfaceNode, input: WasmEditorApi, output: Arc<SurfaceHandle<<WgpuExecutor as GpuExecutor>::Surface<'_>>>, params: []),
|
||||
// todo!(gpu) get this to compie without saying that one type is more general than the other
|
||||
// #[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<_>,
|
||||
|
|
|
@ -21,7 +21,7 @@ impl Context {
|
|||
// `request_adapter` instantiates the general connection to the GPU
|
||||
let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions::default()).await?;
|
||||
|
||||
let limits = adapter.limits();
|
||||
let required_limits = adapter.limits();
|
||||
// `request_device` instantiates the feature specific connection to the GPU, defining some parameters,
|
||||
// `features` being the available features.
|
||||
let (device, queue) = adapter
|
||||
|
@ -29,10 +29,10 @@ impl Context {
|
|||
&wgpu::DeviceDescriptor {
|
||||
label: None,
|
||||
#[cfg(not(feature = "passthrough"))]
|
||||
features: wgpu::Features::empty(),
|
||||
required_features: wgpu::Features::empty(),
|
||||
#[cfg(feature = "passthrough")]
|
||||
features: wgpu::Features::SPIRV_SHADER_PASSTHROUGH,
|
||||
limits,
|
||||
required_features: wgpu::Features::SPIRV_SHADER_PASSTHROUGH,
|
||||
required_limits,
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
|
|
@ -124,7 +124,7 @@ async fn execute_shader<I: Pod + Send + Sync, O: Pod + Send + Sync>(device: Arc<
|
|||
// It is to WebGPU what a command buffer is to Vulkan.
|
||||
let mut encoder = device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
||||
{
|
||||
let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None });
|
||||
let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None, timestamp_writes: None });
|
||||
cpass.set_pipeline(&compute_pipeline);
|
||||
cpass.set_bind_group(0, &bind_group, &[]);
|
||||
cpass.insert_debug_marker("compute node network evaluation");
|
||||
|
|
|
@ -43,7 +43,7 @@ impl<'a, T: ApplicationIo<Executor = WgpuExecutor>> From<EditorApi<'a, T>> for &
|
|||
}
|
||||
}
|
||||
|
||||
pub type WgpuSurface = Arc<SurfaceHandle<wgpu::Surface>>;
|
||||
pub type WgpuSurface<'window> = Arc<SurfaceHandle<wgpu::Surface<'window>>>;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
|
@ -111,7 +111,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
|||
type TextureHandle = Texture;
|
||||
type TextureView = TextureView;
|
||||
type CommandBuffer = CommandBufferWrapper;
|
||||
type Surface = wgpu::Surface;
|
||||
type Surface<'window> = wgpu::Surface<'window>;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
type Window = HtmlCanvasElement;
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
|
@ -196,6 +196,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
|||
usage,
|
||||
view_formats: &[format],
|
||||
},
|
||||
wgpu::util::TextureDataOrder::LayerMajor,
|
||||
bytes.as_ref(),
|
||||
);
|
||||
match options {
|
||||
|
@ -256,7 +257,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
|||
let mut encoder = self.context.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("compute encoder") });
|
||||
{
|
||||
let dimensions = instances.get();
|
||||
let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None });
|
||||
let mut cpass = encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None, timestamp_writes: None });
|
||||
cpass.set_pipeline(&compute_pipeline);
|
||||
cpass.set_bind_group(0, &bind_group, &[]);
|
||||
cpass.insert_debug_marker("compute node network evaluation");
|
||||
|
@ -349,10 +350,12 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
|||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: true,
|
||||
store: wgpu::StoreOp::Store,
|
||||
},
|
||||
})],
|
||||
depth_stencil_attachment: None,
|
||||
timestamp_writes: None,
|
||||
occlusion_query_set: None,
|
||||
});
|
||||
|
||||
render_pass.set_pipeline(&self.render_configuration.render_pipeline);
|
||||
|
@ -430,7 +433,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
|||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fn create_surface(&self, canvas: graphene_core::WasmSurfaceHandle) -> Result<SurfaceHandle<wgpu::Surface>> {
|
||||
let surface = self.context.instance.create_surface_from_canvas(canvas.surface)?;
|
||||
let surface = self.context.instance.create_surface(wgpu::SurfaceTarget::Canvas(canvas.surface))?;
|
||||
|
||||
let surface_caps = surface.get_capabilities(&self.context.adapter);
|
||||
let surface_format = wgpu::TextureFormat::Bgra8Unorm;
|
||||
|
@ -442,6 +445,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
|||
present_mode: surface_caps.present_modes[0],
|
||||
alpha_mode: wgpu::CompositeAlphaMode::PreMultiplied,
|
||||
view_formats: vec![wgpu::TextureFormat::Bgra8UnormSrgb],
|
||||
desired_maximum_frame_latency: 2,
|
||||
};
|
||||
surface.configure(&self.context.device, &config);
|
||||
Ok(SurfaceHandle {
|
||||
|
@ -451,9 +455,9 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
|||
}
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn create_surface(&self, window: SurfaceHandle<Self::Window>) -> Result<SurfaceHandle<wgpu::Surface>> {
|
||||
let surface = unsafe { self.context.instance.create_surface(window.surface.as_ref()) }?;
|
||||
|
||||
let size = window.surface.inner_size();
|
||||
let surface = self.context.instance.create_surface(wgpu::SurfaceTarget::Window(Box::new(window.surface)))?;
|
||||
|
||||
let surface_caps = surface.get_capabilities(&self.context.adapter);
|
||||
println!("{surface_caps:?}");
|
||||
let surface_format = wgpu::TextureFormat::Bgra8Unorm;
|
||||
|
@ -465,6 +469,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
|
|||
present_mode: surface_caps.present_modes[0],
|
||||
alpha_mode: surface_caps.alpha_modes[0],
|
||||
view_formats: vec![],
|
||||
desired_maximum_frame_latency: 2,
|
||||
};
|
||||
surface.configure(&self.context.device, &config);
|
||||
self.surface_config.set(Some(config));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue