@@ -17,6 +17,8 @@ use YuvImageDisplayItem;
1717use bincode;
1818use serde:: { Deserialize , Serialize , Serializer } ;
1919use serde:: ser:: { SerializeMap , SerializeSeq } ;
20+ use std:: io:: Write ;
21+ use std:: { io, ptr} ;
2022use std:: marker:: PhantomData ;
2123use time:: precise_time_ns;
2224
@@ -483,6 +485,48 @@ impl<'a, 'b> Serialize for DisplayItemRef<'a, 'b> {
483485 }
484486}
485487
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+
486530#[ derive( Clone ) ]
487531pub struct DisplayListBuilder {
488532 pub data : Vec < u8 > ,
@@ -541,28 +585,26 @@ impl DisplayListBuilder {
541585 }
542586
543587 fn push_item ( & mut self , item : SpecificDisplayItem , info : & LayoutPrimitiveInfo ) {
544- bincode :: serialize_into (
588+ serialize_fast (
545589 & mut self . data ,
546590 & DisplayItem {
547591 item,
548592 clip_and_scroll : * self . clip_stack . last ( ) . unwrap ( ) ,
549593 info : * info,
550594 } ,
551- bincode:: Infinite ,
552- ) . unwrap ( ) ;
595+ )
553596 }
554597
555598 fn push_new_empty_item ( & mut self , item : SpecificDisplayItem ) {
556599 let info = LayoutPrimitiveInfo :: new ( LayoutRect :: zero ( ) ) ;
557- bincode :: serialize_into (
600+ serialize_fast (
558601 & mut self . data ,
559602 & DisplayItem {
560603 item,
561604 clip_and_scroll : * self . clip_stack . last ( ) . unwrap ( ) ,
562605 info,
563- } ,
564- bincode:: Infinite ,
565- ) . unwrap ( ) ;
606+ }
607+ )
566608 }
567609
568610 fn push_iter < I > ( & mut self , iter : I )
@@ -575,10 +617,10 @@ impl DisplayListBuilder {
575617 let len = iter. len ( ) ;
576618 let mut count = 0 ;
577619
578- bincode :: serialize_into ( & mut self . data , & len, bincode :: Infinite ) . unwrap ( ) ;
620+ serialize_fast ( & mut self . data , & len) ;
579621 for elem in iter {
580622 count += 1 ;
581- bincode :: serialize_into ( & mut self . data , & elem, bincode :: Infinite ) . unwrap ( ) ;
623+ serialize_fast ( & mut self . data , & elem) ;
582624 }
583625
584626 debug_assert_eq ! ( len, count) ;
@@ -1103,8 +1145,8 @@ impl DisplayListBuilder {
11031145
11041146 // Append glyph data to the end
11051147 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) ;
11081150 self . push_iter ( sub_glyphs) ;
11091151 }
11101152
0 commit comments