mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-08 20:01:30 +11:00
[vello_encoding] Move the encoding module into its own crate
This change moves the vello encoding logic to a new crate under crates/encoding. Combined with the `vello_shaders` crate, this enables lightweight integration of the Vello pipelines into renderers that don't depend on wgpu (or perhaps written in languages other than Rust). The Scene/Fragment API currently remain the vello crate.
This commit is contained in:
parent
b8e1bcfac3
commit
db2fefdc8f
12
Cargo.toml
12
Cargo.toml
|
@ -2,6 +2,7 @@
|
|||
resolver = "2"
|
||||
|
||||
members = [
|
||||
"crates/encoding",
|
||||
"crates/shaders",
|
||||
|
||||
"integrations/vello_svg",
|
||||
|
@ -40,17 +41,20 @@ hot_reload = []
|
|||
buffer_labels = []
|
||||
|
||||
[dependencies]
|
||||
bytemuck = { workspace = true }
|
||||
fello = { workspace = true }
|
||||
peniko = { workspace = true }
|
||||
wgpu = { workspace = true }
|
||||
raw-window-handle = "0.5"
|
||||
futures-intrusive = "0.5.0"
|
||||
parking_lot = "0.12"
|
||||
bytemuck = { version = "1.12.1", features = ["derive"] }
|
||||
smallvec = "1.8.0"
|
||||
fello = { git = "https://github.com/dfrg/fount", rev = "58a284eaae67512fb61cf76177c5d33238d79cb1" }
|
||||
peniko = { git = "https://github.com/linebender/peniko", rev = "cafdac9a211a0fb2fec5656bd663d1ac770bcc81" }
|
||||
guillotiere = "0.6.2"
|
||||
vello_encoding = { path = "crates/encoding" }
|
||||
|
||||
[workspace.dependencies]
|
||||
bytemuck = { version = "1.12.1", features = ["derive"] }
|
||||
fello = { git = "https://github.com/dfrg/fount", rev = "58a284eaae67512fb61cf76177c5d33238d79cb1" }
|
||||
peniko = { git = "https://github.com/linebender/peniko", rev = "cafdac9a211a0fb2fec5656bd663d1ac770bcc81" }
|
||||
wgpu = "0.15"
|
||||
|
||||
# Used for examples
|
||||
|
|
10
crates/encoding/Cargo.toml
Normal file
10
crates/encoding/Cargo.toml
Normal file
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "vello_encoding"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
bytemuck = { workspace = true }
|
||||
fello = { workspace = true }
|
||||
peniko = { workspace = true }
|
||||
guillotiere = "0.6.2"
|
|
@ -14,11 +14,9 @@
|
|||
//
|
||||
// Also licensed under MIT license, at your choice.
|
||||
|
||||
use crate::encoding::DrawImage;
|
||||
|
||||
use super::{
|
||||
resolve::Patch, DrawColor, DrawLinearGradient, DrawRadialGradient, DrawTag, Glyph, GlyphRun,
|
||||
PathEncoder, PathTag, Transform,
|
||||
resolve::Patch, DrawColor, DrawImage, DrawLinearGradient, DrawRadialGradient, DrawTag, Glyph,
|
||||
GlyphRun, PathEncoder, PathTag, Transform,
|
||||
};
|
||||
|
||||
use fello::NormalizedCoord;
|
|
@ -59,11 +59,11 @@ impl GlyphCache {
|
|||
Style::Fill(Fill::EvenOdd) => encoding_cache.encode_linewidth(-2.0),
|
||||
Style::Stroke(stroke) => encoding_cache.encode_linewidth(stroke.width),
|
||||
}
|
||||
let mut path = crate::glyph::PathEncoderPen(encoding_cache.encode_path(is_fill));
|
||||
let mut path = encoding_cache.encode_path(is_fill);
|
||||
scaler
|
||||
.outline(GlyphId::new(key.glyph_id as u16), &mut path)
|
||||
.ok()?;
|
||||
if path.0.finish(false) == 0 {
|
||||
if path.finish(false) == 0 {
|
||||
return None;
|
||||
}
|
||||
let end = encoding_cache.stream_offsets();
|
|
@ -381,3 +381,25 @@ impl<'a> PathEncoder<'a> {
|
|||
self.n_encoded_segments
|
||||
}
|
||||
}
|
||||
|
||||
impl fello::scale::Pen for PathEncoder<'_> {
|
||||
fn move_to(&mut self, x: f32, y: f32) {
|
||||
self.move_to(x, y)
|
||||
}
|
||||
|
||||
fn line_to(&mut self, x: f32, y: f32) {
|
||||
self.line_to(x, y)
|
||||
}
|
||||
|
||||
fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) {
|
||||
self.quad_to(cx0, cy0, x, y)
|
||||
}
|
||||
|
||||
fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) {
|
||||
self.cubic_to(cx0, cy0, cx1, cy1, x, y)
|
||||
}
|
||||
|
||||
fn close(&mut self) {
|
||||
self.close()
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@ use super::{
|
|||
ramp_cache::{RampCache, Ramps},
|
||||
DrawTag, Encoding, PathTag, StreamOffsets, Transform,
|
||||
};
|
||||
use crate::shaders;
|
||||
|
||||
/// Layout of a packed encoding.
|
||||
#[derive(Clone, Copy, Debug, Default, Zeroable, Pod)]
|
||||
|
@ -161,6 +160,7 @@ impl Resolver {
|
|||
&'a mut self,
|
||||
encoding: &Encoding,
|
||||
packed: &mut Vec<u8>,
|
||||
workgroup_size: u32,
|
||||
) -> (Layout, Ramps<'a>, Images<'a>) {
|
||||
let sizes = self.resolve_patches(encoding);
|
||||
self.resolve_pending_images();
|
||||
|
@ -172,7 +172,7 @@ impl Resolver {
|
|||
// Compute size of data buffer
|
||||
let n_path_tags =
|
||||
encoding.path_tags.len() + sizes.path_tags + encoding.n_open_clips as usize;
|
||||
let path_tag_padded = align_up(n_path_tags, 4 * shaders::PATHTAG_REDUCE_WG);
|
||||
let path_tag_padded = align_up(n_path_tags, 4 * workgroup_size);
|
||||
let capacity = path_tag_padded
|
||||
+ slice_size_in_bytes(&encoding.path_data, sizes.path_data)
|
||||
+ slice_size_in_bytes(
|
|
@ -12,6 +12,7 @@ repository.workspace = true
|
|||
|
||||
[dependencies]
|
||||
vello = { path = "../../" }
|
||||
vello_encoding = { path = "../../crates/encoding" }
|
||||
vello_svg = { path = "../../integrations/vello_svg" }
|
||||
anyhow = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive"] }
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use vello::{
|
||||
encoding::Glyph,
|
||||
fello::meta::MetadataProvider,
|
||||
fello::raw::FontRef,
|
||||
glyph::GlyphContext,
|
||||
|
@ -25,6 +24,7 @@ use vello::{
|
|||
peniko::{Blob, Brush, BrushRef, Font, StyleRef},
|
||||
SceneBuilder,
|
||||
};
|
||||
use vello_encoding::Glyph;
|
||||
|
||||
// This is very much a hack to get things working.
|
||||
// On Windows, can set this to "c:\\Windows\\Fonts\\seguiemj.ttf" to get color emoji
|
||||
|
|
49
src/glyph.rs
49
src/glyph.rs
|
@ -16,18 +16,17 @@
|
|||
|
||||
//! Support for glyph rendering.
|
||||
|
||||
use fello::scale::Pen;
|
||||
|
||||
use crate::encoding::{Encoding, PathEncoder};
|
||||
use crate::scene::{SceneBuilder, SceneFragment};
|
||||
use peniko::kurbo::Affine;
|
||||
use peniko::{Brush, Color, Fill, Style};
|
||||
|
||||
use fello::{
|
||||
raw::types::GlyphId,
|
||||
raw::FontRef,
|
||||
scale::{Context, Scaler},
|
||||
FontKey, Setting, Size,
|
||||
use {
|
||||
fello::{
|
||||
raw::types::GlyphId,
|
||||
raw::FontRef,
|
||||
scale::{Context, Pen, Scaler},
|
||||
FontKey, Setting, Size,
|
||||
},
|
||||
peniko::kurbo::Affine,
|
||||
peniko::{Brush, Color, Fill, Style},
|
||||
vello_encoding::Encoding,
|
||||
};
|
||||
|
||||
/// General context for creating scene fragments for glyph outlines.
|
||||
|
@ -105,9 +104,9 @@ impl<'a> GlyphProvider<'a> {
|
|||
Style::Fill(Fill::EvenOdd) => encoding.encode_linewidth(-2.0),
|
||||
Style::Stroke(stroke) => encoding.encode_linewidth(stroke.width),
|
||||
}
|
||||
let mut path = PathEncoderPen(encoding.encode_path(matches!(style, Style::Fill(_))));
|
||||
let mut path = encoding.encode_path(matches!(style, Style::Fill(_)));
|
||||
self.scaler.outline(GlyphId::new(gid), &mut path).ok()?;
|
||||
if path.0.finish(false) != 0 {
|
||||
if path.finish(false) != 0 {
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
|
@ -144,27 +143,3 @@ impl Pen for BezPathPen {
|
|||
self.0.close_path()
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct PathEncoderPen<'a>(pub PathEncoder<'a>);
|
||||
|
||||
impl Pen for PathEncoderPen<'_> {
|
||||
fn move_to(&mut self, x: f32, y: f32) {
|
||||
self.0.move_to(x, y)
|
||||
}
|
||||
|
||||
fn line_to(&mut self, x: f32, y: f32) {
|
||||
self.0.line_to(x, y)
|
||||
}
|
||||
|
||||
fn quad_to(&mut self, cx0: f32, cy0: f32, x: f32, y: f32) {
|
||||
self.0.quad_to(cx0, cy0, x, y)
|
||||
}
|
||||
|
||||
fn curve_to(&mut self, cx0: f32, cy0: f32, cx1: f32, cy1: f32, x: f32, y: f32) {
|
||||
self.0.cubic_to(cx0, cy0, cx1, cy1, x, y)
|
||||
}
|
||||
|
||||
fn close(&mut self) {
|
||||
self.0.close()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
//! Take an encoded scene and create a graph to render it
|
||||
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
|
||||
use crate::{
|
||||
encoding::{Config, Encoding, Layout},
|
||||
engine::{BufProxy, ImageFormat, ImageProxy, Recording, ResourceProxy},
|
||||
shaders::{self, FullShaders, Shaders},
|
||||
RenderParams, Scene,
|
||||
};
|
||||
use {
|
||||
bytemuck::{Pod, Zeroable},
|
||||
vello_encoding::{Config, Encoding, Layout},
|
||||
};
|
||||
|
||||
|
||||
/// State for a render in progress.
|
||||
pub struct Render {
|
||||
|
@ -213,11 +215,11 @@ impl Render {
|
|||
params: &RenderParams,
|
||||
robust: bool,
|
||||
) -> Recording {
|
||||
use crate::encoding::Resolver;
|
||||
use vello_encoding::Resolver;
|
||||
let mut recording = Recording::default();
|
||||
let mut resolver = Resolver::new();
|
||||
let mut packed = vec![];
|
||||
let (layout, ramps, images) = resolver.resolve(encoding, &mut packed);
|
||||
let (layout, ramps, images) = resolver.resolve(encoding, &mut packed, shaders::PATHTAG_REDUCE_WG);
|
||||
let gradient_image = if ramps.height == 0 {
|
||||
ResourceProxy::new_image(1, 1, ImageFormat::Rgba8)
|
||||
} else {
|
||||
|
@ -245,7 +247,7 @@ impl Render {
|
|||
let new_height = next_multiple_of(params.height, 16);
|
||||
|
||||
let info_size = layout.bin_data_start;
|
||||
let config = crate::encoding::Config {
|
||||
let config = vello_encoding::Config {
|
||||
width_in_tiles: new_width / 16,
|
||||
height_in_tiles: new_height / 16,
|
||||
target_width: params.width,
|
||||
|
|
|
@ -17,8 +17,7 @@
|
|||
use fello::NormalizedCoord;
|
||||
use peniko::kurbo::{Affine, Rect, Shape};
|
||||
use peniko::{BlendMode, BrushRef, Color, Fill, Font, Image, Stroke, StyleRef};
|
||||
|
||||
use crate::encoding::{Encoding, Glyph, GlyphRun, Patch, Transform};
|
||||
use vello_encoding::{Encoding, Glyph, GlyphRun, Patch, Transform};
|
||||
|
||||
/// Encoded definition of a scene and associated resources.
|
||||
#[derive(Default)]
|
||||
|
|
Loading…
Reference in a new issue