Skip to content

Commit

Permalink
Add final touches to documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
PoignardAzur committed Mar 2, 2024
1 parent 170ecbc commit 3a3d69f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 39 deletions.
11 changes: 8 additions & 3 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Another goal of the overall project is to explain how the renderer is built, and
Much of the progress on Vello is documented in blog entries.
See [doc/blogs.md](doc/blogs.md) for pointers to those.

Ideally, we'd like our documentation to be more structured; we may refactor it in the future (see [#488]).


## Roadmap

Expand All @@ -32,15 +34,15 @@ The repository is structured as such:

- `crates/`
- `encoding/` - Types that represent the data that needs to be rendered.
- `shaders/` - Infrastructure to compile pipelines and shaders; see "Shader templating". Note that the `vello` crate doesn't currently import this crate (see issue #467).
- `shaders/` - Infrastructure to preprocess and cross-compile shaders at compile time; see "Shader templating". Note that the `vello` crate doesn't currently import this crate (see [#467]).
- `tests/` - Helper code for writing tests; current has a single smoke test and not much else.
- `doc/` - Various documents detailing the vision for Vello as it was developed. This directory should probably be refactored away; adding to it not recommended.
- `examples/` - Example projects using Vello. Each example is its own crate, with its own dependencies. The simplest example is the `shapes` one.
- `integrations/vello_svg` - An SVG rendered based on Vello and usvg. Used in examples. May be moved to `crates/` in the future.
- `shader/` - This is where the magic happens. WGSL shaders that define the compute operations (often variations of prefix sum) that Vello does to render a scene.
- `shared/` - Shared types, functions and constants included in other shaders through non-standard `#import` preprocessor directives (see "Shader templating").
- `src/` - Code for the main `vello` crate.
- `shaders/` - Same as `crates/shaders/` above. The duplication should eventually be removed (see issue #467).
- `shaders/` - Same as `crates/shaders/` above. The duplication should eventually be removed (see [#467]).
- `cpu_shader/` - Functions that perform the same work as their equivalently-named WGSL shaders for the CPU fallbacks. The name is a bit loose; they're "shaders" in the sense that they work on resource bindings with the exact same layout as actual GPU shaders.


Expand Down Expand Up @@ -85,11 +87,14 @@ In principle, other backends could consume a `Recording`, but for now the only i
The code in `cpu_shader/*.rs` and `cpu_dispatch.rs` provides *some* support for CPU-side rendering. It's in an awkward place right now:

- It's called through WgpuEngine, so the dependency on wgpu is still there.
- Fine rasterization (the part at the end that puts pixels on screen) doesn't work in CPU yet (see issue #386).
- Fine rasterization (the part at the end that puts pixels on screen) doesn't work in CPU yet (see [#386]).
- Every single WGSL shader needs a CPU equivalent, which is pretty cumbersome.

Still, it's useful for testing and debugging.


[`wgsl-analyzer`]: https://marketplace.visualstudio.com/items?itemName=wgsl-analyzer.wgsl-analyzer
[direct2d]: https://docs.microsoft.com/en-us/windows/win32/direct2d/direct2d-portal
[#488]: https://github.com/linebender/vello/issues/488
[#467]: https://github.com/linebender/vello/issues/467
[#386]: https://github.com/linebender/vello/issues/386
43 changes: 25 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,19 @@ It is used as the rendering backend for [Xilem], a Rust GUI toolkit.
> - [Properly implementing strokes](https://github.com/linebender/vello/issues/303) and [supporting all SVG stroke caps](https://github.com/linebender/vello/issues/280).
> - [Conflations artifacts](https://github.com/linebender/vello/issues/49).
> - [GPU memory allocation strategy](https://github.com/linebender/vello/issues/366)
> - [Glyph caching](https://github.com/linebender/vello/issues/204)
## Motivation

Vello is meant to fill the same place in the graphics stack as other vector graphics renderers like [Skia](https://skia.org/), [Cairo](https://www.cairographics.org/), and its predecessor project [Piet](https://github.com/linebender/piet).
On a basic level, that means it provides tools to render shapes, images, gradients, text, etc, using a PostScript-inspired API, the same that powers SVG files and [the browser `<canvas>` element](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D).

Vello's selling point is that it gets better performance than other renderers by better leveraging the GPU.
In traditional PostScript renderers, some steps of the render process like sorting and clipping either need to be handled in the CPU or done through the use of intermediary textures.
In traditional PostScript-style renderers, some steps of the render process like sorting and clipping either need to be handled in the CPU or done through the use of intermediary textures.
Vello avoids this by using prefix-sum algorithms to parallelize work that usually needs to happen in sequence, so that work can be offloaded to the GPU with minimal use of temporary buffers.

This means that Vello needs a GPU with support for compute shaders to run.


## Getting started

Expand All @@ -54,18 +57,19 @@ To use Vello as the renderer for your PDF reader / GUI toolkit / etc, your code

```rust
// Initialize wgpu and get handles
let (width, height) = ...;
let device: wgpu::Device = ...;
let queue: wgpu::Queue = ...;
let surface: wgpu::Surface<'_> = ...;
let texture_format: wgpu::TextureFormat = ...;
let mut renderer = Renderer::new(
&device,
RendererOptions {
surface_format: Some(texture_format),
use_cpu: false,
antialiasing_support: vello::AaSupport::all(),
num_init_threads: NonZeroUsize::new(1),
},
&device,
RendererOptions {
surface_format: Some(texture_format),
use_cpu: false,
antialiasing_support: vello::AaSupport::all(),
num_init_threads: NonZeroUsize::new(1),
},
).expect("Failed to create renderer");

// Create scene and draw stuff in it
Expand All @@ -87,17 +91,20 @@ scene.pop_layer(...);
// Render to your window/buffer/etc.
let surface_texture = surface.get_current_texture()
.expect("failed to get surface texture");
vello::block_on_wgpu(
renderer
.render_to_surface(
&device,
renderer
.render_to_surface_async(
&device,
&queue,
&scene,
&surface_texture,
&render_params,
),
).expect("Failed to render to surface");
&queue,
&scene,
&surface_texture,
&vello::RenderParams {
base_color: Color::BLACK, // Background color
width,
height,
antialiasing_method: AaConfig::Msaa16,
},
)
.expect("Failed to render to surface");
surface_texture.present();
```

Expand Down
42 changes: 24 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
//! On a basic level, that means it provides tools to render shapes, images, gradients, texts, etc, using a PostScript-inspired API, the same that powers SVG files and [the browser `<canvas>` element](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D).
//!
//! Vello's selling point is that it gets better performance than other renderers by better leveraging the GPU.
//! In traditional PostScript renderers, some steps of the render process like sorting and clipping either need to be handled in the CPU or done through the use of intermediary textures.
//! In traditional PostScript-style renderers, some steps of the render process like sorting and clipping either need to be handled in the CPU or done through the use of intermediary textures.
//! Vello avoids this by using prefix-scan algorithms to parallelize work that usually needs to happen in sequence, so that work can be offloaded to the GPU with minimal use of temporary buffers.
//!
//! This means that Vello needs a GPU with support for compute shaders to run.
//!
//!
//! ## Getting started
//!
Expand All @@ -28,18 +30,19 @@
//!
//! ```ignore
//! // Initialize wgpu and get handles
//! let (width, height) = ...;
//! let device: wgpu::Device = ...;
//! let queue: wgpu::Queue = ...;
//! let surface: wgpu::Surface<'_> = ...;
//! let texture_format: wgpu::TextureFormat = ...;
//! let mut renderer = Renderer::new(
//! &device,
//! RendererOptions {
//! surface_format: Some(texture_format),
//! use_cpu: false,
//! antialiasing_support: vello::AaSupport::all(),
//! num_init_threads: NonZeroUsize::new(1),
//! },
//! &device,
//! RendererOptions {
//! surface_format: Some(texture_format),
//! use_cpu: false,
//! antialiasing_support: vello::AaSupport::all(),
//! num_init_threads: NonZeroUsize::new(1),
//! },
//! ).expect("Failed to create renderer");
//!
//! // Create scene and draw stuff in it
Expand All @@ -61,17 +64,20 @@
//! // Render to your window/buffer/etc.
//! let surface_texture = surface.get_current_texture()
//! .expect("failed to get surface texture");
//! vello::block_on_wgpu(
//! renderer
//! .render_to_surface(
//! &device,
//! renderer
//! .render_to_surface_async(
//! &device,
//! &queue,
//! &scene,
//! &surface_texture,
//! &render_params,
//! ),
//! ).expect("Failed to render to surface");
//! &queue,
//! &scene,
//! &surface_texture,
//! &vello::RenderParams {
//! base_color: Color::BLACK, // Background color
//! width,
//! height,
//! antialiasing_method: AaConfig::Msaa16,
//! },
//! )
//! .expect("Failed to render to surface");
//! surface_texture.present();
//! ```
//!
Expand Down

0 comments on commit 3a3d69f

Please sign in to comment.