@@ -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 {
@@ -526,6 +518,13 @@ fn serialize_fast<T: Serialize>(vec: &mut Vec<u8>, e: &T) {
526
518
bincode:: serialize_into ( & mut UnsafeVecWriter ( vec) , e, bincode:: Infinite ) . unwrap ( ) ;
527
519
}
528
520
521
+ #[ derive( Clone , Debug ) ]
522
+ pub struct SaveState {
523
+ dl_len : usize ,
524
+ clip_stack_len : usize ,
525
+ next_clip_id : u64 ,
526
+ }
527
+
529
528
#[ derive( Clone ) ]
530
529
pub struct DisplayListBuilder {
531
530
pub data : Vec < u8 > ,
@@ -537,6 +536,7 @@ pub struct DisplayListBuilder {
537
536
/// The size of the content of this display list. This is used to allow scrolling
538
537
/// outside the bounds of the display list items themselves.
539
538
content_size : LayoutSize ,
539
+ save_state : Option < SaveState > ,
540
540
}
541
541
542
542
impl DisplayListBuilder {
@@ -563,23 +563,41 @@ impl DisplayListBuilder {
563
563
next_clip_id : FIRST_CLIP_ID ,
564
564
builder_start_time : start_time,
565
565
content_size,
566
+ save_state : None ,
566
567
}
567
568
}
568
569
569
- pub fn save ( & self ) -> DisplayListBuilderSaveState {
570
- DisplayListBuilderSaveState {
570
+ /// Saves the current display list state, so it may be `restore()`'d.
571
+ ///
572
+ /// # Conditions:
573
+ ///
574
+ /// * Doesn't support popping clips that were pushed before the save.
575
+ /// * Doesn't support nested saves.
576
+ /// * Must call `clear_save()` if the restore becomes unnecessary.
577
+ pub fn save ( & mut self ) {
578
+ assert ! ( self . save_state. is_none( ) , "DisplayListBuilder doesn't support nested saves" ) ;
579
+
580
+ self . save_state = Some ( SaveState {
571
581
clip_stack_len : self . clip_stack . len ( ) ,
572
582
dl_len : self . data . len ( ) ,
573
583
next_clip_id : self . next_clip_id ,
574
- }
584
+ } ) ;
575
585
}
576
586
577
- pub fn restore ( & mut self , state : DisplayListBuilderSaveState ) {
587
+ /// Restores the state of the builder to when `save()` was last called.
588
+ pub fn restore ( & mut self ) {
589
+ let state = self . save_state . take ( ) . expect ( "No save to restore DisplayListBuilder from" ) ;
590
+
578
591
self . clip_stack . truncate ( state. clip_stack_len ) ;
579
592
self . data . truncate ( state. dl_len ) ;
580
593
self . next_clip_id = state. next_clip_id ;
581
594
}
582
595
596
+ /// Discards the builder's save (indicating the attempted operation was sucessful).
597
+ pub fn clear_save ( & mut self ) {
598
+ self . save_state . take ( ) . expect ( "No save to clear in DisplayListBuilder" ) ;
599
+ }
600
+
583
601
pub fn print_display_list ( & mut self ) {
584
602
let mut temp = BuiltDisplayList :: default ( ) ;
585
603
:: std:: mem:: swap ( & mut temp. data , & mut self . data ) ;
@@ -1136,6 +1154,10 @@ impl DisplayListBuilder {
1136
1154
1137
1155
pub fn pop_clip_id ( & mut self ) {
1138
1156
self . clip_stack . pop ( ) ;
1157
+ if let Some ( save_state) = self . save_state . as_ref ( ) {
1158
+ assert ! ( self . clip_stack. len( ) >= save_state. clip_stack_len,
1159
+ "Cannot pop clips that were pushed before the DisplayListBuilder save." ) ;
1160
+ }
1139
1161
assert ! ( self . clip_stack. len( ) > 0 ) ;
1140
1162
}
1141
1163
@@ -1155,6 +1177,8 @@ impl DisplayListBuilder {
1155
1177
}
1156
1178
1157
1179
pub fn finalize ( self ) -> ( PipelineId , LayoutSize , BuiltDisplayList ) {
1180
+ assert ! ( self . save_state. is_none( ) , "Finalized DisplayListBuilder with a pending save" ) ;
1181
+
1158
1182
let end_time = precise_time_ns ( ) ;
1159
1183
1160
1184
0 commit comments