Skip to content

Commit 323b7ea

Browse files
author
bors-servo
authored
Auto merge of #3361 - kvark:push-item, r=jrmuizel
Introduce SerializedDisplayItem to reduce mem copies on DL construction This PR addresses the part of #3358 about DL construction: instead of constructing the display items and associated data and passing through the serializer by value, we just pass the references around, which guarantees that no extra copies are made. TODO: - [x] verify that the copies are gone (need the tool hosted/opened somewhere) - [x] Gecko try push with talos jobs <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/webrender/3361) <!-- Reviewable:end -->
2 parents 586af96 + f72bf26 commit 323b7ea

File tree

2 files changed

+50
-54
lines changed

2 files changed

+50
-54
lines changed

webrender_api/src/display_item.rs

+9
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,15 @@ pub struct GenericDisplayItem<T> {
6666

6767
pub type DisplayItem = GenericDisplayItem<SpecificDisplayItem>;
6868

69+
/// A modified version of DI where every field is borrowed instead of owned.
70+
/// It allows us to reduce copies during serialization.
71+
#[derive(Serialize)]
72+
pub struct SerializedDisplayItem<'a> {
73+
pub item: &'a SpecificDisplayItem,
74+
pub clip_and_scroll: &'a ClipAndScrollInfo,
75+
pub info: &'a LayoutPrimitiveInfo,
76+
}
77+
6978
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
7079
pub struct PrimitiveInfo<T> {
7180
pub rect: TypedRect<f32, T>,

webrender_api/src/display_list.rs

+41-54
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ use {ImageRendering, LayoutPoint, LayoutPrimitiveInfo, LayoutRect, LayoutSideOff
2323
use {LayoutTransform, LayoutVector2D, LineDisplayItem, LineOrientation, LineStyle, MixBlendMode};
2424
use {PipelineId, PropertyBinding, PushReferenceFrameDisplayListItem};
2525
use {PushStackingContextDisplayItem, RadialGradient, RadialGradientDisplayItem};
26-
use {RectangleDisplayItem, ReferenceFrame, ScrollFrameDisplayItem, ScrollSensitivity, Shadow};
27-
use {SpecificDisplayItem, StackingContext, StickyFrameDisplayItem, StickyOffsetBounds};
26+
use {RectangleDisplayItem, ReferenceFrame, ScrollFrameDisplayItem, ScrollSensitivity};
27+
use {SerializedDisplayItem, Shadow, SpecificDisplayItem};
28+
use {StackingContext, StickyFrameDisplayItem, StickyOffsetBounds};
2829
use {TextDisplayItem, TransformStyle, YuvColorSpace, YuvData, YuvImageDisplayItem, ColorDepth};
2930

3031
// We don't want to push a long text-run. If a text-run is too long, split it into several parts.
@@ -691,16 +692,16 @@ impl<'a> Write for SizeCounter {
691692
/// If this assumption is incorrect, the result will be Undefined Behaviour. This
692693
/// assumption should hold for all derived Serialize impls, which is all we currently
693694
/// use.
694-
fn serialize_fast<T: Serialize>(vec: &mut Vec<u8>, e: &T) {
695+
fn serialize_fast<T: Serialize>(vec: &mut Vec<u8>, e: T) {
695696
// manually counting the size is faster than vec.reserve(bincode::serialized_size(&e) as usize) for some reason
696697
let mut size = SizeCounter(0);
697-
bincode::serialize_into(&mut size, e).unwrap();
698+
bincode::serialize_into(&mut size, &e).unwrap();
698699
vec.reserve(size.0);
699700

700701
let old_len = vec.len();
701702
let ptr = unsafe { vec.as_mut_ptr().add(old_len) };
702703
let mut w = UnsafeVecWriter(ptr);
703-
bincode::serialize_into(&mut w, e).unwrap();
704+
bincode::serialize_into(&mut w, &e).unwrap();
704705

705706
// fix up the length
706707
unsafe { vec.set_len(old_len + size.0); }
@@ -964,43 +965,36 @@ impl DisplayListBuilder {
964965
/// NOTE: It is usually preferable to use the specialized methods to push
965966
/// display items. Pushing unexpected or invalid items here may
966967
/// result in WebRender panicking or behaving in unexpected ways.
967-
pub fn push_item(&mut self, item: SpecificDisplayItem, info: &LayoutPrimitiveInfo) {
968+
pub fn push_item(&mut self, item: &SpecificDisplayItem, info: &LayoutPrimitiveInfo) {
968969
serialize_fast(
969970
&mut self.data,
970-
&DisplayItem {
971+
SerializedDisplayItem {
971972
item,
972-
clip_and_scroll: *self.clip_stack.last().unwrap(),
973-
info: *info,
973+
clip_and_scroll: self.clip_stack.last().unwrap(),
974+
info,
974975
},
975976
)
976977
}
977978

978979
fn push_item_with_clip_scroll_info(
979980
&mut self,
980-
item: SpecificDisplayItem,
981+
item: &SpecificDisplayItem,
981982
info: &LayoutPrimitiveInfo,
982-
scrollinfo: ClipAndScrollInfo
983+
clip_and_scroll: &ClipAndScrollInfo
983984
) {
984985
serialize_fast(
985986
&mut self.data,
986-
&DisplayItem {
987+
SerializedDisplayItem {
987988
item,
988-
clip_and_scroll: scrollinfo,
989-
info: *info,
989+
clip_and_scroll,
990+
info,
990991
},
991992
)
992993
}
993994

994-
fn push_new_empty_item(&mut self, item: SpecificDisplayItem, clip_and_scroll: &ClipAndScrollInfo) {
995-
let info = LayoutPrimitiveInfo::new(LayoutRect::zero());
996-
serialize_fast(
997-
&mut self.data,
998-
&DisplayItem {
999-
item,
1000-
clip_and_scroll: *clip_and_scroll,
1001-
info,
1002-
}
1003-
)
995+
fn push_new_empty_item(&mut self, item: &SpecificDisplayItem) {
996+
let info = &LayoutPrimitiveInfo::new(LayoutRect::zero());
997+
self.push_item(item, info)
1004998
}
1005999

10061000
fn push_iter_impl<I>(data: &mut Vec<u8>, iter_source: I)
@@ -1050,11 +1044,11 @@ impl DisplayListBuilder {
10501044

10511045
pub fn push_rect(&mut self, info: &LayoutPrimitiveInfo, color: ColorF) {
10521046
let item = SpecificDisplayItem::Rectangle(RectangleDisplayItem { color });
1053-
self.push_item(item, info);
1047+
self.push_item(&item, info);
10541048
}
10551049

10561050
pub fn push_clear_rect(&mut self, info: &LayoutPrimitiveInfo) {
1057-
self.push_item(SpecificDisplayItem::ClearRectangle, info);
1051+
self.push_item(&SpecificDisplayItem::ClearRectangle, info);
10581052
}
10591053

10601054
pub fn push_line(
@@ -1072,7 +1066,7 @@ impl DisplayListBuilder {
10721066
style,
10731067
});
10741068

1075-
self.push_item(item, info);
1069+
self.push_item(&item, info);
10761070
}
10771071

10781072
pub fn push_image(
@@ -1094,7 +1088,7 @@ impl DisplayListBuilder {
10941088
color,
10951089
});
10961090

1097-
self.push_item(item, info);
1091+
self.push_item(&item, info);
10981092
}
10991093

11001094
/// Push a yuv image. All planar data in yuv image should use the same buffer type.
@@ -1112,7 +1106,7 @@ impl DisplayListBuilder {
11121106
color_space,
11131107
image_rendering,
11141108
});
1115-
self.push_item(item, info);
1109+
self.push_item(&item, info);
11161110
}
11171111

11181112
pub fn push_text(
@@ -1130,7 +1124,7 @@ impl DisplayListBuilder {
11301124
});
11311125

11321126
for split_glyphs in glyphs.chunks(MAX_TEXT_RUN_LENGTH) {
1133-
self.push_item(item, info);
1127+
self.push_item(&item, info);
11341128
self.push_iter(split_glyphs);
11351129
}
11361130
}
@@ -1173,7 +1167,7 @@ impl DisplayListBuilder {
11731167
) {
11741168
let item = SpecificDisplayItem::Border(BorderDisplayItem { details, widths });
11751169

1176-
self.push_item(item, info);
1170+
self.push_item(&item, info);
11771171
}
11781172

11791173
pub fn push_box_shadow(
@@ -1197,7 +1191,7 @@ impl DisplayListBuilder {
11971191
clip_mode,
11981192
});
11991193

1200-
self.push_item(item, info);
1194+
self.push_item(&item, info);
12011195
}
12021196

12031197
/// Pushes a linear gradient to be displayed.
@@ -1227,7 +1221,7 @@ impl DisplayListBuilder {
12271221
tile_spacing,
12281222
});
12291223

1230-
self.push_item(item, info);
1224+
self.push_item(&item, info);
12311225
}
12321226

12331227
/// Pushes a radial gradient to be displayed.
@@ -1246,7 +1240,7 @@ impl DisplayListBuilder {
12461240
tile_spacing,
12471241
});
12481242

1249-
self.push_item(item, info);
1243+
self.push_item(&item, info);
12501244
}
12511245

12521246
pub fn push_reference_frame(
@@ -1263,13 +1257,12 @@ impl DisplayListBuilder {
12631257
id,
12641258
},
12651259
});
1266-
self.push_item(item, info);
1260+
self.push_item(&item, info);
12671261
id
12681262
}
12691263

12701264
pub fn pop_reference_frame(&mut self) {
1271-
let clip_and_scroll = *self.clip_stack.last().unwrap();
1272-
self.push_new_empty_item(SpecificDisplayItem::PopReferenceFrame, &clip_and_scroll);
1265+
self.push_new_empty_item(&SpecificDisplayItem::PopReferenceFrame);
12731266
}
12741267

12751268
pub fn push_stacking_context(
@@ -1290,21 +1283,19 @@ impl DisplayListBuilder {
12901283
},
12911284
});
12921285

1293-
self.push_item(item, info);
1286+
self.push_item(&item, info);
12941287
self.push_iter(filters);
12951288
}
12961289

12971290
pub fn pop_stacking_context(&mut self) {
1298-
let clip_and_scroll = *self.clip_stack.last().unwrap();
1299-
self.push_new_empty_item(SpecificDisplayItem::PopStackingContext, &clip_and_scroll);
1291+
self.push_new_empty_item(&SpecificDisplayItem::PopStackingContext);
13001292
}
13011293

13021294
pub fn push_stops(&mut self, stops: &[GradientStop]) {
13031295
if stops.is_empty() {
13041296
return;
13051297
}
1306-
let clip_and_scroll = *self.clip_stack.last().unwrap();
1307-
self.push_new_empty_item(SpecificDisplayItem::SetGradientStops, &clip_and_scroll);
1298+
self.push_new_empty_item(&SpecificDisplayItem::SetGradientStops);
13081299
self.push_iter(stops);
13091300
}
13101301

@@ -1372,9 +1363,9 @@ impl DisplayListBuilder {
13721363
});
13731364

13741365
self.push_item_with_clip_scroll_info(
1375-
item,
1366+
&item,
13761367
&LayoutPrimitiveInfo::with_clip_rect(content_rect, clip_rect),
1377-
ClipAndScrollInfo::simple(parent),
1368+
&ClipAndScrollInfo::simple(parent),
13781369
);
13791370
self.push_iter(complex_clips);
13801371

@@ -1391,8 +1382,7 @@ impl DisplayListBuilder {
13911382
I::IntoIter: ExactSizeIterator + Clone,
13921383
{
13931384
let id = self.generate_clip_chain_id();
1394-
let clip_and_scroll = *self.clip_stack.last().unwrap();
1395-
self.push_new_empty_item(SpecificDisplayItem::ClipChain(ClipChainItem { id, parent }), &clip_and_scroll);
1385+
self.push_new_empty_item(&SpecificDisplayItem::ClipChain(ClipChainItem { id, parent }));
13961386
self.push_iter(clips);
13971387
id
13981388
}
@@ -1454,7 +1444,7 @@ impl DisplayListBuilder {
14541444

14551445
let info = LayoutPrimitiveInfo::new(clip_rect);
14561446

1457-
self.push_item_with_clip_scroll_info(item, &info, scrollinfo);
1447+
self.push_item_with_clip_scroll_info(&item, &info, &scrollinfo);
14581448
self.push_iter(complex_clips);
14591449
id
14601450
}
@@ -1477,7 +1467,7 @@ impl DisplayListBuilder {
14771467
});
14781468

14791469
let info = LayoutPrimitiveInfo::new(frame_rect);
1480-
self.push_item(item, &info);
1470+
self.push_item(&item, &info);
14811471
id
14821472
}
14831473

@@ -1509,24 +1499,21 @@ impl DisplayListBuilder {
15091499
pipeline_id,
15101500
ignore_missing_pipeline,
15111501
});
1512-
self.push_item(item, info);
1502+
self.push_item(&item, info);
15131503
}
15141504

15151505
pub fn push_shadow(&mut self, info: &LayoutPrimitiveInfo, shadow: Shadow) {
1516-
self.push_item(SpecificDisplayItem::PushShadow(shadow), info);
1506+
self.push_item(&SpecificDisplayItem::PushShadow(shadow), info);
15171507
}
15181508

15191509
pub fn pop_all_shadows(&mut self) {
1520-
let clip_and_scroll = *self.clip_stack.last().unwrap();
1521-
self.push_new_empty_item(SpecificDisplayItem::PopAllShadows, &clip_and_scroll);
1510+
self.push_new_empty_item(&SpecificDisplayItem::PopAllShadows);
15221511
}
15231512

15241513
pub fn finalize(self) -> (PipelineId, LayoutSize, BuiltDisplayList) {
15251514
assert!(self.save_state.is_none(), "Finalized DisplayListBuilder with a pending save");
15261515

15271516
let end_time = precise_time_ns();
1528-
1529-
15301517
(
15311518
self.pipeline_id,
15321519
self.content_size,

0 commit comments

Comments
 (0)