Skip to content

Commit b3418f0

Browse files
committed
Render the Rasterize node with Vello
1 parent 9f67c9c commit b3418f0

9 files changed

Lines changed: 85 additions & 87 deletions

File tree

‎Cargo.lock‎

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
655655
description: Cow::Borrowed("Loads an image from a given URL."),
656656
inspector: None,
657657
},
658-
#[cfg(all(feature = "gpu", target_family = "wasm"))]
658+
#[cfg(feature = "gpu")]
659659
DocumentNodeDefinition {
660660
identifier: "Rasterize",
661661
category: "Raster",

‎editor/src/messages/portfolio/document_migration.rs‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3525,7 +3525,6 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
35253525
graphene_std::raster_nodes::std_nodes::image::IDENTIFIER,
35263526
graphene_std::platform_application_io::bytes_to_image::IDENTIFIER,
35273527
graphene_std::platform_application_io::image_to_bytes::IDENTIFIER,
3528-
#[cfg(target_family = "wasm")]
35293528
graphene_std::platform_application_io::rasterize::IDENTIFIER,
35303529
]
35313530
};

‎node-graph/interpreted-executor/src/node_registry.rs‎

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ use graphene_std::any::DynAnyNode;
1010
use graphene_std::brush::Stroke;
1111
use graphene_std::gradient::Gradient;
1212
use graphene_std::list::{AttributeValueDyn, Bundle, Item, List, ListDyn, NodeIdPath};
13-
#[cfg(target_family = "wasm")]
14-
use graphene_std::platform_application_io::canvas_utils::CanvasHandle;
1513
#[cfg(feature = "gpu")]
1614
use graphene_std::raster::GPU;
1715
use graphene_std::raster::color::Color;
@@ -89,8 +87,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
8987
async_node!(graphene_core::context_modification::ContextModificationNode<_, _>, input: Context, fn_params: [Context => Item<RenderOutput>, Context => Item<graphene_std::ContextModification>]),
9088
async_node!(graphene_core::context_modification::ContextModificationNode<_, _>, input: Context, fn_params: [Context => Item<AttributeValueDyn>, Context => Item<graphene_std::ContextModification>]),
9189
async_node!(graphene_core::context_modification::ContextModificationNode<_, _>, input: Context, fn_params: [Context => ListDyn, Context => Item<graphene_std::ContextModification>]),
92-
#[cfg(target_family = "wasm")]
93-
async_node!(graphene_core::context_modification::ContextModificationNode<_, _>, input: Context, fn_params: [Context => Item<CanvasHandle>, Context => Item<graphene_std::ContextModification>]),
90+
async_node!(graphene_core::context_modification::ContextModificationNode<_, _>, input: Context, fn_params: [Context => Item<wgpu_executor::VelloCanvasHandle>, Context => Item<graphene_std::ContextModification>]),
9491
async_node!(graphene_core::context_modification::ContextModificationNode<_, _>, input: Context, fn_params: [Context => Item<Arc<PlatformEditorApi>>, Context => Item<graphene_std::ContextModification>]),
9592
async_node!(graphene_core::context_modification::ContextModificationNode<_, _>, input: Context, fn_params: [Context => Item<graphene_std::RuntimeHandle>, Context => Item<graphene_std::ContextModification>]),
9693
async_node!(graphene_core::context_modification::ContextModificationNode<_, _>, input: Context, fn_params: [Context => Item<graphene_std::SourceId>, Context => Item<graphene_std::ContextModification>]),
@@ -138,8 +135,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
138135
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => Item<BlendMode>]),
139136
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => Item<AttributeValueDyn>]),
140137
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => ListDyn]),
141-
#[cfg(target_family = "wasm")]
142-
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => Item<CanvasHandle>]),
138+
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => Item<wgpu_executor::VelloCanvasHandle>]),
143139
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => Item<RenderOutput>]),
144140
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => Item<Arc<PlatformEditorApi>>]),
145141
async_node!(graphene_core::memo::MemoizeNode<_, _>, input: Context, fn_params: [Context => Item<graphene_std::RuntimeHandle>]),

‎node-graph/libraries/wgpu-executor/src/lib.rs‎

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ pub mod texture_conversion;
77
mod vello_render;
88

99
use crate::texture_cache::TextureCache;
10-
pub use crate::vello_render::VelloCanvas;
1110
use crate::vello_render::VelloRenderer;
11+
pub use crate::vello_render::{VelloCanvas, VelloCanvasHandle};
1212
use anyhow::Result;
1313
use glam::{DAffine2, UVec2};
1414
use graphene_application_io::{ApplicationIo, EditorApi};
@@ -74,11 +74,21 @@ impl<'a, T: ApplicationIo<Executor = WgpuExecutor>> From<&'a EditorApi<T>> for &
7474
impl WgpuExecutor {
7575
/// An empty document scene of `size` to draw into, with its content placed by `view`.
7676
pub fn vello_scene(&self, size: UVec2, view: DAffine2) -> Result<VelloSceneBuilder> {
77-
let view = vello_gpu::kurbo::Affine::new(view.to_cols_array());
7877
let mut canvas = self.inner.document_canvas.lock().unwrap_or_else(PoisonError::into_inner);
78+
self.vello_scene_on_canvas(&mut canvas, size, view)
79+
}
80+
81+
/// An empty scene like [`Self::vello_scene`], but on a canvas the caller owns.
82+
pub fn vello_scene_on_canvas(&self, canvas: &mut VelloCanvas, size: UVec2, view: DAffine2) -> Result<VelloSceneBuilder> {
83+
let view = vello_gpu::kurbo::Affine::new(view.to_cols_array());
7984
canvas.scene(&self.context().device, size, view)
8085
}
8186

87+
/// Renders a scene on a canvas the caller owns into a new [`RASTER_FORMAT`] texture of the scene's size.
88+
pub fn render_vello_raster_on_canvas(&self, canvas: &mut VelloCanvas, scene: VelloSceneBuilder) -> Result<Texture> {
89+
self.render_vello_scene_with_format(canvas, scene, RASTER_FORMAT)
90+
}
91+
8292
/// Renders a document scene into a new texture of the scene's size with straight alpha.
8393
pub fn render_vello_scene(&self, scene: VelloSceneBuilder) -> Result<Texture> {
8494
let mut canvas = self.inner.document_canvas.lock().unwrap_or_else(PoisonError::into_inner);
@@ -87,7 +97,11 @@ impl WgpuExecutor {
8797

8898
/// Renders a scene like [`Self::render_vello_scene`], but on a canvas the caller owns.
8999
pub fn render_vello_scene_on_canvas(&self, canvas: &mut VelloCanvas, scene: VelloSceneBuilder) -> Result<Texture> {
90-
let texture = self.request_texture(UVec2::new(scene.width() as u32, scene.height() as u32));
100+
self.render_vello_scene_with_format(canvas, scene, wgpu::TextureFormat::Rgba8Unorm)
101+
}
102+
103+
fn render_vello_scene_with_format(&self, canvas: &mut VelloCanvas, scene: VelloSceneBuilder, format: wgpu::TextureFormat) -> Result<Texture> {
104+
let texture = self.request_texture_with_format(UVec2::new(scene.width() as u32, scene.height() as u32), format);
91105

92106
let queue = self.context().queue.lock();
93107
self.inner.vello_renderer.render(canvas, &self.context().device, &queue, scene, &texture);

‎node-graph/libraries/wgpu-executor/src/vello_alpha.wgsl‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ fn unpremultiply(@builtin(position) position: vec4<f32>) -> @location(0) vec4<f3
2929
return vec4<f32>(color.rgb / color.a, color.a);
3030
}
3131

32+
@fragment
33+
fn unpremultiply_to_linear(@builtin(position) position: vec4<f32>) -> @location(0) vec4<f32> {
34+
let color = textureLoad(source, vec2<i32>(position.xy), 0);
35+
if color.a <= 0. {
36+
return vec4<f32>(0.);
37+
}
38+
39+
return vec4<f32>(srgb_to_linear(color.rgb / color.a), color.a);
40+
}
41+
3242
@fragment
3343
fn premultiply(@builtin(position) position: vec4<f32>) -> @location(0) vec4<f32> {
3444
var color = textureLoad(source, vec2<i32>(position.xy), 0);
@@ -44,3 +54,9 @@ fn linear_to_srgb(linear: vec3<f32>) -> vec3<f32> {
4454
let high = 1.055 * pow(linear, vec3<f32>(1. / 2.4)) - 0.055;
4555
return select(high, low, linear <= vec3<f32>(0.0031308));
4656
}
57+
58+
fn srgb_to_linear(srgb: vec3<f32>) -> vec3<f32> {
59+
let low = srgb / 12.92;
60+
let high = pow((srgb + 0.055) / 1.055, vec3<f32>(2.4));
61+
return select(high, low, srgb <= vec3<f32>(0.04045));
62+
}

‎node-graph/libraries/wgpu-executor/src/vello_render.rs‎

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use glam::UVec2;
22
use rendering::vello_scene_builder::{SceneImage, VelloSceneBuilder, image_downscale_factor, image_texture_size};
33
use std::collections::HashMap;
4-
use std::sync::{Mutex, PoisonError};
4+
use std::sync::{Arc, Mutex, PoisonError};
55
use vello_gpu::kurbo::Affine;
66
use vello_gpu::peniko;
77
use vello_gpu::{ClearSettings, RenderSize, RenderTargetConfig, Renderer, Resources, TargetInit, TextureBindings, TextureId};
@@ -29,6 +29,16 @@ pub struct VelloCanvas {
2929
images: ImageTextures,
3030
}
3131

32+
/// A [`VelloCanvas`] kept between the evaluations of the node that holds it.
33+
#[derive(Clone, Default, dyn_any::DynAny)]
34+
pub struct VelloCanvasHandle(Arc<Mutex<VelloCanvas>>);
35+
36+
impl VelloCanvasHandle {
37+
pub fn lock(&self) -> std::sync::MutexGuard<'_, VelloCanvas> {
38+
self.0.lock().unwrap_or_else(PoisonError::into_inner)
39+
}
40+
}
41+
3242
impl VelloCanvas {
3343
/// An empty scene of `size` to draw into, with its content placed by `view`.
3444
pub(crate) fn scene(&mut self, device: &wgpu::Device, size: UVec2, view: Affine) -> anyhow::Result<VelloSceneBuilder> {
@@ -56,7 +66,7 @@ impl VelloRenderer {
5666
}
5767
}
5868

59-
/// Renders `scene` on `canvas` into `target` (an `Rgba8Unorm` texture of the scene's size with straight alpha).
69+
/// Renders `scene` on `canvas` into `target`, a texture of the scene's size with straight alpha that is either `Rgba8Unorm` holding sRGB values or [`crate::RASTER_FORMAT`] holding linear-light values.
6070
pub(crate) fn render(&self, canvas: &mut VelloCanvas, device: &wgpu::Device, queue: &wgpu::Queue, scene: VelloSceneBuilder, target: &wgpu::Texture) {
6171
let (width, height) = (scene.width(), scene.height());
6272
let max_texture_size = scene.max_texture_size();
@@ -110,7 +120,7 @@ impl VelloRenderer {
110120
// A failed render leaves its area transparent rather than taking down the editor
111121
let target_view = target.create_view(&wgpu::TextureViewDescriptor::default());
112122
match rendered {
113-
Ok(()) => self.alpha_conversion.unpremultiply(device, &mut encoder, &premultiplied_view, &target_view),
123+
Ok(()) => self.alpha_conversion.unpremultiply(device, &mut encoder, &premultiplied_view, &target_view, target.format()),
114124
Err(error) => {
115125
log::error!("Vello GPU failed to render: {error}");
116126
clear_texture(&mut encoder, &target_view);
@@ -328,6 +338,8 @@ fn create_texture(device: &wgpu::Device, label: &str, size: UVec2, usage: wgpu::
328338
struct AlphaConversion {
329339
bind_group_layout: wgpu::BindGroupLayout,
330340
unpremultiply_pipeline: wgpu::RenderPipeline,
341+
/// Unpremultiplies into a linear-light [`crate::RASTER_FORMAT`] target.
342+
unpremultiply_to_linear_pipeline: wgpu::RenderPipeline,
331343
premultiply_pipeline: wgpu::RenderPipeline,
332344
/// The parameters for a source whose format stores linear values.
333345
linear_source_parameters: wgpu::Buffer,
@@ -372,7 +384,7 @@ impl AlphaConversion {
372384
immediate_size: 0,
373385
});
374386

375-
let create_pipeline = |label: &str, entry_point: &str| {
387+
let create_pipeline = |label: &str, entry_point: &str, format: wgpu::TextureFormat| {
376388
device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
377389
label: Some(label),
378390
layout: Some(&pipeline_layout),
@@ -387,7 +399,7 @@ impl AlphaConversion {
387399
entry_point: Some(entry_point),
388400
compilation_options: Default::default(),
389401
targets: &[Some(wgpu::ColorTargetState {
390-
format: TEXTURE_FORMAT,
402+
format,
391403
blend: None,
392404
write_mask: wgpu::ColorWrites::ALL,
393405
})],
@@ -412,16 +424,22 @@ impl AlphaConversion {
412424
};
413425

414426
Self {
415-
unpremultiply_pipeline: create_pipeline("vello_unpremultiply_pipeline", "unpremultiply"),
416-
premultiply_pipeline: create_pipeline("vello_premultiply_pipeline", "premultiply"),
427+
unpremultiply_pipeline: create_pipeline("vello_unpremultiply_pipeline", "unpremultiply", TEXTURE_FORMAT),
428+
unpremultiply_to_linear_pipeline: create_pipeline("vello_unpremultiply_to_linear_pipeline", "unpremultiply_to_linear", crate::RASTER_FORMAT),
429+
premultiply_pipeline: create_pipeline("vello_premultiply_pipeline", "premultiply", TEXTURE_FORMAT),
417430
linear_source_parameters: create_parameters("vello_alpha_linear_source", 0),
418431
srgb_source_parameters: create_parameters("vello_alpha_srgb_source", 1),
419432
bind_group_layout,
420433
}
421434
}
422435

423-
fn unpremultiply(&self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, source: &wgpu::TextureView, target: &wgpu::TextureView) {
424-
self.run(device, encoder, &self.unpremultiply_pipeline, &self.linear_source_parameters, source, target);
436+
fn unpremultiply(&self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, source: &wgpu::TextureView, target: &wgpu::TextureView, target_format: wgpu::TextureFormat) {
437+
let pipeline = if target_format == crate::RASTER_FORMAT {
438+
&self.unpremultiply_to_linear_pipeline
439+
} else {
440+
&self.unpremultiply_pipeline
441+
};
442+
self.run(device, encoder, pipeline, &self.linear_source_parameters, source, target);
425443
}
426444

427445
fn premultiply(&self, device: &wgpu::Device, encoder: &mut wgpu::CommandEncoder, source: &wgpu::TextureView, source_is_srgb: bool, target: &wgpu::TextureView) {

‎node-graph/nodes/gstd/Cargo.toml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ glam = { workspace = true }
6565
node-macro = { workspace = true }
6666
reqwest = { workspace = true }
6767
image = { workspace = true }
68-
base64 = { workspace = true }
6968
wgpu = { workspace = true }
7069
bytemuck = { workspace = true }
7170

‎node-graph/nodes/gstd/src/platform_application_io.rs‎

Lines changed: 22 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
1-
#[cfg(target_family = "wasm")]
2-
use base64::Engine;
3-
#[cfg(target_family = "wasm")]
4-
use canvas_utils::{Canvas, CanvasHandle};
1+
use ::wgpu_executor::VelloCanvasHandle;
52
use core_types::color::SRGBA8;
63
use core_types::list::Item;
7-
#[cfg(target_family = "wasm")]
84
use core_types::list::List;
9-
#[cfg(target_family = "wasm")]
105
use core_types::math::bbox::Bbox;
116
use core_types::ops::{Convert, ConvertAsync};
127
use core_types::transform::Footprint;
13-
#[cfg(target_family = "wasm")]
14-
use core_types::{ATTR_EDITOR_MERGED_LAYERS, ATTR_TRANSFORM};
15-
use core_types::{Ctx, Interrupt, NodeError};
8+
use core_types::{ATTR_EDITOR_MERGED_LAYERS, ATTR_TRANSFORM, Ctx, Interrupt, NodeError};
9+
use glam::DAffine2;
1610
pub use graph_craft::application_io::resource::{Resource, ResourceHash};
1711
pub use graph_craft::application_io::*;
1812
pub use graph_craft::document::value::RenderOutputType;
1913
#[cfg(target_family = "wasm")]
2014
pub use graphene_canvas_utils as canvas_utils;
21-
#[cfg(target_family = "wasm")]
2215
use graphic_types::Graphic;
2316
use graphic_types::raster_types::Image;
2417
use graphic_types::raster_types::{CPU, GPU, Raster, Storage};
2518
use raster_nodes::raster_kernel::raster_kernel_pipeline;
26-
#[cfg(target_family = "wasm")]
27-
use rendering::{Render, RenderParams, RenderSvgSegmentList, SvgRender};
19+
use rendering::{Render, RenderParams};
2820
use std::sync::Arc;
2921

3022
fn parse_headers(headers: &str) -> reqwest::header::HeaderMap {
@@ -182,85 +174,50 @@ fn bytes_to_image(_: impl Ctx, data: Item<Resource>, #[scope(raster_kernel_pipel
182174
Ok(Item::new_from_element(Raster::new_cpu(image).convert(Footprint::DEFAULT, executor)))
183175
}
184176

185-
#[cfg(target_family = "wasm")]
186177
#[node_macro::node(category(""))]
187-
fn create_canvas(_: impl Ctx) -> Item<CanvasHandle> {
188-
Item::new_from_element(CanvasHandle::new())
178+
fn create_canvas(_: impl Ctx) -> Item<VelloCanvasHandle> {
179+
Item::new_from_element(VelloCanvasHandle::default())
189180
}
190181

191182
/// Renders a view of the input graphic within an area defined by the *Footprint*.
192-
#[cfg(target_family = "wasm")]
193-
#[node_macro::node(category(""), placeholder = pending_raster)]
194-
async fn rasterize(
183+
#[node_macro::node(category(""))]
184+
fn rasterize(
195185
_: impl Ctx,
196186
data: List<Graphic>,
197187
footprint: Item<Footprint>,
198-
canvas: Item<CanvasHandle>,
188+
canvas: Item<VelloCanvasHandle>,
199189
#[scope(raster_kernel_pipeline::IDENTIFIER)] pipeline: Item<::wgpu_executor::WgpuPipelineCache>,
200-
) -> Result<List<Raster<GPU>>, NodeError> {
201-
let mut data = data;
202-
let mut canvas = canvas.into_element();
203-
use glam::{DAffine2, DVec2};
204-
190+
) -> Result<List<Raster<GPU>>, Interrupt> {
205191
let footprint = footprint.into_element();
192+
let resolution = footprint.resolution;
206193

207-
if footprint.transform.matrix2.determinant() == 0. {
194+
if footprint.transform.matrix2.determinant() == 0. || resolution.x == 0 || resolution.y == 0 {
208195
log::trace!("Invalid footprint received for rasterization");
209196
return Ok(List::new());
210197
}
211198

212-
// Snapshot the input as a List<Graphic> so the renderer can recurse into the original child layers
213-
// when collecting metadata, exposing their click targets to editor tools (same mechanism as Boolean Operation).
214-
let upstream_graphic_list = data.clone();
215-
216-
let mut render = SvgRender::new();
217199
let aabb = Bbox::from_transform(footprint.transform).to_axis_aligned_bbox();
218-
let size = aabb.size();
219-
let resolution = footprint.resolution;
200+
let view = DAffine2::from_scale(resolution.as_dvec2() / aabb.size()) * DAffine2::from_translation(-aabb.start);
220201
let render_params = RenderParams {
221-
footprint,
202+
footprint: Footprint { transform: view, ..footprint },
203+
render_output_type: rendering::RenderOutputType::Vello,
222204
for_export: true,
223205
..Default::default()
224206
};
225207

226-
for transform in data.iter_attribute_values_mut_or_default::<DAffine2>(ATTR_TRANSFORM) {
227-
*transform = DAffine2::from_translation(-aabb.start) * *transform;
228-
}
229-
data.render_svg(&mut render, &render_params);
230-
render.format_svg(DVec2::ZERO, size);
231-
let svg_string = render.svg.to_svg_string();
232-
233-
canvas.set_resolution(resolution);
234-
let context = canvas.context();
235-
236-
let preamble = "data:image/svg+xml;base64,";
237-
let mut base64_string = String::with_capacity(preamble.len() + svg_string.len() * 4);
238-
base64_string.push_str(preamble);
239-
base64::engine::general_purpose::STANDARD.encode_string(svg_string, &mut base64_string);
208+
let executor = pipeline.element().executor().ok_or_else(|| NodeError::new("A GPU is required to rasterize"))?;
209+
let mut canvas = canvas.element().lock();
210+
let mut scene = executor.vello_scene_on_canvas(&mut canvas, resolution, view).map_err(NodeError::new)?;
211+
data.render_to_vello(&mut scene, DAffine2::IDENTITY, &render_params);
212+
let texture = executor.render_vello_raster_on_canvas(&mut canvas, scene).map_err(NodeError::new)?;
240213

241-
let image_data = web_sys::HtmlImageElement::new().unwrap();
242-
image_data.set_src(base64_string.as_str());
243-
wasm_bindgen_futures::JsFuture::from(image_data.decode()).await.unwrap();
244-
context
245-
.draw_image_with_html_image_element_and_dw_and_dh(&image_data, 0., 0., resolution.x as f64, resolution.y as f64)
246-
.unwrap();
247-
248-
let rasterized = context.get_image_data(0, 0, resolution.x as i32, resolution.y as i32).unwrap();
249-
250-
let image = Image::from_image_data(&rasterized.data().0, resolution.x as u32, resolution.y as u32);
251-
let executor = pipeline.element().executor().cloned().ok_or_else(|| NodeError::new("A GPU is required to rasterize"))?;
252214
Ok(List::new_from_item(
253-
Item::new_from_element(Raster::new_cpu(image).convert(Footprint::DEFAULT, executor))
215+
Item::new_from_element(Raster::new_gpu(texture))
254216
.with_attribute(ATTR_TRANSFORM, footprint.transform)
255-
.with_attribute(ATTR_EDITOR_MERGED_LAYERS, upstream_graphic_list),
217+
.with_attribute(ATTR_EDITOR_MERGED_LAYERS, data),
256218
))
257219
}
258220

259-
#[cfg(target_family = "wasm")]
260-
fn pending_raster(_data: &List<Graphic>, _footprint: &Item<Footprint>, _canvas: &Item<CanvasHandle>, _pipeline: &Item<::wgpu_executor::WgpuPipelineCache>) -> List<Raster<GPU>> {
261-
List::new()
262-
}
263-
264221
#[node_macro::node(category(""), inject_scope)]
265222
fn editor_api(_: impl Ctx, #[scope("editor-api")] editor_api: Item<Arc<PlatformEditorApi>>) -> Item<Arc<PlatformEditorApi>> {
266223
editor_api

0 commit comments

Comments
 (0)