blob: 27fb3463ba901edad3d751160f59619818d0f4b9 [file]
// Copyright 2025 the Vello Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// After you edit the crate's doc comment, run this command, then check README.md for any missing links
// cargo rdme --workspace-project=vello_api
// These docs are written for a more complete version of Vello API.
//! Vello API is the **experimental** rendering API of the 2D renderers in the Vello project.
//!
//! Warning: Vello API is currently only released as a preview, and is not ready for usage beyond short-term experiments.
//! We know of several design decisions which will change before its use can be recommended.
//!
//! There are currently two [supported Vello renderers](#renderers), each with different tradeoffs.
//! This crate allows you to write the majority of your application logic to support either of those renderers.
//! These renderers are [Vello CPU](todo) and [Vello Hybrid](todo).
//!
//! # Usage
//!
//! TODO: Mention Renderer trait when it exists. Otherwise, this code isn't really usable yet.
//! TODO: This is a stub just to have an outline to push.
//!
//! # Renderers
//!
//! The Vello renderers which support this API are:
//!
//! - Vello CPU, an extremely portable 2D renderer which does not require a GPU.
//! It is one of the fastest CPU-only 2D renderers in Rust.
//! - Vello Hybrid, which runs the most compute intensive portions of rendering on the GPU, improving performance over Vello CPU.
//! It will have wide compatibility with most devices, so long as they have a GPU, including running well on the web.
//! <!-- We might also have, to be determined:
//! - Vello Classic, which performs almost all rendering on the GPU, which gives great performance on devices with decent GPUs.
//! However, it cannot run well on devices with weak GPUs, or in contexts without support for compute shaders, such as the web.
//! It also has unavoidably high memory usage, and can silently fail to render if the scene gets too big.
//! -->
//!
//! Currently, Vello CPU is much more mature, and so most consumers should currently prefer that implementation.
//! We hope that in the not-too distant future, application developers will be able to migrate to Vello Hybrid.
//! We expect headless use cases (such as screenshot tests or server-rendered previews) to prefer Vello CPU, due to
//! its cross-platform consistency and lower latency.
//!
//! Note that even once Vello Hybrid is more stable, applications using Vello Hybrid might need to support falling
//! back to Vello CPU for compatibility or performance reasons.
//!
//! This abstraction is tailored for the Vello renderers, as we believe that these have a sufficiently broad coverage of the trade-off
//! space to be viable for any consumer.
//! Vello API guarantees identical rendering between renderers which implement it, barring subpixel differences due to precision/different rounding.
//! This doesn't apply to renderer-specific features.
//! <!-- TODO: Is ^ true? -->
//!
//! # Abstraction Boundaries
//!
//! The abstractions in this crate are focused on 2D rendering, and the resources required to perform that.
//! In particular, this does not abstract over strategies for:
//!
//! - creating the renderer (which can require more context, such as a wgpu `Device`); nor
//! - bringing external content into the renderer (for example, already resident GPU textures); nor
//! - presenting rendered content to an operating system window.
//!
//! These functionalities are however catered for where applicable by APIs on the specific renderers.
//! The renderer API supports downcasting to the specific renderer, so that these extensions can be called.
//! Each supported renderer will/does have examples showing how to achieve this yourself.
//!
//! # Text
//!
//! Vello API does not handle text/glyph rendering itself.
//! This allows for improved resource sharing of intermediate text layout data, for hinting and ink splitting underlines.
//!
//! Text can be rendered to Vello API scenes using the "Parley Draw" crate.
//! Note that this crate is not currently implemented; design work is ongoing.
//! We also support rendering using using traditional glyph atlases, which may be preferred by some consumers.
//! This is especially useful to achieve subpixel rendering, such as ClearType, which Vello doesn't currently support directly.
//!
//! # Unimplemented Features
//!
//! NOTE: This section is not complete; in particular, we have only pushed a half-version of this API to make review more scoped.
//!
//! The current version of Vello API is a minimal viable product for exploration and later expansion.
//! As such, there are several features which we expect to be included in this API, but which are not yet exposed in this crate.
//! These are categorised as follows:
//!
//! ## Out of scope/Renderer specific
//!
//! <!-- This section can be removed once the other three classes are empty -->
//! As discussed above, some features are out-of-scope, as they have concerns which need to be handled individually by each renderer.
//! This includes:
//!
//! - Rendering directly to a surface.
//! - Importing "external" textures (e.g. from a `wgpu::Texture`)
//!
//! ## Excluded for expedience
//!
//! - Renderer specific painting commands (i.e. using downcasting).
//! This is intended to be an immediate follow-up to the MVP landing.
//! - Pushing/popping clip paths (i.e. non-isolated clipping).
//! This feature should be easy to restore, although it isn't clear how it will work with "Vello GPU", i.e. Hybrid with GPU sparse strip rendering.
//! - Downloading rendered textures back to the CPU/host.
//! This is currently supported through individual methods on the renderers, but we hope to have a portable API for coordinating this.
//! - Anti-aliasing threshold.
//! - Fill rules for clip paths.
//! - Proper error types; we currently return `()`. This is to ensure that these error types are explicitly interim.
//! - Texture resizing; this might not be viably possible
//! - More explicit texture atlas support
//! - Proper handling of where `TextureHandle` and `TextureId` should be passed.
//! - "Unsetting" the brush; this is mostly useful for append style operations, which may unexpectedly change the brush.
//! - Dynamic version of `PaintScene`, allowing `dyn PaintScene` for cases where that would be relevant.
//!
//! ## Not cross-renderer
//!
//! There are some features which are only implemented in one of our target renderers, so cannot yet be included in the generalised API.
//! As an interim solution, we intend to expose these features as renderer specific extensions (see the "excluded for expedience section").
//!
//! For Vello CPU, these are (i.e. Vello Hybrid does not implement these):
//!
//! - Masks
//! - Filter effects
//! - Non-isolated blending (this is "supported" by Vello Hybrid, but currently silently ignored)
//! - Blurred rounded rectangles (note that currently this is actually included in the abstraction, despite this status)
//!
//! There are currently no such features the other way around (i.e. which only Vello Hybrid supports).
//!
//! ## Not implemented
//!
//! - Path caching. This feature is intended to allow re-using paths efficiently, primarily for glyphs.
//! - Blurred rounded rectangle paints in custom shapes (e.g. to exclude the unblurred parts).
//! (TODO: This actually does exist as a method, but no renderer implements it; we should maybe remove that method?)
//! - Mipmaps
//!
//! For even more detail on some of these, see the `design.md` file.
//! Note however that file is very uncurated.
#![forbid(unsafe_code)]
#![no_std]
#![expect(clippy::result_unit_err, reason = "This code is very experimental.")]
extern crate alloc;
mod painter;
pub mod exact;
pub mod paths;
pub mod scene;
pub mod texture;
pub use self::painter::{PaintScene, StandardBrush};
pub use self::scene::Scene;
pub use ::peniko;