@@ -501,6 +501,21 @@ pub struct ResourceCache {
501
501
502
502
/// A pool of render targets for use by the render task graph
503
503
render_target_pool : Vec < RenderTarget > ,
504
+
505
+ /// An empty (1x1 transparent) image used when a stacking context snapshot
506
+ /// is missing.
507
+ ///
508
+ /// For now it acts as a catch-all solution for cases where WebRender fails
509
+ /// to produce a texture cache item for a snapshotted tacking context.
510
+ /// These cases include:
511
+ /// - Empty stacking contexts.
512
+ /// - Stacking contexts that are more aggressively culled out than they
513
+ /// should, for example when they are in a perspective transform that
514
+ /// cannot be projected to screen space.
515
+ /// - Likely other cases we have not found yet.
516
+ /// Over time it would be better to handle each of these cases explicitly
517
+ /// and make it a hard error to fail to snapshot a stacking context.
518
+ fallback_handle : TextureCacheHandle ,
504
519
}
505
520
506
521
impl ResourceCache {
@@ -538,6 +553,7 @@ impl ResourceCache {
538
553
image_templates_memory : 0 ,
539
554
font_templates_memory : 0 ,
540
555
render_target_pool : Vec :: new ( ) ,
556
+ fallback_handle : TextureCacheHandle :: invalid ( ) ,
541
557
}
542
558
}
543
559
@@ -661,7 +677,7 @@ impl ResourceCache {
661
677
self . texture_cache . shared_color_expected_format ( ) ,
662
678
flags,
663
679
) ;
664
-
680
+
665
681
// Allocate space in the texture cache, but don't supply
666
682
// and CPU-side data to be uploaded.
667
683
let user_data = [ 0.0 ; 4 ] ;
@@ -1342,7 +1358,19 @@ impl ResourceCache {
1342
1358
pub fn get_cached_image ( & self , request : ImageRequest ) -> Result < CacheItem , ( ) > {
1343
1359
debug_assert_eq ! ( self . state, State :: QueryResources ) ;
1344
1360
let image_info = self . get_image_info ( request) ?;
1345
- Ok ( self . get_texture_cache_item ( & image_info. texture_cache_handle ) )
1361
+
1362
+ if let Ok ( item) = self . get_texture_cache_item ( & image_info. texture_cache_handle ) {
1363
+ // Common path.
1364
+ return Ok ( item) ;
1365
+ }
1366
+
1367
+ if self . resources . image_templates
1368
+ . get ( request. key )
1369
+ . map_or ( false , |img| img. data . is_snapshot ( ) ) {
1370
+ return self . get_texture_cache_item ( & self . fallback_handle ) ;
1371
+ }
1372
+
1373
+ panic ! ( "Requested image missing from the texture cache" ) ;
1346
1374
}
1347
1375
1348
1376
pub fn get_cached_render_task (
@@ -1364,8 +1392,12 @@ impl ResourceCache {
1364
1392
}
1365
1393
1366
1394
#[ inline]
1367
- pub fn get_texture_cache_item ( & self , handle : & TextureCacheHandle ) -> CacheItem {
1368
- self . texture_cache . get ( handle)
1395
+ pub fn get_texture_cache_item ( & self , handle : & TextureCacheHandle ) -> Result < CacheItem , ( ) > {
1396
+ if let Some ( item) = self . texture_cache . try_get ( handle) {
1397
+ return Ok ( item) ;
1398
+ }
1399
+
1400
+ Err ( ( ) )
1369
1401
}
1370
1402
1371
1403
pub fn get_image_properties ( & self , image_key : ImageKey ) -> Option < ImageProperties > {
@@ -1480,6 +1512,29 @@ impl ResourceCache {
1480
1512
1481
1513
fn update_texture_cache ( & mut self , gpu_cache : & mut GpuCache ) {
1482
1514
profile_scope ! ( "update_texture_cache" ) ;
1515
+
1516
+ if self . fallback_handle == TextureCacheHandle :: invalid ( ) {
1517
+ self . texture_cache . update (
1518
+ & mut self . fallback_handle ,
1519
+ ImageDescriptor {
1520
+ size : size2 ( 1 , 1 ) ,
1521
+ stride : None ,
1522
+ format : ImageFormat :: BGRA8 ,
1523
+ flags : ImageDescriptorFlags :: empty ( ) ,
1524
+ offset : 0 ,
1525
+ } ,
1526
+ TextureFilter :: Linear ,
1527
+ Some ( CachedImageData :: Raw ( Arc :: new ( vec ! [ 0 , 0 , 0 , 0 ] ) ) ) ,
1528
+ [ 0.0 ; 4 ] ,
1529
+ DirtyRect :: All ,
1530
+ gpu_cache,
1531
+ None ,
1532
+ UvRectKind :: Rect ,
1533
+ Eviction :: Manual ,
1534
+ TargetShader :: Default ,
1535
+ ) ;
1536
+ }
1537
+
1483
1538
for request in self . pending_image_requests . drain ( ) {
1484
1539
let image_template = self . resources . image_templates . get_mut ( request. key ) . unwrap ( ) ;
1485
1540
debug_assert ! ( image_template. data. uses_texture_cache( ) ) ;
0 commit comments