33
44use alloc:: { sync:: Arc , vec:: Vec } ;
55
6- use peniko:: { BlendMode , kurbo:: Affine } ;
6+ use peniko:: { BlendMode , ImageBrush , kurbo:: Affine } ;
77
88use 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
6671impl 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
8996pub 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