Restore functionality of GPU infrastructure (#1797)

* Update gpu nodes to compile again

Restructure `gpu-executor` and `wgpu-executor`

And libssl to nix shell

Fix graphene-cli and add half percision color format

Fix texture scaling

Remove vulkan executor

Fix compile errors

Improve execution request deduplication

* Fix warnings

* Fix graph compile issues

* Code review

* Remove test file

* Fix lint

* Wip make node futures send

* Make futures Send on non wasm targets

* Fix warnings

* Fix nested use of block_on

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Dennis Kobert
2024-07-15 13:14:48 +00:00
committed by GitHub
co-authored by Keavon Chambers
parent 59a943f42f
commit 212f08c6c8
66 changed files with 1572 additions and 1577 deletions
+31 -82
View File
@@ -1,15 +1,16 @@
use crate::application_io::SurfaceHandleFrame;
use crate::raster::{BlendMode, ImageFrame};
use crate::renderer::GraphicElementRendered;
use crate::transform::Footprint;
use crate::vector::VectorData;
use crate::{Color, Node};
use crate::{Color, Node, SurfaceFrame};
use bezier_rs::BezierHandles;
use dyn_any::{DynAny, StaticType};
use node_macro::node_fn;
use core::future::Future;
use core::ops::{Deref, DerefMut};
use glam::{DAffine2, DVec2, IVec2, UVec2};
use web_sys::HtmlCanvasElement;
pub mod renderer;
@@ -67,6 +68,8 @@ pub enum GraphicElement {
VectorData(Box<VectorData>),
/// A bitmap image with a finite position and extent, equivalent to the SVG <image> tag: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/image
ImageFrame(ImageFrame<Color>),
/// A Canvas evement
Surface(SurfaceFrame),
}
// TODO: Can this be removed? It doesn't necessarily make that much sense to have a default when, instead, the entire GraphicElement just shouldn't exist if there's no specific content to assign it.
@@ -127,10 +130,10 @@ pub struct ConstructLayerNode<Stack, GraphicElement> {
}
#[node_fn(ConstructLayerNode)]
async fn construct_layer<Data: Into<GraphicElement>, Fut1: Future<Output = GraphicGroup>, Fut2: Future<Output = Data>>(
async fn construct_layer<Data: Into<GraphicElement> + Send>(
footprint: crate::transform::Footprint,
mut stack: impl Node<crate::transform::Footprint, Output = Fut1>,
graphic_element: impl Node<crate::transform::Footprint, Output = Fut2>,
mut stack: impl Node<crate::transform::Footprint, Output = GraphicGroup>,
graphic_element: impl Node<crate::transform::Footprint, Output = Data>,
) -> GraphicGroup {
let graphic_element = self.graphic_element.eval(footprint).await;
let mut stack = self.stack.eval(footprint).await;
@@ -162,9 +165,9 @@ pub struct ConstructArtboardNode<Contents, Label, Location, Dimensions, Backgrou
}
#[node_fn(ConstructArtboardNode)]
async fn construct_artboard<Fut: Future<Output = GraphicGroup>>(
async fn construct_artboard(
mut footprint: Footprint,
contents: impl Node<Footprint, Output = Fut>,
contents: impl Node<Footprint, Output = GraphicGroup>,
label: String,
location: IVec2,
dimensions: IVec2,
@@ -189,11 +192,7 @@ pub struct AddArtboardNode<ArtboardGroup, Artboard> {
}
#[node_fn(AddArtboardNode)]
async fn add_artboard<Data: Into<Artboard>, Fut1: Future<Output = ArtboardGroup>, Fut2: Future<Output = Data>>(
footprint: Footprint,
artboards: impl Node<Footprint, Output = Fut1>,
artboard: impl Node<Footprint, Output = Fut2>,
) -> ArtboardGroup {
async fn add_artboard<Data: Into<Artboard> + Send>(footprint: Footprint, artboards: impl Node<Footprint, Output = ArtboardGroup>, artboard: impl Node<Footprint, Output = Data>) -> ArtboardGroup {
let artboard = self.artboard.eval(footprint).await;
let mut artboards = self.artboards.eval(footprint).await;
@@ -229,6 +228,25 @@ impl From<GraphicGroup> for GraphicElement {
GraphicElement::GraphicGroup(graphic_group)
}
}
impl From<SurfaceFrame> for GraphicElement {
fn from(surface: SurfaceFrame) -> Self {
GraphicElement::Surface(surface)
}
}
impl From<alloc::sync::Arc<SurfaceHandleFrame<HtmlCanvasElement>>> for GraphicElement {
fn from(surface: alloc::sync::Arc<SurfaceHandleFrame<HtmlCanvasElement>>) -> Self {
let surface_id = surface.surface_handle.surface_id;
let transform = surface.transform;
GraphicElement::Surface(SurfaceFrame { surface_id, transform })
}
}
impl From<SurfaceHandleFrame<HtmlCanvasElement>> for GraphicElement {
fn from(surface: SurfaceHandleFrame<HtmlCanvasElement>) -> Self {
let surface_id = surface.surface_handle.surface_id;
let transform = surface.transform;
GraphicElement::Surface(SurfaceFrame { surface_id, transform })
}
}
impl Deref for GraphicGroup {
type Target = Vec<GraphicElement>;
@@ -287,72 +305,3 @@ impl GraphicGroup {
tree
}
}
impl GraphicElement {
fn to_usvg_node(&self) -> usvg::Node {
fn to_transform(transform: DAffine2) -> usvg::Transform {
let cols = transform.to_cols_array();
usvg::Transform::from_row(cols[0] as f32, cols[1] as f32, cols[2] as f32, cols[3] as f32, cols[4] as f32, cols[5] as f32)
}
match self {
GraphicElement::VectorData(vector_data) => {
use usvg::tiny_skia_path::PathBuilder;
let mut builder = PathBuilder::new();
let transform = to_transform(vector_data.transform);
for subpath in vector_data.stroke_bezier_paths() {
let start = vector_data.transform.transform_point2(subpath[0].anchor);
builder.move_to(start.x as f32, start.y as f32);
for bezier in subpath.iter() {
bezier.apply_transformation(|pos| vector_data.transform.transform_point2(pos));
let end = bezier.end;
match bezier.handles {
BezierHandles::Linear => builder.line_to(end.x as f32, end.y as f32),
BezierHandles::Quadratic { handle } => builder.quad_to(handle.x as f32, handle.y as f32, end.x as f32, end.y as f32),
BezierHandles::Cubic { handle_start, handle_end } => {
builder.cubic_to(handle_start.x as f32, handle_start.y as f32, handle_end.x as f32, handle_end.y as f32, end.x as f32, end.y as f32)
}
}
}
if subpath.closed {
builder.close()
}
}
let path = builder.finish().unwrap();
let mut path = usvg::Path::new(path.into());
path.abs_transform = transform;
// TODO: use proper style
path.fill = None;
path.stroke = Some(usvg::Stroke::default());
usvg::Node::Path(Box::new(path))
}
GraphicElement::ImageFrame(image_frame) => {
if image_frame.image.width * image_frame.image.height == 0 {
return usvg::Node::Group(Box::default());
}
let png = image_frame.image.to_png();
usvg::Node::Image(Box::new(usvg::Image {
id: String::new(),
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(),
aspect: usvg::AspectRatio::default(),
},
rendering_mode: usvg::ImageRendering::OptimizeSpeed,
kind: usvg::ImageKind::PNG(png.into()),
bounding_box: None,
}))
}
GraphicElement::GraphicGroup(group) => {
let mut group_element = usvg::Group::default();
for element in group.iter() {
group_element.children.push(element.to_usvg_node());
}
usvg::Node::Group(Box::new(group_element))
}
}
}
}