@@ -17,6 +17,8 @@ use YuvImageDisplayItem;
17
17
use bincode;
18
18
use serde:: { Deserialize , Serialize , Serializer } ;
19
19
use serde:: ser:: { SerializeMap , SerializeSeq } ;
20
+ use std:: io:: Write ;
21
+ use std:: { io, ptr} ;
20
22
use std:: marker:: PhantomData ;
21
23
use time:: precise_time_ns;
22
24
@@ -483,6 +485,48 @@ impl<'a, 'b> Serialize for DisplayItemRef<'a, 'b> {
483
485
}
484
486
}
485
487
488
+ // This is a replacement for bincode::serialize_into(&vec)
489
+ // The default implementation Write for Vec will basically
490
+ // call extend_from_slice(). Serde ends up calling that for ever
491
+ // field of a struct that we're serializing. extend_from_slice()
492
+ // does not get inlined and thus we end up calling a generic memcpy()
493
+ // implementation. If we instead reserve enough room for the serialized
494
+ // struct in the Vec ahead of time we can rely on that and use
495
+ // the following UnsafeVecWriter to write into the vec without
496
+ // any checks.
497
+ struct UnsafeVecWriter < ' a > ( & ' a mut Vec < u8 > ) ;
498
+
499
+ impl < ' a > Write for UnsafeVecWriter < ' a > {
500
+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
501
+ unsafe {
502
+ let old_len = self . 0 . len ( ) ;
503
+ self . 0 . set_len ( old_len + buf. len ( ) ) ;
504
+ ptr:: copy_nonoverlapping ( buf. as_ptr ( ) , self . 0 . as_mut_ptr ( ) . offset ( old_len as isize ) , buf. len ( ) ) ;
505
+ }
506
+ Ok ( buf. len ( ) )
507
+ }
508
+ fn flush ( & mut self ) -> io:: Result < ( ) > { Ok ( ( ) ) }
509
+ }
510
+
511
+ struct SizeCounter ( usize ) ;
512
+
513
+ impl < ' a > Write for SizeCounter {
514
+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
515
+ self . 0 += buf. len ( ) ;
516
+ Ok ( buf. len ( ) )
517
+ }
518
+ fn flush ( & mut self ) -> io:: Result < ( ) > { Ok ( ( ) ) }
519
+ }
520
+
521
+ fn serialize_fast < T : Serialize > ( vec : & mut Vec < u8 > , e : & T ) {
522
+ // manually counting the size is faster than vec.reserve(bincode::serialized_size(&e) as usize) for some reason
523
+ let mut size = SizeCounter ( 0 ) ;
524
+ bincode:: serialize_into ( & mut size, e , bincode:: Infinite ) . unwrap ( ) ;
525
+ vec. reserve ( size. 0 ) ;
526
+
527
+ bincode:: serialize_into ( & mut UnsafeVecWriter ( vec) , e, bincode:: Infinite ) . unwrap ( ) ;
528
+ }
529
+
486
530
#[ derive( Clone ) ]
487
531
pub struct DisplayListBuilder {
488
532
pub data : Vec < u8 > ,
@@ -541,28 +585,26 @@ impl DisplayListBuilder {
541
585
}
542
586
543
587
fn push_item ( & mut self , item : SpecificDisplayItem , info : & LayoutPrimitiveInfo ) {
544
- bincode :: serialize_into (
588
+ serialize_fast (
545
589
& mut self . data ,
546
590
& DisplayItem {
547
591
item,
548
592
clip_and_scroll : * self . clip_stack . last ( ) . unwrap ( ) ,
549
593
info : * info,
550
594
} ,
551
- bincode:: Infinite ,
552
- ) . unwrap ( ) ;
595
+ )
553
596
}
554
597
555
598
fn push_new_empty_item ( & mut self , item : SpecificDisplayItem ) {
556
599
let info = LayoutPrimitiveInfo :: new ( LayoutRect :: zero ( ) ) ;
557
- bincode :: serialize_into (
600
+ serialize_fast (
558
601
& mut self . data ,
559
602
& DisplayItem {
560
603
item,
561
604
clip_and_scroll : * self . clip_stack . last ( ) . unwrap ( ) ,
562
605
info,
563
- } ,
564
- bincode:: Infinite ,
565
- ) . unwrap ( ) ;
606
+ }
607
+ )
566
608
}
567
609
568
610
fn push_iter < I > ( & mut self , iter : I )
@@ -575,10 +617,10 @@ impl DisplayListBuilder {
575
617
let len = iter. len ( ) ;
576
618
let mut count = 0 ;
577
619
578
- bincode :: serialize_into ( & mut self . data , & len, bincode :: Infinite ) . unwrap ( ) ;
620
+ serialize_fast ( & mut self . data , & len) ;
579
621
for elem in iter {
580
622
count += 1 ;
581
- bincode :: serialize_into ( & mut self . data , & elem, bincode :: Infinite ) . unwrap ( ) ;
623
+ serialize_fast ( & mut self . data , & elem) ;
582
624
}
583
625
584
626
debug_assert_eq ! ( len, count) ;
@@ -1103,8 +1145,8 @@ impl DisplayListBuilder {
1103
1145
1104
1146
// Append glyph data to the end
1105
1147
for ( ( font_key, color) , sub_glyphs) in glyphs {
1106
- bincode :: serialize_into ( & mut self . data , & font_key, bincode :: Infinite ) . unwrap ( ) ;
1107
- bincode :: serialize_into ( & mut self . data , & color, bincode :: Infinite ) . unwrap ( ) ;
1148
+ serialize_fast ( & mut self . data , & font_key) ;
1149
+ serialize_fast ( & mut self . data , & color) ;
1108
1150
self . push_iter ( sub_glyphs) ;
1109
1151
}
1110
1152
0 commit comments