22// SPDX-License-Identifier: Apache-2.0 OR MIT
33
44use crate :: Error ;
5- use imaging:: { ImageBrush , ImageRef } ;
6- use peniko:: ImageData ;
5+ use imaging:: { ImageBrush , ImageRef , SceneImage , SceneImageWeak } ;
6+ use peniko:: { Blob , ImageAlphaType , ImageData , ImageFormat } ;
77use std:: collections:: VecDeque ;
88use std:: hash:: { DefaultHasher , Hash , Hasher } ;
9+ use std:: sync:: Arc ;
910use vello_common:: paint:: { Image as VelloImage , ImageId , ImageSource } ;
1011
1112#[ derive( Debug ) ]
1213pub ( crate ) struct HybridImageRegistry {
1314 live : VecDeque < RegisteredImage > ,
15+ scene_images : VecDeque < CachedSceneImage > ,
1416 bytes_used : usize ,
1517 max_bytes : usize ,
1618}
@@ -25,6 +27,7 @@ impl HybridImageRegistry {
2527 pub ( crate ) fn new ( max_bytes : usize ) -> Self {
2628 Self {
2729 live : VecDeque :: new ( ) ,
30+ scene_images : VecDeque :: new ( ) ,
2831 bytes_used : 0 ,
2932 max_bytes,
3033 }
@@ -35,6 +38,7 @@ impl HybridImageRegistry {
3538 renderer : & ' a mut vello_hybrid:: Renderer ,
3639 device : & ' a wgpu:: Device ,
3740 queue : & ' a wgpu:: Queue ,
41+ tolerance : f64 ,
3842 mut encoder : wgpu:: CommandEncoder ,
3943 ) -> HybridImageUploadSession < ' a > {
4044 // We evict excess images at the start of the session,
@@ -50,6 +54,7 @@ impl HybridImageRegistry {
5054 renderer,
5155 device,
5256 queue,
57+ tolerance,
5358 encoder : Some ( encoder) ,
5459 pending : Vec :: new ( ) ,
5560 }
@@ -102,22 +107,78 @@ pub(crate) struct HybridImageUploadSession<'a> {
102107 renderer : & ' a mut vello_hybrid:: Renderer ,
103108 device : & ' a wgpu:: Device ,
104109 queue : & ' a wgpu:: Queue ,
110+ tolerance : f64 ,
105111 encoder : Option < wgpu:: CommandEncoder > ,
106112 pending : Vec < RegisteredImage > ,
107113}
108114
109115impl HybridImageUploadSession < ' _ > {
116+ pub ( crate ) fn realize_scene_image (
117+ & mut self ,
118+ scene_image : & SceneImage ,
119+ ) -> Result < ImageData , Error > {
120+ self . registry
121+ . scene_images
122+ . retain ( |entry| entry. scene_image . upgrade ( ) . is_some ( ) ) ;
123+
124+ if let Some ( entry) = self . registry . scene_images . iter ( ) . find ( |entry| {
125+ entry. scene_image_id == scene_image. id ( )
126+ && entry. width == scene_image. width ( )
127+ && entry. height == scene_image. height ( )
128+ && entry. tolerance == self . tolerance
129+ } ) {
130+ return Ok ( entry. image . clone ( ) ) ;
131+ }
132+
133+ let ( width, height) = crate :: VelloHybridRendererState :: checked_size (
134+ scene_image. width ( ) ,
135+ scene_image. height ( ) ,
136+ ) ?;
137+ let mut renderer = crate :: VelloHybridRenderer :: new ( self . device . clone ( ) , self . queue . clone ( ) ) ;
138+ renderer. set_tolerance ( self . tolerance ) ;
139+ let native = renderer. encode_scene ( scene_image. scene ( ) , width, height) ?;
140+ let image = renderer. render ( & native, width, height) ?;
141+ let image = ImageData {
142+ data : Blob :: new ( Arc :: new ( image. data ) ) ,
143+ format : ImageFormat :: Rgba8 ,
144+ alpha_type : ImageAlphaType :: Alpha ,
145+ width : scene_image. width ( ) ,
146+ height : scene_image. height ( ) ,
147+ } ;
148+ self . registry . scene_images . push_back ( CachedSceneImage {
149+ scene_image : scene_image. downgrade ( ) ,
150+ scene_image_id : scene_image. id ( ) ,
151+ width : scene_image. width ( ) ,
152+ height : scene_image. height ( ) ,
153+ tolerance : self . tolerance ,
154+ image : image. clone ( ) ,
155+ } ) ;
156+ Ok ( image)
157+ }
110158 pub ( crate ) fn resolve_image_brush ( & mut self , brush : & ImageBrush ) -> Result < VelloImage , Error > {
111- let ImageRef :: Raster ( image) = brush. image . as_ref ( ) else {
112- return Err ( Error :: UnsupportedImageBrush ) ;
159+ let key = match brush. image . as_ref ( ) {
160+ ImageRef :: Raster ( image) => ImageKey :: Raster ( ImageDataKey :: derive ( image) ) ,
161+ ImageRef :: Scene ( scene_image) => ImageKey :: Scene ( SceneImageKey {
162+ scene_image_id : scene_image. id ( ) ,
163+ width : scene_image. width ( ) ,
164+ height : scene_image. height ( ) ,
165+ tolerance : self . tolerance . to_bits ( ) ,
166+ } ) ,
113167 } ;
114- let key = ImageKey :: derive ( image) ;
115168 let image = if let Some ( image) = self . pending . iter ( ) . find ( |ri| ri. key == key) . copied ( ) {
116169 image
117170 } else if let Some ( index) = self . registry . live . iter ( ) . position ( |ri| ri. key == key) {
118171 let index = self . registry . touch ( index) ;
119172 self . registry . live . get ( index) . copied ( ) . unwrap ( )
120173 } else {
174+ let realized_image;
175+ let image = match brush. image . as_ref ( ) {
176+ ImageRef :: Raster ( image) => image,
177+ ImageRef :: Scene ( scene_image) => {
178+ realized_image = self . realize_scene_image ( scene_image) ?;
179+ & realized_image
180+ }
181+ } ;
121182 let image_source = ImageSource :: from_peniko_image_data ( image) ;
122183 let ImageSource :: Pixmap ( pixmap) = image_source else {
123184 return Err ( Error :: Internal (
@@ -185,15 +246,21 @@ struct RegisteredImage {
185246}
186247
187248#[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
188- struct ImageKey {
189- format : core:: mem:: Discriminant < peniko:: ImageFormat > ,
190- alpha_type : core:: mem:: Discriminant < peniko:: ImageAlphaType > ,
249+ enum ImageKey {
250+ Raster ( ImageDataKey ) ,
251+ Scene ( SceneImageKey ) ,
252+ }
253+
254+ #[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
255+ struct ImageDataKey {
256+ format : core:: mem:: Discriminant < ImageFormat > ,
257+ alpha_type : core:: mem:: Discriminant < ImageAlphaType > ,
191258 width : u32 ,
192259 height : u32 ,
193260 data_hash : u64 ,
194261}
195262
196- impl ImageKey {
263+ impl ImageDataKey {
197264 fn derive ( image : & ImageData ) -> Self {
198265 let mut hasher = DefaultHasher :: new ( ) ;
199266 image. data . data ( ) . hash ( & mut hasher) ;
@@ -207,11 +274,29 @@ impl ImageKey {
207274 }
208275}
209276
277+ #[ derive( Clone , Copy , Debug , Eq , Hash , PartialEq ) ]
278+ struct SceneImageKey {
279+ scene_image_id : u64 ,
280+ width : u32 ,
281+ height : u32 ,
282+ tolerance : u64 ,
283+ }
284+
285+ #[ derive( Clone , Debug ) ]
286+ struct CachedSceneImage {
287+ scene_image : SceneImageWeak ,
288+ scene_image_id : u64 ,
289+ width : u32 ,
290+ height : u32 ,
291+ tolerance : f64 ,
292+ image : ImageData ,
293+ }
294+
210295#[ cfg( test) ]
211296mod tests {
212297 use crate :: image_registry:: HybridImageRegistry ;
213298
214- use super :: { ImageKey , RegisteredImage } ;
299+ use super :: { ImageDataKey , ImageKey , RegisteredImage , SceneImageKey } ;
215300 use peniko:: { Blob , ImageAlphaType , ImageData , ImageFormat } ;
216301 use std:: collections:: VecDeque ;
217302 use std:: sync:: Arc ;
@@ -231,18 +316,33 @@ mod tests {
231316 fn image_key_dedupes_equivalent_image_contents ( ) {
232317 let a = image ( [ 1 , 2 , 3 , 4 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 10 , 11 , 12 , 13 ] ) ;
233318 let b = image ( [ 1 , 2 , 3 , 4 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 10 , 11 , 12 , 13 ] ) ;
234- assert_eq ! ( ImageKey :: derive( & a) , ImageKey :: derive( & b) ) ;
319+ assert_eq ! ( ImageDataKey :: derive( & a) , ImageDataKey :: derive( & b) ) ;
235320 }
236321
237322 #[ test]
238323 fn image_key_distinguishes_metadata_changes ( ) {
239324 let mut a = image ( [ 1 , 2 , 3 , 4 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 10 , 11 , 12 , 13 ] ) ;
240325 let mut b = a. clone ( ) ;
241326 b. alpha_type = ImageAlphaType :: AlphaPremultiplied ;
242- assert_ne ! ( ImageKey :: derive( & a) , ImageKey :: derive( & b) ) ;
327+ assert_ne ! ( ImageDataKey :: derive( & a) , ImageDataKey :: derive( & b) ) ;
243328
244329 a. format = ImageFormat :: Bgra8 ;
245- assert_ne ! ( ImageKey :: derive( & a) , ImageKey :: derive( & b) ) ;
330+ assert_ne ! ( ImageDataKey :: derive( & a) , ImageDataKey :: derive( & b) ) ;
331+ }
332+
333+ #[ test]
334+ fn scene_image_key_distinguishes_scene_identity ( ) {
335+ let a = SceneImageKey {
336+ scene_image_id : 1 ,
337+ width : 2 ,
338+ height : 3 ,
339+ tolerance : 0.1_f64 . to_bits ( ) ,
340+ } ;
341+ let b = SceneImageKey {
342+ scene_image_id : 2 ,
343+ ..a
344+ } ;
345+ assert_ne ! ( a, b) ;
246346 }
247347
248348 #[ test]
@@ -252,8 +352,8 @@ mod tests {
252352
253353 let bytes_used = a. data . len ( ) + b. data . len ( ) ;
254354
255- let a_key = ImageKey :: derive ( & a) ;
256- let b_key = ImageKey :: derive ( & b) ;
355+ let a_key = ImageKey :: Raster ( ImageDataKey :: derive ( & a) ) ;
356+ let b_key = ImageKey :: Raster ( ImageDataKey :: derive ( & b) ) ;
257357
258358 let a_ri = RegisteredImage {
259359 key : a_key,
@@ -274,6 +374,7 @@ mod tests {
274374
275375 let mut registry = HybridImageRegistry {
276376 live,
377+ scene_images : VecDeque :: new ( ) ,
277378 max_bytes : 1000 * 1000 * 1000 ,
278379 bytes_used,
279380 } ;
0 commit comments