Remove surface and window from ApplicationIo (#3941)

* Remove surface and window from ApplicationIo

* Seperate Wasm and Native ApplicationIo

* Fix warnings

* Fix tests

* Remove redundant PlatformApplicationIo::new_offscreen

* Fixup

* Remove unused From implementaitions for ApplicationIo
This commit is contained in:
Timon
2026-04-09 22:12:53 +02:00
committed by GitHub
parent b100892bfa
commit 661e8bc569
36 changed files with 716 additions and 773 deletions

View File

@@ -1,10 +1,9 @@
pub mod any;
pub mod pixel_preview;
pub mod platform_application_io;
pub mod render_cache;
pub mod render_node;
pub mod text;
#[cfg(feature = "wasm")]
pub mod wasm_application_io;
pub use blending_nodes;
pub use brush_nodes as brush;
pub use core_types::*;

View File

@@ -2,16 +2,16 @@ use crate::render_node::RenderOutputType;
use core_types::transform::{Footprint, Transform};
use core_types::{CloneVarArgs, Context, Ctx, ExtractAll, OwnedContextImpl};
use glam::{DAffine2, DVec2, UVec2};
use graph_craft::application_io::PlatformEditorApi;
use graph_craft::document::value::RenderOutput;
use graph_craft::wasm_application_io::WasmEditorApi;
use graphene_application_io::{ApplicationIo, ImageTexture};
use graphene_application_io::ApplicationIo;
use rendering::{RenderOutputType as RenderOutputTypeRequest, RenderParams};
use vector_types::vector::style::RenderMode;
#[node_macro::node(category(""))]
pub async fn pixel_preview<'a: 'n>(
ctx: impl Ctx + ExtractAll + CloneVarArgs + Sync,
editor_api: &'a WasmEditorApi,
editor_api: &'a PlatformEditorApi,
data: impl Node<Context<'static>, Output = RenderOutput> + Send + Sync,
) -> RenderOutput {
let Some(render_params) = ctx.vararg(0).ok().and_then(|v| v.downcast_ref::<RenderParams>()).cloned() else {
@@ -59,9 +59,9 @@ pub async fn pixel_preview<'a: 'n>(
let transform = DAffine2::from_translation(-upstream_min) * footprint.transform.inverse() * DAffine2::from_scale(logical_resolution);
let exec = editor_api.application_io.as_ref().unwrap().gpu_executor().unwrap();
let resampled = exec.resample_texture(&source_texture.texture, physical_resolution, &transform);
let resampled = exec.resample_texture(source_texture.as_ref(), physical_resolution, &transform);
result.data = RenderOutputType::Texture(ImageTexture { texture: resampled.into() });
result.data = RenderOutputType::Texture(resampled.into());
result
.metadata

View File

@@ -1,6 +1,8 @@
#[cfg(target_family = "wasm")]
use base64::Engine;
#[cfg(target_family = "wasm")]
use canvas_utils::{Canvas, CanvasHandle};
#[cfg(target_family = "wasm")]
use core_types::WasmNotSend;
#[cfg(target_family = "wasm")]
use core_types::math::bbox::Bbox;
@@ -8,10 +10,12 @@ use core_types::table::Table;
#[cfg(target_family = "wasm")]
use core_types::transform::Footprint;
use core_types::{Color, Ctx};
pub use graph_craft::application_io::*;
pub use graph_craft::document::value::RenderOutputType;
pub use graph_craft::wasm_application_io::*;
use graphene_application_io::ApplicationIo;
#[cfg(target_family = "wasm")]
pub use graphene_canvas_utils as canvas_utils;
#[cfg(target_family = "wasm")]
use graphic_types::Graphic;
#[cfg(target_family = "wasm")]
use graphic_types::Vector;
@@ -22,17 +26,6 @@ use graphic_types::vector_types::gradient::GradientStops;
#[cfg(target_family = "wasm")]
use rendering::{Render, RenderParams, RenderSvgSegmentList, SvgRender};
use std::sync::Arc;
#[cfg(target_family = "wasm")]
use wasm_bindgen::JsCast;
#[cfg(target_family = "wasm")]
use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement};
/// Allocates GPU memory and a rendering context for vector-to-raster conversion.
#[cfg(feature = "wgpu")]
#[node_macro::node(category(""))]
async fn create_surface<'a: 'n>(_: impl Ctx, editor: &'a WasmEditorApi) -> Arc<WasmSurfaceHandle> {
Arc::new(editor.application_io.as_ref().unwrap().create_window())
}
fn parse_headers(headers: &str) -> reqwest::header::HeaderMap {
use reqwest::header::{HeaderMap, HeaderName, HeaderValue};
@@ -132,7 +125,7 @@ fn image_to_bytes(_: impl Ctx, image: Table<Raster<CPU>>) -> Vec<u8> {
/// Loads binary from URLs and local asset paths. Returns a transparent placeholder if the resource fails to load, allowing rendering to continue.
#[node_macro::node(category("Web Request"))]
async fn load_resource<'a: 'n>(_: impl Ctx, _primary: (), #[scope("editor-api")] editor_resources: &'a WasmEditorApi, #[name("URL")] url: String) -> Arc<[u8]> {
async fn load_resource<'a: 'n>(_: impl Ctx, _primary: (), #[scope("editor-api")] editor_resources: &'a PlatformEditorApi, #[name("URL")] url: String) -> Arc<[u8]> {
let Some(api) = editor_resources.application_io.as_ref() else {
return Arc::from(include_bytes!("../../../graph-craft/src/null.png").to_vec());
};
@@ -168,6 +161,12 @@ fn decode_image(_: impl Ctx, data: Arc<[u8]>) -> Table<Raster<CPU>> {
Table::new_from_element(Raster::new_cpu(image))
}
#[cfg(target_family = "wasm")]
#[node_macro::node(category(""))]
async fn create_canvas(_: impl Ctx) -> CanvasHandle {
CanvasHandle::new()
}
/// Renders a view of the input graphic within an area defined by the *Footprint*.
#[cfg(target_family = "wasm")]
#[node_macro::node(category(""))]
@@ -182,7 +181,7 @@ async fn rasterize<T: WasmNotSend + 'n>(
)]
mut data: Table<T>,
footprint: Footprint,
surface_handle: Arc<graphene_application_io::SurfaceHandle<HtmlCanvasElement>>,
mut canvas: CanvasHandle,
) -> Table<Raster<CPU>>
where
Table<T>: Render,
@@ -211,11 +210,8 @@ where
render.format_svg(glam::DVec2::ZERO, size);
let svg_string = render.svg.to_svg_string();
let canvas = &surface_handle.surface;
canvas.set_width(resolution.x);
canvas.set_height(resolution.y);
let context = canvas.get_context("2d").unwrap().unwrap().dyn_into::<CanvasRenderingContext2d>().unwrap();
canvas.set_resolution(resolution);
let context = canvas.context();
let preamble = "data:image/svg+xml;base64,";
let mut base64_string = String::with_capacity(preamble.len() + svg_string.len() * 4);

View File

@@ -4,9 +4,9 @@ use core_types::math::bbox::AxisAlignedBbox;
use core_types::transform::{Footprint, RenderQuality, Transform};
use core_types::{CloneVarArgs, Context, Ctx, ExtractAll, ExtractAnimationTime, ExtractPointerPosition, ExtractRealTime, OwnedContextImpl};
use glam::{DAffine2, DVec2, IVec2, UVec2};
use graph_craft::application_io::PlatformEditorApi;
use graph_craft::document::value::RenderOutput;
use graph_craft::wasm_application_io::WasmEditorApi;
use graphene_application_io::{ApplicationIo, ImageTexture};
use graphene_application_io::ApplicationIo;
use rendering::{RenderOutputType as RenderOutputTypeRequest, RenderParams};
use std::collections::HashSet;
use std::hash::Hash;
@@ -374,7 +374,7 @@ fn flood_fill(start: &TileCoord, tile_set: &HashSet<TileCoord>, visited: &mut Ha
#[node_macro::node(category(""))]
pub async fn render_output_cache<'a: 'n>(
ctx: impl Ctx + ExtractAll + CloneVarArgs + ExtractRealTime + ExtractAnimationTime + ExtractPointerPosition + Sync,
editor_api: &'a WasmEditorApi,
editor_api: &'a PlatformEditorApi,
data: impl Node<Context<'static>, Output = RenderOutput> + Send + Sync,
#[data] tile_cache: TileCache,
) -> RenderOutput {
@@ -460,7 +460,7 @@ pub async fn render_output_cache<'a: 'n>(
let combined_metadata = composite_cached_regions(&all_regions, output_texture.as_ref(), &device_origin_offset, &footprint.transform, exec);
RenderOutput {
data: RenderOutputType::Texture(ImageTexture { texture: output_texture }),
data: RenderOutputType::Texture(output_texture.into()),
metadata: combined_metadata,
}
}
@@ -506,7 +506,7 @@ where
let memory_size = (region_pixel_size.x * region_pixel_size.y) as usize * BYTES_PER_PIXEL;
CachedRegion {
texture: rendered_texture.texture.as_ref().clone(),
texture: rendered_texture.as_ref().clone(),
texture_size: region_pixel_size,
tiles: region.tiles.clone(),
metadata: result.metadata,
@@ -558,7 +558,7 @@ fn composite_cached_regions(
aspect: wgpu::TextureAspect::All,
},
wgpu::TexelCopyTextureInfo {
texture: &output_texture,
texture: output_texture,
mip_level: 0,
origin: wgpu::Origin3d { x: dst_x, y: dst_y, z: 0 },
aspect: wgpu::TextureAspect::All,

View File

@@ -2,10 +2,10 @@ use core_types::table::Table;
use core_types::transform::{Footprint, Transform};
use core_types::{CloneVarArgs, ExtractAll, ExtractVarArgs};
use core_types::{Color, Context, Ctx, ExtractFootprint, OwnedContextImpl, WasmNotSend};
pub use graph_craft::application_io::*;
use graph_craft::document::value::RenderOutput;
pub use graph_craft::document::value::RenderOutputType;
pub use graph_craft::wasm_application_io::*;
use graphene_application_io::{ApplicationIo, ExportFormat, ImageTexture, RenderConfig};
use graphene_application_io::{ApplicationIo, ExportFormat, RenderConfig};
use graphic_types::raster_types::Image;
use graphic_types::raster_types::{CPU, Raster};
use graphic_types::{Artboard, Graphic, Vector};
@@ -124,7 +124,7 @@ async fn create_context<'a: 'n>(
}
#[node_macro::node(category(""))]
async fn render<'a: 'n>(ctx: impl Ctx + ExtractFootprint + ExtractVarArgs, editor_api: &'a WasmEditorApi, data: RenderIntermediate) -> RenderOutput {
async fn render<'a: 'n>(ctx: impl Ctx + ExtractFootprint + ExtractVarArgs, editor_api: &'a PlatformEditorApi, data: RenderIntermediate) -> RenderOutput {
let footprint = ctx.footprint();
let render_params = ctx
.vararg(0)
@@ -202,7 +202,7 @@ async fn render<'a: 'n>(ctx: impl Ctx + ExtractFootprint + ExtractVarArgs, edito
.expect("Failed to render Vello scene"),
);
RenderOutputType::Texture(ImageTexture { texture })
RenderOutputType::Texture(texture.into())
}
_ => unreachable!("Render node did not receive its requested data type"),
};

View File

@@ -1,5 +1,5 @@
use core_types::{Ctx, table::Table};
use graph_craft::wasm_application_io::WasmEditorApi;
use graph_craft::application_io::PlatformEditorApi;
use graphic_types::Vector;
pub use text_nodes::*;
@@ -9,7 +9,7 @@ fn text<'i: 'n>(
_: impl Ctx,
/// The Graphite editor's source for global font resources.
#[scope("editor-api")]
editor_resources: &'i WasmEditorApi,
editor_resources: &'i PlatformEditorApi,
/// The text content to be drawn.
#[widget(ParsedWidgetOverride::Custom = "text_area")]
#[default("Lorem ipsum")]