@@ -51,14 +51,6 @@ impl<T> ItemRange<T> {
51
51
}
52
52
}
53
53
54
- #[ repr( C ) ]
55
- #[ derive( Debug ) ]
56
- pub struct DisplayListBuilderSaveState {
57
- dl_len : usize ,
58
- clip_stack_len : usize ,
59
- next_clip_id : u64 ,
60
- }
61
-
62
54
/// A display list.
63
55
#[ derive( Clone , Default ) ]
64
56
pub struct BuiltDisplayList {
@@ -533,6 +525,13 @@ fn serialize_fast<T: Serialize>(vec: &mut Vec<u8>, e: &T) {
533
525
debug_assert ! ( ( ( w. 0 as usize ) - ( vec. as_ptr( ) as usize ) ) == vec. len( ) ) ;
534
526
}
535
527
528
+ #[ derive( Clone , Debug ) ]
529
+ pub struct SaveState {
530
+ dl_len : usize ,
531
+ clip_stack_len : usize ,
532
+ next_clip_id : u64 ,
533
+ }
534
+
536
535
#[ derive( Clone ) ]
537
536
pub struct DisplayListBuilder {
538
537
pub data : Vec < u8 > ,
@@ -544,6 +543,7 @@ pub struct DisplayListBuilder {
544
543
/// The size of the content of this display list. This is used to allow scrolling
545
544
/// outside the bounds of the display list items themselves.
546
545
content_size : LayoutSize ,
546
+ save_state : Option < SaveState > ,
547
547
}
548
548
549
549
impl DisplayListBuilder {
@@ -570,23 +570,41 @@ impl DisplayListBuilder {
570
570
next_clip_id : FIRST_CLIP_ID ,
571
571
builder_start_time : start_time,
572
572
content_size,
573
+ save_state : None ,
573
574
}
574
575
}
575
576
576
- pub fn save ( & self ) -> DisplayListBuilderSaveState {
577
- DisplayListBuilderSaveState {
577
+ /// Saves the current display list state, so it may be `restore()`'d.
578
+ ///
579
+ /// # Conditions:
580
+ ///
581
+ /// * Doesn't support popping clips that were pushed before the save.
582
+ /// * Doesn't support nested saves.
583
+ /// * Must call `clear_save()` if the restore becomes unnecessary.
584
+ pub fn save ( & mut self ) {
585
+ assert ! ( self . save_state. is_none( ) , "DisplayListBuilder doesn't support nested saves" ) ;
586
+
587
+ self . save_state = Some ( SaveState {
578
588
clip_stack_len : self . clip_stack . len ( ) ,
579
589
dl_len : self . data . len ( ) ,
580
590
next_clip_id : self . next_clip_id ,
581
- }
591
+ } ) ;
582
592
}
583
593
584
- pub fn restore ( & mut self , state : DisplayListBuilderSaveState ) {
594
+ /// Restores the state of the builder to when `save()` was last called.
595
+ pub fn restore ( & mut self ) {
596
+ let state = self . save_state . take ( ) . expect ( "No save to restore DisplayListBuilder from" ) ;
597
+
585
598
self . clip_stack . truncate ( state. clip_stack_len ) ;
586
599
self . data . truncate ( state. dl_len ) ;
587
600
self . next_clip_id = state. next_clip_id ;
588
601
}
589
602
603
+ /// Discards the builder's save (indicating the attempted operation was sucessful).
604
+ pub fn clear_save ( & mut self ) {
605
+ self . save_state . take ( ) . expect ( "No save to clear in DisplayListBuilder" ) ;
606
+ }
607
+
590
608
pub fn print_display_list ( & mut self ) {
591
609
let mut temp = BuiltDisplayList :: default ( ) ;
592
610
:: std:: mem:: swap ( & mut temp. data , & mut self . data ) ;
@@ -1143,6 +1161,10 @@ impl DisplayListBuilder {
1143
1161
1144
1162
pub fn pop_clip_id ( & mut self ) {
1145
1163
self . clip_stack . pop ( ) ;
1164
+ if let Some ( save_state) = self . save_state . as_ref ( ) {
1165
+ assert ! ( self . clip_stack. len( ) >= save_state. clip_stack_len,
1166
+ "Cannot pop clips that were pushed before the DisplayListBuilder save." ) ;
1167
+ }
1146
1168
assert ! ( self . clip_stack. len( ) > 0 ) ;
1147
1169
}
1148
1170
@@ -1162,6 +1184,8 @@ impl DisplayListBuilder {
1162
1184
}
1163
1185
1164
1186
pub fn finalize ( self ) -> ( PipelineId , LayoutSize , BuiltDisplayList ) {
1187
+ assert ! ( self . save_state. is_none( ) , "Finalized DisplayListBuilder with a pending save" ) ;
1188
+
1165
1189
let end_time = precise_time_ns ( ) ;
1166
1190
1167
1191
0 commit comments