diff --git a/Cargo.lock b/Cargo.lock index 5487e27d28..9405b0b39b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,22 +815,15 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "codespan-reporting" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ + "serde", "termcolor", "unicode-width", ] -[[package]] -name = "color" -version = "0.1.0" -source = "git+https://github.com/linebender/color.git?rev=a4fa61aff6c3f292b729dc409e7832e5f0166e4a#a4fa61aff6c3f292b729dc409e7832e5f0166e4a" -dependencies = [ - "serde", -] - [[package]] name = "color" version = "0.3.1" @@ -1565,12 +1558,6 @@ dependencies = [ "rustc_version", ] -[[package]] -name = "fixedbitset" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" - [[package]] name = "fixedbitset" version = "0.5.7" @@ -1605,15 +1592,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" -[[package]] -name = "font-types" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa6a5e5a77b5f3f7f9e32879f484aa5b3632ddfbe568a16266c904a6f32cdaf" -dependencies = [ - "bytemuck", -] - [[package]] name = "font-types" version = "0.9.0" @@ -1671,7 +1649,7 @@ dependencies = [ "objc2-core-foundation", "objc2-core-text", "objc2-foundation 0.3.1", - "peniko 0.4.0", + "peniko", "read-fonts 0.29.3", "roxmltree", "smallvec", @@ -2129,9 +2107,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "glow" -version = "0.14.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51fa363f025f5c111e03f13eda21162faeacb6911fe8caa0c0349f9cf0c4483" +checksum = "c5e5ea60d70410161c8bf5da3fdfeaa1c72ed2c15f8bbb9d19fe3a4fad085f08" dependencies = [ "js-sys", "slotmap", @@ -2587,6 +2565,7 @@ dependencies = [ "bytemuck", "cfg-if", "crunchy", + "num-traits", "serde", ] @@ -3604,9 +3583,9 @@ dependencies = [ [[package]] name = "metal" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" +checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" dependencies = [ "bitflags 2.9.1", "block", @@ -3673,24 +3652,28 @@ dependencies = [ [[package]] name = "naga" -version = "23.1.0" +version = "25.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "364f94bc34f61332abebe8cad6f6cd82a5b65cff22c828d05d0968911462ca4f" +checksum = "2b977c445f26e49757f9aca3631c3b8b836942cb278d69a92e7b80d3b24da632" dependencies = [ "arrayvec", "bit-set", "bitflags 2.9.1", - "cfg_aliases 0.1.1", + "cfg_aliases 0.2.1", "codespan-reporting", + "half", + "hashbrown 0.15.4", "hexf-parse", "indexmap 2.10.0", "log", - "petgraph 0.6.5", + "num-traits", + "once_cell", + "petgraph 0.8.2", "rustc-hash 1.1.0", "spirv", - "termcolor", - "thiserror 1.0.69", - "unicode-xid", + "strum", + "thiserror 2.0.12", + "unicode-ident", ] [[package]] @@ -3884,6 +3867,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -4255,6 +4239,15 @@ dependencies = [ "libredox", ] +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + [[package]] name = "os_pipe" version = "1.2.2" @@ -4330,7 +4323,7 @@ checksum = "13e57638545cf2ba4c3e72cc5715e53b1880b829cc3dbefda3d1700c58efe723" dependencies = [ "fontique", "hashbrown 0.15.4", - "peniko 0.4.0", + "peniko", "skrifa 0.31.3", "swash", ] @@ -4361,23 +4354,13 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" -[[package]] -name = "peniko" -version = "0.2.0" -source = "git+https://github.com/linebender/peniko.git?rev=d114c62#d114c6292dbcfb03e7360692198be423168a0edd" -dependencies = [ - "color 0.1.0", - "kurbo", - "smallvec", -] - [[package]] name = "peniko" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f9529efd019889b2a205193c14ffb6e2839b54ed9d2720674f10f4b04d87ac9" dependencies = [ - "color 0.3.1", + "color", "kurbo", "smallvec", ] @@ -4434,22 +4417,24 @@ dependencies = [ [[package]] name = "petgraph" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ - "fixedbitset 0.4.2", + "fixedbitset", "indexmap 2.10.0", ] [[package]] name = "petgraph" -version = "0.7.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "54acf3a685220b533e437e264e4d932cfbdc4cc7ec0cd232ed73c08d03b8a7ca" dependencies = [ - "fixedbitset 0.5.7", + "fixedbitset", + "hashbrown 0.15.4", "indexmap 2.10.0", + "serde", ] [[package]] @@ -5165,16 +5150,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "read-fonts" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f9e8a4f503e5c8750e4cd3b32a4e090035c46374b305a15c70bad833dca05f" -dependencies = [ - "bytemuck", - "font-types 0.8.4", -] - [[package]] name = "read-fonts" version = "0.29.3" @@ -5182,7 +5157,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04ca636dac446b5664bd16c069c00a9621806895b8bb02c2dc68542b23b8f25d" dependencies = [ "bytemuck", - "font-types 0.9.0", + "font-types", ] [[package]] @@ -5192,7 +5167,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "192735ef611aac958468e670cb98432c925426f3cb71521fda202130f7388d91" dependencies = [ "bytemuck", - "font-types 0.9.0", + "font-types", ] [[package]] @@ -5914,16 +5889,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" -[[package]] -name = "skrifa" -version = "0.26.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cc1aa86c26dbb1b63875a7180aa0819709b33348eb5b1491e4321fae388179d" -dependencies = [ - "bytemuck", - "read-fonts 0.25.3", -] - [[package]] name = "skrifa" version = "0.31.3" @@ -6153,6 +6118,28 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.104", +] + [[package]] name = "subtle" version = "2.6.1" @@ -7160,12 +7147,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "untrusted" version = "0.9.0" @@ -7272,15 +7253,15 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vello" -version = "0.3.0" -source = "git+https://github.com/linebender/vello.git?rev=3275ec8#3275ec85d831180be81820de06cca29a97a757f5" +version = "0.5.0" +source = "git+https://github.com/linebender/vello.git#87cc5bee6d3a34d15017dbbb58634ddc7f33ff9b" dependencies = [ "bytemuck", "futures-intrusive", "log", - "peniko 0.2.0", + "peniko", "png", - "skrifa 0.26.6", + "skrifa 0.31.3", "static_assertions", "thiserror 2.0.12", "vello_encoding", @@ -7290,22 +7271,23 @@ dependencies = [ [[package]] name = "vello_encoding" -version = "0.3.0" -source = "git+https://github.com/linebender/vello.git?rev=3275ec8#3275ec85d831180be81820de06cca29a97a757f5" +version = "0.5.0" +source = "git+https://github.com/linebender/vello.git#87cc5bee6d3a34d15017dbbb58634ddc7f33ff9b" dependencies = [ "bytemuck", "guillotiere", - "peniko 0.2.0", - "skrifa 0.26.6", + "peniko", + "skrifa 0.31.3", "smallvec", ] [[package]] name = "vello_shaders" -version = "0.3.0" -source = "git+https://github.com/linebender/vello.git?rev=3275ec8#3275ec85d831180be81820de06cca29a97a757f5" +version = "0.5.0" +source = "git+https://github.com/linebender/vello.git#87cc5bee6d3a34d15017dbbb58634ddc7f33ff9b" dependencies = [ "bytemuck", + "log", "naga", "thiserror 2.0.12", "vello_encoding", @@ -7703,17 +7685,20 @@ checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" [[package]] name = "wgpu" -version = "23.0.1" +version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80f70000db37c469ea9d67defdc13024ddf9a5f1b89cb2941b812ad7cde1735a" +checksum = "ec8fb398f119472be4d80bc3647339f56eb63b2a331f6a3d16e25d8144197dd9" dependencies = [ "arrayvec", - "cfg_aliases 0.1.1", + "bitflags 2.9.1", + "cfg_aliases 0.2.1", "document-features", + "hashbrown 0.15.4", "js-sys", "log", "naga", "parking_lot", + "portable-atomic", "profiling", "raw-window-handle", "smallvec", @@ -7728,30 +7713,63 @@ dependencies = [ [[package]] name = "wgpu-core" -version = "23.0.1" +version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d63c3c478de8e7e01786479919c8769f62a22eec16788d8c2ac77ce2c132778a" +checksum = "f7b882196f8368511d613c6aeec80655160db6646aebddf8328879a88d54e500" dependencies = [ "arrayvec", + "bit-set", "bit-vec", "bitflags 2.9.1", "bytemuck", - "cfg_aliases 0.1.1", + "cfg_aliases 0.2.1", "document-features", + "hashbrown 0.15.4", "indexmap 2.10.0", "log", "naga", "once_cell", "parking_lot", + "portable-atomic", "profiling", "raw-window-handle", "rustc-hash 1.1.0", "smallvec", - "thiserror 1.0.69", + "thiserror 2.0.12", + "wgpu-core-deps-apple", + "wgpu-core-deps-emscripten", + "wgpu-core-deps-windows-linux-android", "wgpu-hal", "wgpu-types", ] +[[package]] +name = "wgpu-core-deps-apple" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfd488b3239b6b7b185c3b045c39ca6bf8af34467a4c5de4e0b1a564135d093d" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-emscripten" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f09ad7aceb3818e52539acc679f049d3475775586f3f4e311c30165cf2c00445" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-windows-linux-android" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cba5fb5f7f9c98baa7c889d444f63ace25574833df56f5b817985f641af58e46" +dependencies = [ + "wgpu-hal", +] + [[package]] name = "wgpu-executor" version = "0.1.0" @@ -7772,9 +7790,9 @@ dependencies = [ [[package]] name = "wgpu-hal" -version = "23.0.1" +version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89364b8a0b211adc7b16aeaf1bd5ad4a919c1154b44c9ce27838213ba05fd821" +checksum = "f968767fe4d3d33747bbd1473ccd55bf0f6451f55d733b5597e67b5deab4ad17" dependencies = [ "android_system_properties", "arrayvec", @@ -7783,13 +7801,15 @@ dependencies = [ "bitflags 2.9.1", "block", "bytemuck", - "cfg_aliases 0.1.1", + "cfg-if", + "cfg_aliases 0.2.1", "core-graphics-types 0.1.3", "glow", "glutin_wgl_sys", "gpu-alloc", "gpu-allocator", "gpu-descriptor", + "hashbrown 0.15.4", "js-sys", "khronos-egl", "libc", @@ -7799,15 +7819,15 @@ dependencies = [ "naga", "ndk-sys 0.5.0+25.2.9519653", "objc", - "once_cell", + "ordered-float", "parking_lot", + "portable-atomic", "profiling", "range-alloc", "raw-window-handle", "renderdoc-sys", - "rustc-hash 1.1.0", "smallvec", - "thiserror 1.0.69", + "thiserror 2.0.12", "wasm-bindgen", "web-sys", "wgpu-types", @@ -7817,12 +7837,15 @@ dependencies = [ [[package]] name = "wgpu-types" -version = "23.0.0" +version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "610f6ff27778148c31093f3b03abc4840f9636d58d597ca2f5977433acfe0068" +checksum = "2aa49460c2a8ee8edba3fca54325540d904dd85b2e086ada762767e17d06e8bc" dependencies = [ "bitflags 2.9.1", + "bytemuck", "js-sys", + "log", + "thiserror 2.0.12", "web-sys", ] diff --git a/Cargo.toml b/Cargo.toml index 35c5e7040d..2f21fd39ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,7 +83,7 @@ axum = "0.8" chrono = "0.4" ron = "0.8" fastnoise-lite = "1.1" -wgpu = { version = "23", features = [ +wgpu = { version = "25.0.2", features = [ # 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 "fragile-send-sync-non-atomic-wasm", "spirv", @@ -114,7 +114,7 @@ web-sys = { version = "=0.3.77", features = [ winit = "0.29" url = "2.5" tokio = { version = "1.29", features = ["fs", "macros", "io-std", "rt"] } -vello = { git = "https://github.com/linebender/vello.git", rev = "3275ec8" } # TODO switch back to stable when a release is made +vello = { git = "https://github.com/linebender/vello.git" } # TODO switch back to stable when a release is made resvg = "0.44" usvg = "0.44" rand = { version = "0.9", default-features = false, features = ["std_rng"] } diff --git a/node-graph/graphene-cli/src/main.rs b/node-graph/graphene-cli/src/main.rs index af535b7363..049878cc3b 100644 --- a/node-graph/graphene-cli/src/main.rs +++ b/node-graph/graphene-cli/src/main.rs @@ -111,7 +111,7 @@ async fn main() -> Result<(), Box> { std::thread::spawn(move || { loop { std::thread::sleep(std::time::Duration::from_nanos(10)); - device.poll(wgpu::Maintain::Poll); + device.poll(wgpu::PollType::Poll).unwrap(); } }); let executor = create_executor(proto_graph)?; @@ -123,7 +123,7 @@ async fn main() -> Result<(), Box> { println!("{:?}", result); break; } - std::thread::sleep(std::time::Duration::from_millis(16)); + tokio::time::sleep(std::time::Duration::from_millis(16)).await; } } } diff --git a/node-graph/gstd/src/wasm_application_io.rs b/node-graph/gstd/src/wasm_application_io.rs index 92c2f2f6fb..4ab9e5093b 100644 --- a/node-graph/gstd/src/wasm_application_io.rs +++ b/node-graph/gstd/src/wasm_application_io.rs @@ -220,7 +220,7 @@ async fn render_canvas( if !data.contains_artboard() && !render_config.hide_artboards { background = Color::WHITE; } - exec.render_vello_scene(&scene, &surface_handle, footprint.resolution.x, footprint.resolution.y, &context, background) + exec.render_vello_scene(&scene, &surface_handle, footprint.resolution, &context, background) .await .expect("Failed to render Vello scene"); diff --git a/node-graph/gsvg-renderer/src/renderer.rs b/node-graph/gsvg-renderer/src/renderer.rs index 216a9b666f..aba185c951 100644 --- a/node-graph/gsvg-renderer/src/renderer.rs +++ b/node-graph/gsvg-renderer/src/renderer.rs @@ -145,7 +145,7 @@ impl Default for SvgRender { #[derive(Clone, Debug, Default)] pub struct RenderContext { #[cfg(feature = "vello")] - pub resource_overrides: HashMap>, + pub resource_overrides: HashMap, } /// Static state used whilst rendering @@ -983,7 +983,7 @@ impl GraphicElementRendered for RasterDataTable { if image.data.is_empty() { return; } - let image = peniko::Image::new(image.to_flat_u8().0.into(), peniko::Format::Rgba8, image.width, image.height).with_extend(peniko::Extend::Repeat); + let image = peniko::Image::new(image.to_flat_u8().0.into(), peniko::ImageFormat::Rgba8, image.width, image.height).with_extend(peniko::Extend::Repeat); let transform = transform * *instance.transform * DAffine2::from_scale(1. / DVec2::new(image.width as f64, image.height as f64)); scene.draw_image(&image, kurbo::Affine::new(transform.to_cols_array())); @@ -1035,10 +1035,10 @@ impl GraphicElementRendered for RasterDataTable { }; for instance in self.instance_ref_iter() { - let image = peniko::Image::new(vec![].into(), peniko::Format::Rgba8, instance.instance.data().width(), instance.instance.data().height()).with_extend(peniko::Extend::Repeat); + let image = peniko::Image::new(vec![].into(), peniko::ImageFormat::Rgba8, instance.instance.data().width(), instance.instance.data().height()).with_extend(peniko::Extend::Repeat); let id = image.data.id(); - context.resource_overrides.insert(id, instance.instance.data_owned()); + context.resource_overrides.insert(id, instance.instance.data().clone()); render_stuff(image, *instance.transform, *instance.alpha_blending); } diff --git a/node-graph/wgpu-executor/src/context.rs b/node-graph/wgpu-executor/src/context.rs index 7d0d81859c..a8ffd7b17f 100644 --- a/node-graph/wgpu-executor/src/context.rs +++ b/node-graph/wgpu-executor/src/context.rs @@ -16,7 +16,7 @@ impl Context { backends: wgpu::Backends::all(), ..Default::default() }; - let instance = Instance::new(instance_descriptor); + let instance = Instance::new(&instance_descriptor); let adapter_options = wgpu::RequestAdapterOptions { power_preference: wgpu::PowerPreference::HighPerformance, @@ -24,26 +24,24 @@ impl Context { force_fallback_adapter: false, }; // `request_adapter` instantiates the general connection to the GPU - let adapter = instance.request_adapter(&adapter_options).await?; + let adapter = instance.request_adapter(&adapter_options).await.ok()?; 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 - .request_device( - &wgpu::DeviceDescriptor { - label: None, - // #[cfg(not(feature = "passthrough"))] - required_features: wgpu::Features::empty(), - // Currently disabled because not all backend support passthrough. - // TODO: reenable only when vulkan adapter is available - // #[cfg(feature = "passthrough")] - // required_features: wgpu::Features::SPIRV_SHADER_PASSTHROUGH, - required_limits, - memory_hints: Default::default(), - }, - None, - ) + .request_device(&wgpu::DeviceDescriptor { + label: None, + // #[cfg(not(feature = "passthrough"))] + required_features: wgpu::Features::empty(), + // Currently disabled because not all backend support passthrough. + // TODO: reenable only when vulkan adapter is available + // #[cfg(feature = "passthrough")] + // required_features: wgpu::Features::SPIRV_SHADER_PASSTHROUGH, + required_limits, + memory_hints: Default::default(), + trace: wgpu::Trace::Off, + }) .await .unwrap(); diff --git a/node-graph/wgpu-executor/src/lib.rs b/node-graph/wgpu-executor/src/lib.rs index d65c24814a..c0113a45c6 100644 --- a/node-graph/wgpu-executor/src/lib.rs +++ b/node-graph/wgpu-executor/src/lib.rs @@ -3,18 +3,20 @@ mod context; use anyhow::Result; pub use context::Context; use dyn_any::StaticType; +use futures::lock::Mutex; use glam::UVec2; -use graphene_application_io::{ApplicationIo, EditorApi, SurfaceHandle}; +use graphene_application_io::{ApplicationIo, EditorApi, SurfaceHandle, SurfaceId}; use graphene_core::{Color, Ctx}; pub use graphene_svg_renderer::RenderContext; use std::sync::Arc; use vello::{AaConfig, AaSupport, RenderParams, Renderer, RendererOptions, Scene}; +use wgpu::util::TextureBlitter; use wgpu::{Origin3d, SurfaceConfiguration, TextureAspect}; #[derive(dyn_any::DynAny)] pub struct WgpuExecutor { pub context: Context, - vello_renderer: futures::lock::Mutex, + vello_renderer: Mutex, } impl std::fmt::Debug for WgpuExecutor { @@ -32,16 +34,17 @@ impl<'a, T: ApplicationIo> From<&'a EditorApi> for & pub type WgpuSurface = Arc>; pub type WgpuWindow = Arc>; -impl graphene_application_io::Size for Surface { - fn size(&self) -> UVec2 { - self.resolution - } -} - pub struct Surface { pub inner: wgpu::Surface<'static>, - resolution: UVec2, + pub target_texture: Mutex>, + pub blitter: TextureBlitter, } + +pub struct TargetTexture { + view: wgpu::TextureView, + size: UVec2, +} + #[cfg(target_arch = "wasm32")] pub type Window = web_sys::HtmlCanvasElement; #[cfg(not(target_arch = "wasm32"))] @@ -51,52 +54,88 @@ unsafe impl StaticType for Surface { type Static = Surface; } +const VELLO_SURFACE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8Unorm; + impl WgpuExecutor { - pub async fn render_vello_scene(&self, scene: &Scene, surface: &WgpuSurface, width: u32, height: u32, context: &RenderContext, background: Color) -> Result<()> { - let surface = &surface.surface.inner; - let surface_caps = surface.get_capabilities(&self.context.adapter); - surface.configure( + pub async fn render_vello_scene(&self, scene: &Scene, surface: &WgpuSurface, size: UVec2, context: &RenderContext, background: Color) -> Result<()> { + let mut guard = surface.surface.target_texture.lock().await; + let target_texture = if let Some(target_texture) = &*guard + && target_texture.size == size + { + target_texture + } else { + let texture = self.context.device.create_texture(&wgpu::TextureDescriptor { + label: None, + size: wgpu::Extent3d { + width: size.x, + height: size.y, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: wgpu::TextureDimension::D2, + usage: wgpu::TextureUsages::STORAGE_BINDING | wgpu::TextureUsages::TEXTURE_BINDING, + format: VELLO_SURFACE_FORMAT, + view_formats: &[], + }); + let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); + *guard = Some(TargetTexture { size, view }); + guard.as_ref().unwrap() + }; + + let surface_inner = &surface.surface.inner; + let surface_caps = surface_inner.get_capabilities(&self.context.adapter); + surface_inner.configure( &self.context.device, &SurfaceConfiguration { usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::STORAGE_BINDING, - format: wgpu::TextureFormat::Rgba8Unorm, - width, - height, + format: VELLO_SURFACE_FORMAT, + width: size.x, + height: size.y, present_mode: surface_caps.present_modes[0], alpha_mode: wgpu::CompositeAlphaMode::Opaque, view_formats: vec![], desired_maximum_frame_latency: 2, }, ); - let surface_texture = surface.get_current_texture()?; let [r, g, b, _] = background.to_rgba8_srgb(); let render_params = RenderParams { // We are using an explicit opaque color here to eliminate the alpha premultiplication step // which would be required to support a transparent webgpu canvas base_color: vello::peniko::Color::from_rgba8(r, g, b, 0xff), - width, - height, + width: size.x, + height: size.y, antialiasing_method: AaConfig::Msaa16, }; { let mut renderer = self.vello_renderer.lock().await; for (id, texture) in context.resource_overrides.iter() { - let texture_view = wgpu::ImageCopyTextureBase { - texture: texture.clone(), + let texture = texture.clone(); + let texture_view = wgpu::TexelCopyTextureInfoBase { + texture, mip_level: 0, origin: Origin3d::ZERO, aspect: TextureAspect::All, }; renderer.override_image( - &vello::peniko::Image::new(vello::peniko::Blob::from_raw_parts(Arc::new(vec![]), *id), vello::peniko::Format::Rgba8, 0, 0), + &vello::peniko::Image::new(vello::peniko::Blob::from_raw_parts(Arc::new(vec![]), *id), vello::peniko::ImageFormat::Rgba8, 0, 0), Some(texture_view), ); } - renderer.render_to_surface(&self.context.device, &self.context.queue, scene, &surface_texture, &render_params).unwrap(); + renderer.render_to_texture(&self.context.device, &self.context.queue, scene, &target_texture.view, &render_params)?; } + let surface_texture = surface_inner.get_current_texture()?; + let mut encoder = self.context.device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: Some("Surface Blit") }); + surface.surface.blitter.copy( + &self.context.device, + &mut encoder, + &target_texture.view, + &surface_texture.texture.create_view(&wgpu::TextureViewDescriptor::default()), + ); + self.context.queue.submit([encoder.finish()]); surface_texture.present(); Ok(()) @@ -105,24 +144,23 @@ impl WgpuExecutor { #[cfg(target_arch = "wasm32")] pub fn create_surface(&self, canvas: graphene_application_io::WasmSurfaceHandle) -> Result> { let surface = self.context.instance.create_surface(wgpu::SurfaceTarget::Canvas(canvas.surface))?; - - Ok(SurfaceHandle { - window_id: canvas.window_id, - surface: Surface { - inner: surface, - resolution: UVec2::ZERO, - }, - }) + self.create_surface_inner(surface, canvas.window_id) } #[cfg(not(target_arch = "wasm32"))] pub fn create_surface(&self, window: SurfaceHandle) -> Result> { - let size = window.surface.inner_size(); - let resolution = UVec2::new(size.width, size.height); let surface = self.context.instance.create_surface(wgpu::SurfaceTarget::Window(Box::new(window.surface)))?; + self.create_surface_inner(surface, window.window_id) + } + pub fn create_surface_inner(&self, surface: wgpu::Surface<'static>, window_id: SurfaceId) -> Result> { + let blitter = TextureBlitter::new(&self.context.device, VELLO_SURFACE_FORMAT); Ok(SurfaceHandle { - window_id: window.window_id, - surface: Surface { inner: surface, resolution }, + window_id, + surface: Surface { + inner: surface, + target_texture: Mutex::new(None), + blitter, + }, }) } } @@ -134,7 +172,8 @@ impl WgpuExecutor { let vello_renderer = Renderer::new( &context.device, RendererOptions { - surface_format: Some(wgpu::TextureFormat::Rgba8Unorm), + // surface_format: Some(wgpu::TextureFormat::Rgba8Unorm), + pipeline_cache: None, use_cpu: false, antialiasing_support: AaSupport::all(), num_init_threads: std::num::NonZeroUsize::new(1),