diff --git a/.github/workflows/web-demo.yml b/.github/workflows/web-demo.yml new file mode 100644 index 000000000..c1f1683c0 --- /dev/null +++ b/.github/workflows/web-demo.yml @@ -0,0 +1,70 @@ +name: Web Demo Update + +on: + push: + branches: + - main + +jobs: + release-web: + permissions: + contents: read + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: install stable toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: wasm32-unknown-unknown + + - name: install wasm-bindgen + uses: jetli/wasm-bindgen-action@v0.2.0 + with: + version: 'latest' + + - name: build (wasm) + run: cargo build -p with_winit --bin with_winit_bin --release --target wasm32-unknown-unknown + env: + RUSTFLAGS: '--cfg=web_sys_unstable_apis' + + - name: package wasm + run: | + mkdir public + wasm-bindgen --target web --out-dir public target/wasm32-unknown-unknown/release/with_winit_bin.wasm --no-typescript + cat << EOF > public/index.html + + Vello Web Demo + + + + + + + + + + + EOF + + - name: Setup Pages + uses: actions/configure-pages@v4 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: './public' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/Cargo.toml b/Cargo.toml index 629c25be8..8977a09d6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,5 @@ [workspace] resolver = "2" - members = [ "crates/encoding", "crates/shaders", @@ -13,27 +12,33 @@ members = [ "examples/with_bevy", "examples/run_wasm", "examples/scenes", - "examples/shapes", + "examples/simple", ] [workspace.package] +# Vello version, also used by other packages which want to mimic Vello's version. +# Right now those packages include vello_encoding and vello_shaders. +# +# NOTE: When bumping this, remember to also bump the aforementioned other packages' +# version in the dependencies section at the bottom of this file. +# Additionally, bump the Vello dependency version in the 'simple' example. +version = "0.1.0" + edition = "2021" -version = "0.0.1" -license = "MIT OR Apache-2.0" +rust-version = "1.75" +license = "Apache-2.0 OR MIT" repository = "https://github.com/linebender/vello" [package] name = "vello" -description = "An experimental GPU compute-centric 2D renderer" +version.workspace = true +description = "An experimental GPU compute-centric 2D renderer." categories = ["rendering", "graphics"] keywords = ["2d", "vector-graphics"] - -# This crate is intended for publishing, but not ready yet -publish = false - -version.workspace = true -license.workspace = true +exclude = ["/.github/", "/doc/", "/examples/", ".gitignore"] edition.workspace = true +rust-version.workspace = true +license.workspace = true repository.workspace = true [features] @@ -42,26 +47,29 @@ hot_reload = [] buffer_labels = [] [dependencies] +vello_encoding = { workspace = true } bytemuck = { workspace = true } skrifa = { workspace = true } peniko = { workspace = true } wgpu = { workspace = true, optional = true } -raw-window-handle = "0.6" -futures-intrusive = "0.5.0" -vello_encoding = { path = "crates/encoding" } +raw-window-handle = { workspace = true } +futures-intrusive = { workspace = true } wgpu-profiler = { workspace = true, optional = true } [workspace.dependencies] -bytemuck = { version = "1.12.1", features = ["derive"] } -skrifa = "0.15.4" +vello_encoding = { version = "0.1.0", path = "crates/encoding" } +bytemuck = { version = "1.14.3", features = ["derive"] } +skrifa = "0.15.5" peniko = "0.1.0" +futures-intrusive = "0.5.0" +raw-window-handle = "0.6" # NOTE: Make sure to keep this in sync with the version badge in README.md wgpu = { version = "0.19" } # Used for examples -clap = "4.1.0" +clap = "4.5.1" anyhow = "1.0" instant = { version = "0.1.12", features = ["wasm-bindgen"] } pollster = "0.3.0" diff --git a/README.md b/README.md index a9baa4b8d..6a9f0b4fa 100644 --- a/README.md +++ b/README.md @@ -180,7 +180,7 @@ Other platforms are more tricky, and may require special building/running proced Because Vello relies heavily on compute shaders, we rely on the emerging WebGPU standard to run on the web. Until browser support becomes widespread, it will probably be necessary to use development browser versions (e.g. Chrome Canary) and explicitly enable WebGPU. -The following command builds and runs a web version of the [winit demo](#winit). +The following command builds and runs a web version of the [winit demo](#winit). This uses [`cargo-run-wasm`](https://github.com/rukai/cargo-run-wasm) to build the example for web, and host a local server for it ```shell @@ -191,6 +191,8 @@ rustup target add wasm32-unknown-unknown cargo run_wasm -p with_winit --bin with_winit_bin ``` +There is also a web demo [available here](https://linebender.github.io/vello) on supporting web browsers. + > [!WARNING] > The web is not currently a primary target for Vello, and WebGPU implementations are incomplete, so you might run into issues running this example. diff --git a/crates/encoding/Cargo.toml b/crates/encoding/Cargo.toml index bb2c590ba..763e5fba0 100644 --- a/crates/encoding/Cargo.toml +++ b/crates/encoding/Cargo.toml @@ -1,7 +1,9 @@ [package] name = "vello_encoding" -version = "0.1.0" +version.workspace = true # We mimic Vello's version +description = "Vello types that represent the data that needs to be rendered." edition.workspace = true +rust-version.workspace = true license.workspace = true repository.workspace = true diff --git a/crates/encoding/README.md b/crates/encoding/README.md new file mode 100644 index 000000000..8544642e0 --- /dev/null +++ b/crates/encoding/README.md @@ -0,0 +1,5 @@ +# Vello Encoding + +This package contains types that represent data that [Vello] can render. + +[Vello]: https://github.com/linebender/vello diff --git a/crates/shaders/Cargo.toml b/crates/shaders/Cargo.toml index 5cf538ec9..9114fef3a 100644 --- a/crates/shaders/Cargo.toml +++ b/crates/shaders/Cargo.toml @@ -1,10 +1,14 @@ [package] name = "vello_shaders" -version = "0.1.0" +version.workspace = true # We mimic Vello's version +description = "Vello infrastructure to preprocess and cross-compile shaders at compile time." edition.workspace = true +rust-version.workspace = true license.workspace = true repository.workspace = true +publish = false # Remove this when the package is ready for publishing + [features] default = ["compile", "wgsl", "msl"] compile = ["naga", "thiserror"] @@ -28,9 +32,9 @@ msl = [] [dependencies] naga = { version = "0.13", features = ["wgsl-in", "msl-out", "validate"], optional = true } -thiserror = { version = "1.0.40", optional = true } +thiserror = { version = "1.0.57", optional = true } [build-dependencies] naga = { version = "0.13", features = ["wgsl-in", "msl-out", "validate"] } -thiserror = "1.0.40" +thiserror = "1.0.57" diff --git a/crates/tests/Cargo.toml b/crates/tests/Cargo.toml index e97b1c414..8a6ce575e 100644 --- a/crates/tests/Cargo.toml +++ b/crates/tests/Cargo.toml @@ -1,19 +1,17 @@ [package] name = "vello_tests" +description = "Integration tests for Vello." edition.workspace = true -version.workspace = true license.workspace = true repository.workspace = true publish = false -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] vello = { path = "../.." } -image = "0.24.5" +image = "0.24.9" anyhow = { workspace = true } wgpu = { workspace = true } pollster = { workspace = true } -png = "0.17.7" -futures-intrusive = "0.5.0" +png = "0.17.13" +futures-intrusive = { workspace = true } diff --git a/examples/headless/Cargo.toml b/examples/headless/Cargo.toml index bab506bb0..6c04262a1 100644 --- a/examples/headless/Cargo.toml +++ b/examples/headless/Cargo.toml @@ -1,23 +1,19 @@ [package] name = "headless" -description = "An example showing how to use `vello` to create raster images" -publish = false - -version.workspace = true -license.workspace = true +description = "An example showing how to use Vello to create raster images." edition.workspace = true +license.workspace = true repository.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +publish = false [dependencies] -anyhow = { workspace = true } -clap = { workspace = true, features = ["derive"] } vello = { path = "../../" } scenes = { path = "../scenes" } +anyhow = { workspace = true } +clap = { workspace = true, features = ["derive"] } wgpu = { workspace = true } pollster = { workspace = true } -env_logger = "0.10.0" -png = "0.17.7" -futures-intrusive = "0.5.0" +env_logger = "0.11.2" +png = "0.17.13" +futures-intrusive = { workspace = true } diff --git a/examples/run_wasm/Cargo.toml b/examples/run_wasm/Cargo.toml index de51958a6..76068dd0c 100644 --- a/examples/run_wasm/Cargo.toml +++ b/examples/run_wasm/Cargo.toml @@ -1,13 +1,9 @@ [package] name = "run_wasm" -publish = false - -version.workspace = true -license.workspace = true edition.workspace = true +license.workspace = true repository.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +publish = false [dependencies] cargo-run-wasm = "0.3.2" diff --git a/examples/scenes/Cargo.toml b/examples/scenes/Cargo.toml index 8637665a8..dd23a7d4c 100644 --- a/examples/scenes/Cargo.toml +++ b/examples/scenes/Cargo.toml @@ -1,21 +1,17 @@ [package] name = "scenes" -description = "Vello scenes used in the other examples" -publish = false - -version.workspace = true -license.workspace = true +description = "Vello scenes used in the other examples." edition.workspace = true +license.workspace = true repository.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +publish = false [dependencies] vello = { path = "../../" } vello_svg = { path = "../../integrations/vello_svg" } anyhow = { workspace = true } clap = { workspace = true, features = ["derive"] } -image = "0.24.5" +image = "0.24.9" rand = "0.8.5" instant = { workspace = true } @@ -23,4 +19,4 @@ instant = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] byte-unit = "4.0" dialoguer = "0.10" -ureq = "2.6" +ureq = "2.9" diff --git a/examples/shapes/src/main.rs b/examples/shapes/src/main.rs deleted file mode 100644 index 5517677a7..000000000 --- a/examples/shapes/src/main.rs +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2024 the Vello Authors -// SPDX-License-Identifier: Apache-2.0 OR MIT - -use anyhow::Result; -use std::num::NonZeroUsize; -use std::sync::Arc; -use vello::kurbo::{Circle, Ellipse, Line, RoundedRect, Stroke}; -use vello::peniko::Color; -use vello::util::RenderSurface; -use vello::RendererOptions; -use vello::{kurbo::Affine, util::RenderContext, AaConfig, Renderer, Scene}; -use winit::{dpi::LogicalSize, window::WindowBuilder}; -use winit::{event::*, event_loop::ControlFlow}; -use winit::{event_loop::EventLoop, window::Window}; - -// Simple struct to hold the state of the renderer -pub struct RenderState<'s> { - // The fields MUST be in this order, so that the surface is dropped before the window - surface: RenderSurface<'s>, - window: Arc, -} - -// Helper function that creates a Winit window and returns it (wrapped in an Arc for thread safety) -fn create_window(event_loop: &winit::event_loop::EventLoopWindowTarget<()>) -> Arc { - Arc::new( - WindowBuilder::new() - .with_inner_size(LogicalSize::new(1044, 800)) - .with_resizable(true) - .with_title("Vello Shapes") - .build(event_loop) - .unwrap(), - ) -} - -fn main() -> Result<()> { - let event_loop = EventLoop::new()?; - let mut render_cx = RenderContext::new().unwrap(); - let mut renderers: Vec> = vec![]; - let mut render_state = None::; - // Cache a window so that it can be reused when the app is resumed after being suspended - let mut cached_window = None; - let mut scene = Scene::new(); - - event_loop - .run(move |event, event_loop| match event { - Event::WindowEvent { - ref event, - window_id, - } => { - let Some(render_state) = &mut render_state else { - return; - }; - if render_state.window.id() != window_id { - return; - } - match event { - WindowEvent::CloseRequested => event_loop.exit(), - WindowEvent::Resized(size) => { - // Resize the surface when the window is resized - render_cx.resize_surface(&mut render_state.surface, size.width, size.height) - } - WindowEvent::RedrawRequested => { - // This is where all the rendering happens - - // Get the window size - let width = render_state.surface.config.width; - let height = render_state.surface.config.height; - // Get a handle to the device - let device_handle = &render_cx.devices[render_state.surface.dev_id]; - // Use the render_state to retrieve the surface to draw to - let surface_texture = render_state - .surface - .surface - .get_current_texture() - .expect("failed to get surface texture"); - - // Define the render parameters. - let render_params = vello::RenderParams { - // Background color - base_color: Color::BLACK, - // Width - width, - // Height - height, - // Antialiasing method to use. Other methods: AaConfig::Area, AaConfig::Msaa8 - antialiasing_method: AaConfig::Msaa16, - }; - - // Create some shapes! - let stroke = Stroke::new(6.0); - - let rect = RoundedRect::new(10.0, 10.0, 240.0, 240.0, 20.0); - let rect_stroke_color = Color::rgb(0.9804, 0.702, 0.5294); - - let circle = Circle::new((420.0, 200.0), 120.0); - let circle_fill_color = Color::rgb(0.9529, 0.5451, 0.6588); - - let ellipse = Ellipse::new((250.0, 420.0), (100.0, 160.0), -90.0); - let ellipse_fill_color = Color::rgb(0.7961, 0.651, 0.9686); - - let line = Line::new((260.0, 20.0), (620.0, 100.0)); - let line_stroke_color = Color::rgb(0.5373, 0.7059, 0.9804); - - scene.reset(); - - // Draw the shapes! - scene.stroke(&stroke, Affine::IDENTITY, rect_stroke_color, None, &rect); - scene.fill( - vello::peniko::Fill::NonZero, - Affine::IDENTITY, - circle_fill_color, - None, - &circle, - ); - scene.fill( - vello::peniko::Fill::NonZero, - Affine::IDENTITY, - ellipse_fill_color, - None, - &ellipse, - ); - scene.stroke(&stroke, Affine::IDENTITY, line_stroke_color, None, &line); - - // Render to the surface - vello::block_on_wgpu( - &device_handle.device, - renderers[render_state.surface.dev_id] - .as_mut() - .unwrap() - .render_to_surface_async( - &device_handle.device, - &device_handle.queue, - &scene, - &surface_texture, - &render_params, - ), - ) - .expect("failed to render to surface"); - surface_texture.present(); - device_handle.device.poll(wgpu::Maintain::Poll); - } - _ => {} - } - } - Event::Suspended => { - if let Some(render_state) = render_state.take() { - cached_window = Some(render_state.window); - } - event_loop.set_control_flow(ControlFlow::Wait); - } - Event::Resumed => { - let Option::None = render_state else { return }; - // Get the window - let window = cached_window - .take() - .unwrap_or_else(|| create_window(event_loop)); - let size = window.inner_size(); - let surface_future = - render_cx.create_surface(window.clone(), size.width, size.height); - // Create a surface - let surface = pollster::block_on(surface_future).expect("Error creating surface"); - render_state = { - let render_state = RenderState { window, surface }; - renderers.resize_with(render_cx.devices.len(), || None); - let id = render_state.surface.dev_id; - renderers[id].get_or_insert_with(|| { - Renderer::new( - &render_cx.devices[id].device, - RendererOptions { - surface_format: Some(render_state.surface.format), - use_cpu: false, - antialiasing_support: vello::AaSupport::all(), - num_init_threads: NonZeroUsize::new(1), - }, - ) - .expect("Could create renderer") - }); - Some(render_state) - }; - event_loop.set_control_flow(ControlFlow::Poll); - } - _ => {} - }) - .expect("Couldn't run event loop"); - Ok(()) -} diff --git a/examples/shapes/Cargo.toml b/examples/simple/Cargo.toml similarity index 52% rename from examples/shapes/Cargo.toml rename to examples/simple/Cargo.toml index 048fa22e2..639818ef5 100644 --- a/examples/shapes/Cargo.toml +++ b/examples/simple/Cargo.toml @@ -1,17 +1,16 @@ [package] -name = "shapes" +name = "simple" edition.workspace = true -version.workspace = true license.workspace = true repository.workspace = true publish = false # The dependencies here are independent from the workspace versions [dependencies] +# When using this example outside of the original Vello workspace, +# remove the path property of the following Vello dependency requirement. +vello = { version = "0.1.0", path = "../../" } anyhow = "1.0.80" pollster = "0.3.0" wgpu = "0.19.1" -winit = "0.29.10" -vello = { path = "../../" } -# When using, replace the above line with this: -#vello = { git = "https://github.com/linebender/vello" } +winit = "0.29.11" diff --git a/examples/simple/src/main.rs b/examples/simple/src/main.rs new file mode 100644 index 000000000..06a5ac389 --- /dev/null +++ b/examples/simple/src/main.rs @@ -0,0 +1,232 @@ +// Copyright 2024 the Vello Authors +// SPDX-License-Identifier: Apache-2.0 OR MIT + +use anyhow::Result; +use std::num::NonZeroUsize; +use std::sync::Arc; +use vello::kurbo::{Circle, Ellipse, Line, RoundedRect, Stroke}; +use vello::peniko::Color; +use vello::util::RenderSurface; +use vello::RendererOptions; +use vello::{kurbo::Affine, util::RenderContext, AaConfig, Renderer, Scene}; +use winit::{dpi::LogicalSize, window::WindowBuilder}; +use winit::{event::*, event_loop::ControlFlow}; +use winit::{event_loop::EventLoop, window::Window}; + +// Simple struct to hold the state of the renderer +pub struct ActiveRenderState<'s> { + // The fields MUST be in this order, so that the surface is dropped before the window + surface: RenderSurface<'s>, + window: Arc, +} + +enum RenderState<'s> { + Active(ActiveRenderState<'s>), + // Cache a window so that it can be reused when the app is resumed after being suspended + Suspended(Option>), +} + +fn main() -> Result<()> { + // Setup a bunch of state: + + // The vello RenderContext which is a global context that lasts for the lifetime of the application + let mut render_cx = RenderContext::new().unwrap(); + + // An array of renderers, one per wgpu device + let mut renderers: Vec> = vec![]; + + // State for our example where we store the winit Window and the wgpu Surface + let mut render_state = RenderState::Suspended(None); + + // A vello Scene which is a data structure which allows one to build up a description a scene to be drawn + // (with paths, fills, images, text, etc) which is then passed to a renderer for rendering + let mut scene = Scene::new(); + + // Create and run a winit event loop + let event_loop = EventLoop::new()?; + event_loop + .run(move |event, event_loop| match event { + // Setup renderer. In winit apps it is recommended to do setup in Event::Resumed + // for best cross-platform compatibility + Event::Resumed => { + let RenderState::Suspended(cached_window) = &mut render_state else { + return; + }; + + // Get the winit window cached in a previous Suspended event or else create a new window + let window = cached_window + .take() + .unwrap_or_else(|| create_winit_window(event_loop)); + + // Create a vello Surface + let size = window.inner_size(); + let surface_future = + render_cx.create_surface(window.clone(), size.width, size.height); + let surface = pollster::block_on(surface_future).expect("Error creating surface"); + + // Create a vello Renderer for the surface (using its device id) + renderers.resize_with(render_cx.devices.len(), || None); + renderers[surface.dev_id] + .get_or_insert_with(|| create_vello_renderer(&render_cx, &surface)); + + // Save the Window and Surface to a state variable + render_state = RenderState::Active(ActiveRenderState { window, surface }); + + event_loop.set_control_flow(ControlFlow::Poll); + } + + // Save window state on suspend + Event::Suspended => { + if let RenderState::Active(state) = &render_state { + render_state = RenderState::Suspended(Some(state.window.clone())); + } + event_loop.set_control_flow(ControlFlow::Wait); + } + + Event::WindowEvent { + ref event, + window_id, + } => { + // Ignore the event (return from the function) if + // - we have no render_state + // - OR the window id of the event doesn't match the window id of our render_state + // + // Else extract a mutable reference to the render state from its containing option for use below + let render_state = match &mut render_state { + RenderState::Active(state) if state.window.id() == window_id => state, + _ => return, + }; + + match event { + // Exit the event loop when a close is requested (e.g. window's close button is pressed) + WindowEvent::CloseRequested => event_loop.exit(), + + // Resize the surface when the window is resized + WindowEvent::Resized(size) => { + render_cx.resize_surface( + &mut render_state.surface, + size.width, + size.height, + ); + render_state.window.request_redraw(); + } + + // This is where all the rendering happens + WindowEvent::RedrawRequested => { + // Empty the scene of objects to draw. You could create a new Scene each time, but in this case + // the same Scene is reused so that the underlying memory allocation can also be reused. + scene.reset(); + + // Re-add the objects to draw to the scene. + add_shapes_to_scene(&mut scene); + + // Get the RenderSurface (surface + config) + let surface = &render_state.surface; + + // Get the window size + let width = surface.config.width; + let height = surface.config.height; + + // Get a handle to the device + let device_handle = &render_cx.devices[surface.dev_id]; + + // Get the surface's texture + let surface_texture = surface + .surface + .get_current_texture() + .expect("failed to get surface texture"); + + // Render to the surface's texture + renderers[surface.dev_id] + .as_mut() + .unwrap() + .render_to_surface( + &device_handle.device, + &device_handle.queue, + &scene, + &surface_texture, + &vello::RenderParams { + base_color: Color::BLACK, // Background color + width, + height, + antialiasing_method: AaConfig::Msaa16, + }, + ) + .expect("failed to render to surface"); + + // Queue the texture to be presented on the surface + surface_texture.present(); + + device_handle.device.poll(wgpu::Maintain::Poll); + } + _ => {} + } + } + _ => {} + }) + .expect("Couldn't run event loop"); + Ok(()) +} + +/// Helper function that creates a Winit window and returns it (wrapped in an Arc for sharing between threads) +fn create_winit_window(event_loop: &winit::event_loop::EventLoopWindowTarget<()>) -> Arc { + Arc::new( + WindowBuilder::new() + .with_inner_size(LogicalSize::new(1044, 800)) + .with_resizable(true) + .with_title("Vello Shapes") + .build(event_loop) + .unwrap(), + ) +} + +/// Helper function that creates a vello Renderer for a given RenderContext and Surface +fn create_vello_renderer(render_cx: &RenderContext, surface: &RenderSurface) -> Renderer { + Renderer::new( + &render_cx.devices[surface.dev_id].device, + RendererOptions { + surface_format: Some(surface.format), + use_cpu: false, + antialiasing_support: vello::AaSupport::all(), + num_init_threads: NonZeroUsize::new(1), + }, + ) + .expect("Could create renderer") +} + +/// Add shapes to a vello scene. This does not actually render the shapes, but adds them +/// to the Scene data structure which represents a set of objects to draw. +fn add_shapes_to_scene(scene: &mut Scene) { + // Draw an outlined rectangle + let stroke = Stroke::new(6.0); + let rect = RoundedRect::new(10.0, 10.0, 240.0, 240.0, 20.0); + let rect_stroke_color = Color::rgb(0.9804, 0.702, 0.5294); + scene.stroke(&stroke, Affine::IDENTITY, rect_stroke_color, None, &rect); + + // Draw a filled circle + let circle = Circle::new((420.0, 200.0), 120.0); + let circle_fill_color = Color::rgb(0.9529, 0.5451, 0.6588); + scene.fill( + vello::peniko::Fill::NonZero, + Affine::IDENTITY, + circle_fill_color, + None, + &circle, + ); + + // Draw a filled ellipse + let ellipse = Ellipse::new((250.0, 420.0), (100.0, 160.0), -90.0); + let ellipse_fill_color = Color::rgb(0.7961, 0.651, 0.9686); + scene.fill( + vello::peniko::Fill::NonZero, + Affine::IDENTITY, + ellipse_fill_color, + None, + &ellipse, + ); + + // Draw a straight line + let line = Line::new((260.0, 20.0), (620.0, 100.0)); + let line_stroke_color = Color::rgb(0.5373, 0.7059, 0.9804); + scene.stroke(&stroke, Affine::IDENTITY, line_stroke_color, None, &line); +} diff --git a/examples/with_bevy/Cargo.toml b/examples/with_bevy/Cargo.toml index d4cdbea6c..7c8b01bb2 100644 --- a/examples/with_bevy/Cargo.toml +++ b/examples/with_bevy/Cargo.toml @@ -1,15 +1,13 @@ [package] name = "with_bevy" -description = "Example of using Vello in a Bevy application" - -version.workspace = true -license.workspace = true +description = "Example of using Vello in a Bevy application." edition.workspace = true +license.workspace = true repository.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +publish = false [dependencies] +vello = { path = "../../" } bevy = { version = "0.13", features = [ "bevy_winit", "bevy_core_pipeline", @@ -19,5 +17,3 @@ bevy = { version = "0.13", features = [ "x11", "tonemapping_luts", ], default-features = false } - -vello = { path = "../../" } diff --git a/examples/with_winit/Cargo.toml b/examples/with_winit/Cargo.toml index 206d4d230..2b2c12a7f 100644 --- a/examples/with_winit/Cargo.toml +++ b/examples/with_winit/Cargo.toml @@ -1,14 +1,11 @@ [package] name = "with_winit" +version = "0.0.0" description = "An example using vello to render to a winit window" -publish = false - -version.workspace = true -license.workspace = true edition.workspace = true +license.workspace = true repository.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +publish = false [lib] name = "with_winit" @@ -29,9 +26,9 @@ pollster = { workspace = true } wgpu-profiler = { workspace = true } wgpu = { workspace = true } -winit = "0.29.10" -env_logger = "0.10.0" -log = "0.4.17" +winit = "0.29.11" +env_logger = "0.11.2" +log = "0.4.21" [target.'cfg(not(any(target_arch = "wasm32", target_os = "android")))'.dependencies] vello = { path = "../../", features = ["hot_reload"] } @@ -39,15 +36,15 @@ notify-debouncer-mini = "0.3" [target.'cfg(target_os = "android")'.dependencies] -winit = { version = "0.29.10", features = ["android-native-activity"] } -android_logger = "0.13.0" +winit = { version = "0.29.11", features = ["android-native-activity"] } +android_logger = "0.13.3" [target.'cfg(target_arch = "wasm32")'.dependencies] console_error_panic_hook = "0.1.7" console_log = "1" -wasm-bindgen-futures = "0.4.33" +wasm-bindgen-futures = "0.4.41" # Note: pin web-sys to 0.3.67 because wgpu 0.19 depends on that exact version. # Update this when revving wgpu. Remove pin when wgpu no longer demands it. # See https://github.com/gfx-rs/wgpu/pull/5224 for more info. web-sys = { version = "=0.3.67", features = [ "HtmlCollection", "Text" ] } -getrandom = { version = "0.2.10", features = ["js"] } +getrandom = { version = "0.2.12", features = ["js"] } diff --git a/examples/with_winit/src/lib.rs b/examples/with_winit/src/lib.rs index adb5e3e5c..eb50cb305 100644 --- a/examples/with_winit/src/lib.rs +++ b/examples/with_winit/src/lib.rs @@ -630,17 +630,26 @@ pub fn main() -> Result<()> { let window = create_window(&event_loop); // On wasm, append the canvas to the document body let canvas = window.canvas().unwrap(); - let size = window.inner_size(); - canvas.set_width(size.width); - canvas.set_height(size.height); web_sys::window() .and_then(|win| win.document()) .and_then(|doc| doc.body()) .and_then(|body| body.append_child(canvas.as_ref()).ok()) .expect("couldn't append canvas to document body"); + // Best effort to start with the canvas focused, taking input _ = web_sys::HtmlElement::from(canvas).focus(); wasm_bindgen_futures::spawn_local(async move { - let size = window.inner_size(); + let (width, height, scale_factor) = web_sys::window() + .map(|w| { + ( + w.inner_width().unwrap().as_f64().unwrap(), + w.inner_height().unwrap().as_f64().unwrap(), + w.device_pixel_ratio(), + ) + }) + .unwrap(); + let size = + winit::dpi::PhysicalSize::from_logical::<_, f64>((width, height), scale_factor); + _ = window.request_inner_size(size); let surface = render_cx .create_surface(window.clone(), size.width, size.height) .await; diff --git a/integrations/vello_svg/Cargo.toml b/integrations/vello_svg/Cargo.toml index 89ec0dc1a..fcb421e90 100644 --- a/integrations/vello_svg/Cargo.toml +++ b/integrations/vello_svg/Cargo.toml @@ -3,13 +3,10 @@ name = "vello_svg" description = "Render a usvg document to a Vello scene" categories = ["rendering", "graphics"] keywords = ["2d", "vector-graphics", "vello"] - -version.workspace = true -license.workspace = true edition.workspace = true +license.workspace = true repository.workspace = true - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +publish = false [dependencies] vello = { path = "../../" }