Skip to content

Commit e8aacd8

Browse files
committed
Draft further the use of TextureHandle
1 parent 2d1602e commit e8aacd8

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

sparse_strips/vello_api/src/painter.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ use core::any::Any;
66
use peniko::kurbo::{Affine, BezPath, Rect, Shape, Stroke};
77
use peniko::{BlendMode, Brush, Color, Fill, ImageBrush};
88

9-
use crate::scene::Scene;
10-
use crate::texture::TextureId;
9+
use crate::scene::{OurBrush, Scene};
1110

1211
pub trait PaintScene: Any {
1312
// Error if associated with different renderer.
@@ -18,7 +17,7 @@ pub trait PaintScene: Any {
1817

1918
fn set_brush(
2019
&mut self,
21-
brush: impl Into<Brush<ImageBrush<TextureId>>>,
20+
brush: impl Into<OurBrush>,
2221
// We'd like to support both brushes which are "object-local" and brushes which are "scene-local".
2322
// Image for example you want a gradient to be applied over a whole paragraph of text.
2423
// The naive solution would need to apply the gradient with a paint transform which undoes the

sparse_strips/vello_api/src/scene.rs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33

44
use alloc::{sync::Arc, vec::Vec};
55

6-
use peniko::{BlendMode, kurbo::Affine};
6+
use peniko::{BlendMode, ImageBrush, kurbo::Affine};
77

88
use crate::{
99
PaintScene, Renderer,
1010
paths::{PathId, PathSet},
11-
texture::TextureId,
11+
texture::{TextureHandle, TextureId},
1212
};
1313

1414
#[derive(Debug)]
@@ -23,7 +23,10 @@ pub enum RenderCommand {
2323
///
2424
/// The affine is currently path local for future drawing operations.
2525
/// That is something I expect *could* change in the future/want to change.
26-
SetPaint(Affine, OurBrush),
26+
///
27+
/// This doesn't use [`OurBrush`] because we want to limit the
28+
/// number of textures stored.
29+
SetPaint(Affine, peniko::Brush<peniko::ImageBrush<TextureId>>),
2730
/// Set the paint to be a blurred rounded rectangle.
2831
///
2932
/// This is useful for box shadows.
@@ -61,6 +64,8 @@ pub struct Scene {
6164
commands: Vec<RenderCommand>,
6265
renderer: Arc<dyn Renderer>,
6366
hinted: bool,
67+
// TODO: HashSet? We'd need to bring in hashbrown, but that's probably fine
68+
textures: Vec<TextureHandle>,
6469
}
6570

6671
impl Scene {
@@ -70,6 +75,7 @@ impl Scene {
7075
paths: PathSet::new(),
7176
commands: Vec::new(),
7277
hinted,
78+
textures: Vec::new(),
7379
}
7480
}
7581
}
@@ -84,7 +90,8 @@ impl Scene {
8490
}
8591
}
8692

87-
pub type OurBrush = peniko::Brush<peniko::ImageBrush<TextureId>>;
93+
// TODO: Change module and give a better name.
94+
pub type OurBrush = peniko::Brush<peniko::ImageBrush<TextureHandle>>;
8895

8996
pub fn extract_integer_translation(transform: Affine) -> Option<(f64, f64)> {
9097
fn is_nearly(a: f64, b: f64) -> bool {
@@ -118,6 +125,7 @@ impl PaintScene for Scene {
118125
commands: other_commands,
119126
renderer: other_renderer,
120127
hinted: other_hinted,
128+
textures,
121129
}: &Scene,
122130
) -> Result<(), ()> {
123131
if !Arc::ptr_eq(&self.renderer, other_renderer) {
@@ -164,6 +172,17 @@ impl PaintScene for Scene {
164172
RenderCommand::BlurredRoundedRectPaint(brush.clone())
165173
}
166174
}));
175+
176+
// We avoid duplicating the handles where possible.
177+
// It is likely that there's a better data structure for this (a `HashSet`?)
178+
// but there isn't one provided in core/alloc.x
179+
// We expect the number of textures to be relatively small, so this O(N^2) isn't
180+
// an immediate optimisation target.
181+
for texture in textures {
182+
if !self.textures.contains(texture) {
183+
self.textures.push(texture.clone());
184+
}
185+
}
167186
Ok(())
168187
}
169188

@@ -192,8 +211,24 @@ impl PaintScene for Scene {
192211
// transform: peniko::kurbo::Affine,
193212
paint_transform: peniko::kurbo::Affine,
194213
) {
214+
let brush = match brush.into() {
215+
peniko::Brush::Image(image) => {
216+
let id = image.image.id();
217+
// We expect there to be relatively few textures per scene, so an O(n) linear scan here is *fine*
218+
// (i.e. even though it's O(N^2) for total textures in a scene, we expect N to be small)
219+
if !self.textures.contains(&image.image) {
220+
self.textures.push(image.image);
221+
}
222+
peniko::Brush::Image(ImageBrush {
223+
sampler: image.sampler,
224+
image: id,
225+
})
226+
}
227+
peniko::Brush::Solid(alpha_color) => peniko::Brush::Solid(alpha_color),
228+
peniko::Brush::Gradient(gradient) => peniko::Brush::Gradient(gradient),
229+
};
195230
self.commands
196-
.push(RenderCommand::SetPaint(paint_transform, brush.into()));
231+
.push(RenderCommand::SetPaint(paint_transform, brush));
197232
}
198233

199234
fn set_blurred_rounded_rect_brush(

0 commit comments

Comments
 (0)