Bug 1536121 - rearchitect the webrender display-list. r=gw

disclaimer: this isn't an *amazing* cleanup, but more of a major step that
unlocks the ability to do more minor cleanups and refinements. There's some
messy things and inconsistencies here and there, but we can hopefully iron
them out over time.

1. The primary change here is to move from
    struct { common_fields, enum(specific_fields) }
to
    enum (maybe_common_fields, specific_fields)

most notably this drops the common fields from a ton of things
that don't need them PopXXX, SetXXX, ClipChain, etc.

2. Additionally some types have had some redundant states shaved off,
for instance, rect no longer has *both* bounds and a clip_rect, as
the intersection of the two can be used. This was done a bit conservatively
as some adjustments will need to be done to the backend to fully eliminate
some states, and this can be done more incrementally.

2.5. As a minor side-effect of 2, we now early-reject some primitives whose
bounds and clip_rect are disjoint.

3. A HitTest display item has been added, which is just a Rect without
color. In addition to the minor space wins from this, this makes it much
easier to debug display lists

4. Adds a bunch of comments to the display list, making it easier to understand
things.

The end result of all these changes is a significantly smaller and easier to
understand display list. Especially on pages like gmail which have so many
clip chains. However this ultimately just makes text an even greater percentage
of pages (often 70-80%).

Differential Revision: https://phabricator.services.mozilla.com/D27439

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alexis Beingessner 2019-04-23 17:29:58 +00:00
Родитель bd5e102438
Коммит 8289701d8c
35 изменённых файлов: 1480 добавлений и 937 удалений

Просмотреть файл

@ -937,6 +937,16 @@ void DisplayListBuilder::PushRoundedRect(const wr::LayoutRect& aBounds,
&spaceAndClip, aColor);
}
void DisplayListBuilder::PushHitTest(const wr::LayoutRect& aBounds,
const wr::LayoutRect& aClip,
bool aIsBackfaceVisible) {
wr::LayoutRect clip = MergeClipLeaf(aClip);
WRDL_LOG("PushHitTest b=%s cl=%s\n", mWrState, Stringify(aBounds).c_str(),
Stringify(clip).c_str());
wr_dp_push_hit_test(mWrState, aBounds, clip, aIsBackfaceVisible,
&mCurrentSpaceAndClipChain);
}
void DisplayListBuilder::PushClearRect(const wr::LayoutRect& aBounds) {
wr::LayoutRect clip = MergeClipLeaf(aBounds);
WRDL_LOG("PushClearRect b=%s c=%s\n", mWrState, Stringify(aBounds).c_str(),

Просмотреть файл

@ -423,7 +423,8 @@ class DisplayListBuilder final {
void PushRoundedRect(const wr::LayoutRect& aBounds,
const wr::LayoutRect& aClip, bool aIsBackfaceVisible,
const wr::ColorF& aColor);
void PushHitTest(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip,
bool aIsBackfaceVisible);
void PushClearRect(const wr::LayoutRect& aBounds);
void PushClearRectWithComplexRegion(const wr::LayoutRect& aBounds,
const wr::ComplexClipRegion& aRegion);

Просмотреть файл

@ -2143,7 +2143,7 @@ pub extern "C" fn wr_dp_push_stacking_context(
},
};
wr_spatial_id = state.frame_builder.dl_builder.push_reference_frame(
&bounds,
bounds.origin,
wr_spatial_id,
params.transform_style,
transform_binding,
@ -2155,16 +2155,11 @@ pub extern "C" fn wr_dp_push_stacking_context(
assert_ne!(wr_spatial_id.0, 0);
}
let prim_info = LayoutPrimitiveInfo {
is_backface_visible: params.is_backface_visible,
tag: state.current_tag,
.. LayoutPrimitiveInfo::new(bounds)
};
state.frame_builder
.dl_builder
.push_stacking_context(&prim_info,
.push_stacking_context(bounds.origin,
wr_spatial_id,
params.is_backface_visible,
wr_clip_id,
params.transform_style,
params.mix_blend_mode,
@ -2319,17 +2314,15 @@ pub extern "C" fn wr_dp_define_scroll_layer(state: &mut WrState,
pub extern "C" fn wr_dp_push_iframe(state: &mut WrState,
rect: LayoutRect,
clip: LayoutRect,
is_backface_visible: bool,
_is_backface_visible: bool,
parent: &WrSpaceAndClipChain,
pipeline_id: WrPipelineId,
ignore_missing_pipeline: bool) {
debug_assert!(unsafe { is_in_main_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
state.frame_builder.dl_builder.push_iframe(
&prim_info,
rect,
clip,
&parent.to_webrender(state.pipeline_id),
pipeline_id,
ignore_missing_pipeline,
@ -2345,12 +2338,22 @@ pub extern "C" fn wr_dp_push_rect(state: &mut WrState,
color: ColorF) {
debug_assert!(unsafe { !is_in_render_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let clip_rect = clip.intersection(&rect);
let prim_info = CommonItemProperties {
// NB: the damp-e10s talos-test will frequently crash on startup if we
// early-return here for empty rects. I couldn't figure out why, but
// it's pretty harmless to feed these through, so, uh, we do?
clip_rect: clip_rect.unwrap_or(LayoutRect::zero()),
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_rect(
&prim_info,
&parent.to_webrender(state.pipeline_id),
color,
);
}
@ -2366,12 +2369,21 @@ pub extern "C" fn wr_dp_push_rect_with_parent_clip(
) {
debug_assert!(unsafe { !is_in_render_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let clip_rect = clip.intersection(&rect);
if clip_rect.is_none() { return; }
let prim_info = CommonItemProperties {
clip_rect: clip_rect.unwrap(),
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_rect(
&prim_info,
&parent.to_webrender(state.pipeline_id),
color,
);
}
@ -2383,10 +2395,47 @@ pub extern "C" fn wr_dp_push_clear_rect(state: &mut WrState,
parent: &WrSpaceAndClipChain) {
debug_assert!(unsafe { !is_in_render_thread() });
let prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
let space_and_clip = parent.to_webrender(state.pipeline_id);
let clip_rect = clip.intersection(&rect);
if clip_rect.is_none() { return; }
let prim_info = CommonItemProperties {
clip_rect: clip_rect.unwrap(),
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible: true,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_clear_rect(
&prim_info,
&parent.to_webrender(state.pipeline_id),
);
}
#[no_mangle]
pub extern "C" fn wr_dp_push_hit_test(state: &mut WrState,
rect: LayoutRect,
clip: LayoutRect,
is_backface_visible: bool,
parent: &WrSpaceAndClipChain) {
debug_assert!(unsafe { !is_in_render_thread() });
let space_and_clip = parent.to_webrender(state.pipeline_id);
let clip_rect = clip.intersection(&rect);
if clip_rect.is_none() { return; }
let prim_info = CommonItemProperties {
clip_rect: clip_rect.unwrap(),
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_hit_test(
&prim_info,
);
}
@ -2399,10 +2448,21 @@ pub extern "C" fn wr_dp_push_clear_rect_with_parent_clip(
) {
debug_assert!(unsafe { !is_in_render_thread() });
let prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
let space_and_clip = parent.to_webrender(state.pipeline_id);
let clip_rect = clip.intersection(&rect);
if clip_rect.is_none() { return; }
let prim_info = CommonItemProperties {
clip_rect: clip_rect.unwrap(),
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible: true,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_clear_rect(
&prim_info,
&parent.to_webrender(state.pipeline_id),
);
}
@ -2420,18 +2480,26 @@ pub extern "C" fn wr_dp_push_image(state: &mut WrState,
color: ColorF) {
debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
let alpha_type = if premultiplied_alpha {
AlphaType::PremultipliedAlpha
} else {
AlphaType::Alpha
};
state.frame_builder
.dl_builder
.push_image(&prim_info,
&parent.to_webrender(state.pipeline_id),
bounds,
stretch_size,
tile_spacing,
image_rendering,
@ -2455,13 +2523,20 @@ pub extern "C" fn wr_dp_push_yuv_planar_image(state: &mut WrState,
image_rendering: ImageRendering) {
debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder
.dl_builder
.push_yuv_image(&prim_info,
&parent.to_webrender(state.pipeline_id),
bounds,
YuvData::PlanarYCbCr(image_key_0, image_key_1, image_key_2),
color_depth,
color_space,
@ -2482,13 +2557,20 @@ pub extern "C" fn wr_dp_push_yuv_NV12_image(state: &mut WrState,
image_rendering: ImageRendering) {
debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder
.dl_builder
.push_yuv_image(&prim_info,
&parent.to_webrender(state.pipeline_id),
bounds,
YuvData::NV12(image_key_0, image_key_1),
color_depth,
color_space,
@ -2508,13 +2590,20 @@ pub extern "C" fn wr_dp_push_yuv_interleaved_image(state: &mut WrState,
image_rendering: ImageRendering) {
debug_assert!(unsafe { is_in_main_thread() || is_in_compositor_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder
.dl_builder
.push_yuv_image(&prim_info,
&parent.to_webrender(state.pipeline_id),
bounds,
YuvData::InterleavedYCbCr(image_key_0),
color_depth,
color_space,
@ -2536,13 +2625,20 @@ pub extern "C" fn wr_dp_push_text(state: &mut WrState,
let glyph_slice = unsafe { make_slice(glyphs, glyph_count as usize) };
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
spatial_id: space_and_clip.spatial_id,
clip_id: space_and_clip.clip_id,
is_backface_visible,
hit_info: state.current_tag
};
state.frame_builder
.dl_builder
.push_text(&prim_info,
&parent.to_webrender(state.pipeline_id),
bounds,
&glyph_slice,
font_key,
color,
@ -2551,18 +2647,14 @@ pub extern "C" fn wr_dp_push_text(state: &mut WrState,
#[no_mangle]
pub extern "C" fn wr_dp_push_shadow(state: &mut WrState,
bounds: LayoutRect,
clip: LayoutRect,
is_backface_visible: bool,
_bounds: LayoutRect,
_clip: LayoutRect,
_is_backface_visible: bool,
parent: &WrSpaceAndClipChain,
shadow: Shadow) {
debug_assert!(unsafe { is_in_main_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(bounds, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
state.frame_builder.dl_builder.push_shadow(
&prim_info,
&parent.to_webrender(state.pipeline_id),
shadow.into(),
);
@ -2587,13 +2679,20 @@ pub extern "C" fn wr_dp_push_line(state: &mut WrState,
style: LineStyle) {
debug_assert!(unsafe { is_in_main_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(*bounds, (*clip).into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: *clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder
.dl_builder
.push_line(&prim_info,
&parent.to_webrender(state.pipeline_id),
bounds,
wavy_line_thickness,
orientation,
color,
@ -2625,13 +2724,20 @@ pub extern "C" fn wr_dp_push_border(state: &mut WrState,
do_aa: do_aa == AntialiasBorder::Yes,
});
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder
.dl_builder
.push_border(&prim_info,
&parent.to_webrender(state.pipeline_id),
rect,
widths,
border_details);
}
@ -2661,12 +2767,19 @@ pub extern "C" fn wr_dp_push_border_image(state: &mut WrState,
repeat_horizontal: repeat_horizontal.into(),
repeat_vertical: repeat_vertical.into(),
});
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_border(
&prim_info,
&parent.to_webrender(state.pipeline_id),
rect,
widths.into(),
border_details,
);
@ -2711,12 +2824,19 @@ pub extern "C" fn wr_dp_push_border_gradient(state: &mut WrState,
repeat_vertical: RepeatMode::Stretch,
});
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_border(
&prim_info,
&parent.to_webrender(state.pipeline_id),
rect,
widths.into(),
border_details,
);
@ -2764,12 +2884,20 @@ pub extern "C" fn wr_dp_push_border_radial_gradient(state: &mut WrState,
repeat_horizontal: RepeatMode::Stretch,
repeat_vertical: RepeatMode::Stretch,
});
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_border(
&prim_info,
&parent.to_webrender(state.pipeline_id),
rect,
widths.into(),
border_details,
);
@ -2799,12 +2927,20 @@ pub extern "C" fn wr_dp_push_linear_gradient(state: &mut WrState,
end_point.into(),
stops_vector,
extend_mode.into());
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_gradient(
&prim_info,
&parent.to_webrender(state.pipeline_id),
rect,
gradient,
tile_size.into(),
tile_spacing.into(),
@ -2835,12 +2971,20 @@ pub extern "C" fn wr_dp_push_radial_gradient(state: &mut WrState,
radius.into(),
stops_vector,
extend_mode.into());
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder.dl_builder.push_radial_gradient(
&prim_info,
&parent.to_webrender(state.pipeline_id),
rect,
gradient,
tile_size,
tile_spacing);
@ -2848,7 +2992,7 @@ pub extern "C" fn wr_dp_push_radial_gradient(state: &mut WrState,
#[no_mangle]
pub extern "C" fn wr_dp_push_box_shadow(state: &mut WrState,
rect: LayoutRect,
_rect: LayoutRect,
clip: LayoutRect,
is_backface_visible: bool,
parent: &WrSpaceAndClipChain,
@ -2861,13 +3005,19 @@ pub extern "C" fn wr_dp_push_box_shadow(state: &mut WrState,
clip_mode: BoxShadowClipMode) {
debug_assert!(unsafe { is_in_main_thread() });
let mut prim_info = LayoutPrimitiveInfo::with_clip_rect(rect, clip.into());
prim_info.is_backface_visible = is_backface_visible;
prim_info.tag = state.current_tag;
let space_and_clip = parent.to_webrender(state.pipeline_id);
let prim_info = CommonItemProperties {
clip_rect: clip,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible,
hit_info: state.current_tag,
};
state.frame_builder
.dl_builder
.push_box_shadow(&prim_info,
&parent.to_webrender(state.pipeline_id),
box_bounds,
offset,
color,

Просмотреть файл

@ -151,11 +151,13 @@ impl Rectangle {
);
builder.push_rect(
&api::PrimitiveInfo::new(rect),
&api::SpaceAndClipInfo {
spatial_id: api::SpatialId::root_scroll_node(pipeline_id),
clip_id,
},
&api::CommonItemProperties::new(
rect,
api::SpaceAndClipInfo {
spatial_id: api::SpatialId::root_scroll_node(pipeline_id),
clip_id,
},
),
self.color,
);

Просмотреть файл

@ -32,16 +32,19 @@ impl Example for App {
_document_id: DocumentId,
) {
let bounds = (0, 0).to(1920, 1080);
let info = LayoutPrimitiveInfo::new(bounds);
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
builder.push_simple_stacking_context(
&info,
bounds.origin,
space_and_clip.spatial_id,
true,
);
for _ in 0 .. self.rect_count {
builder.push_rect(&info, &space_and_clip, ColorF::new(1.0, 1.0, 1.0, 0.05));
builder.push_rect(
&CommonItemProperties::new(bounds, space_and_clip),
ColorF::new(1.0, 1.0, 1.0, 0.05)
);
}
builder.pop_stacking_context();

Просмотреть файл

@ -58,7 +58,7 @@ impl App {
};
let spatial_id = builder.push_reference_frame(
&LayoutRect::new(bounds.origin, LayoutSize::zero()),
bounds.origin,
SpatialId::root_scroll_node(pipeline_id),
TransformStyle::Flat,
PropertyBinding::Binding(property_key, LayoutTransform::identity()),
@ -66,8 +66,9 @@ impl App {
);
builder.push_simple_stacking_context_with_filters(
&LayoutPrimitiveInfo::new(LayoutRect::zero()),
LayoutPoint::zero(),
spatial_id,
true,
&filters,
&[],
);
@ -86,11 +87,13 @@ impl App {
// Fill it with a white rect
builder.push_rect(
&LayoutPrimitiveInfo::new(LayoutRect::new(LayoutPoint::zero(), bounds.size)),
&SpaceAndClipInfo {
spatial_id,
clip_id,
},
&CommonItemProperties::new(
LayoutRect::new(LayoutPoint::zero(), bounds.size),
SpaceAndClipInfo {
spatial_id,
clip_id,
}
),
color,
);

Просмотреть файл

@ -190,14 +190,14 @@ impl Example for App {
pipeline_id: PipelineId,
_document_id: DocumentId,
) {
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
let info = LayoutPrimitiveInfo::new(bounds);
let content_bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
let root_space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
let spatial_id = root_space_and_clip.spatial_id;
builder.push_simple_stacking_context(
&info,
content_bounds.origin,
spatial_id,
true,
);
let image_mask_key = api.generate_image_key();
@ -217,17 +217,26 @@ impl Example for App {
BorderRadius::uniform(20.0),
ClipMode::Clip
);
let clip_id = builder.define_clip(&root_space_and_clip, bounds, vec![complex], Some(mask));
let clip_id = builder.define_clip(
&root_space_and_clip,
content_bounds,
vec![complex],
Some(mask)
);
builder.push_rect(
&LayoutPrimitiveInfo::new((100, 100).to(200, 200)),
&SpaceAndClipInfo { spatial_id, clip_id },
&CommonItemProperties::new(
(100, 100).to(200, 200),
SpaceAndClipInfo { spatial_id, clip_id },
),
ColorF::new(0.0, 1.0, 0.0, 1.0),
);
builder.push_rect(
&LayoutPrimitiveInfo::new((250, 100).to(350, 200)),
&SpaceAndClipInfo { spatial_id, clip_id },
&CommonItemProperties::new(
(250, 100).to(350, 200),
SpaceAndClipInfo { spatial_id, clip_id },
),
ColorF::new(0.0, 1.0, 0.0, 1.0),
);
let border_side = BorderSide {
@ -244,16 +253,19 @@ impl Example for App {
do_aa: true,
});
let bounds = (100, 100).to(200, 200);
builder.push_border(
&LayoutPrimitiveInfo::new((100, 100).to(200, 200)),
&SpaceAndClipInfo { spatial_id, clip_id },
&CommonItemProperties::new(
bounds,
SpaceAndClipInfo { spatial_id, clip_id },
),
bounds,
border_widths,
border_details,
);
if false {
// draw box shadow?
let rect = LayoutRect::zero();
let simple_box_bounds = (20, 200).by(50, 50);
let offset = vec2(10.0, 10.0);
let color = ColorF::new(1.0, 1.0, 1.0, 1.0);
@ -263,8 +275,7 @@ impl Example for App {
let box_shadow_type = BoxShadowClipMode::Inset;
builder.push_box_shadow(
&LayoutPrimitiveInfo::with_clip_rect(rect, bounds),
&root_space_and_clip,
&CommonItemProperties::new(content_bounds, root_space_and_clip),
simple_box_bounds,
offset,
color,

Просмотреть файл

@ -17,7 +17,7 @@ use rayon::prelude::*;
use std::collections::HashMap;
use std::sync::Arc;
use webrender::api::{self, DisplayListBuilder, DocumentId, PipelineId, RenderApi, Transaction};
use webrender::api::{ColorF, SpaceAndClipInfo};
use webrender::api::{ColorF, CommonItemProperties, SpaceAndClipInfo};
use webrender::api::units::*;
use webrender::euclid::size2;
@ -220,17 +220,18 @@ impl Example for App {
None,
);
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
builder.push_simple_stacking_context(
&api::LayoutPrimitiveInfo::new(bounds),
LayoutPoint::zero(),
space_and_clip.spatial_id,
true,
);
let bounds = (30, 30).by(500, 500);
builder.push_image(
&api::LayoutPrimitiveInfo::new((30, 30).by(500, 500)),
&space_and_clip,
&CommonItemProperties::new(bounds, space_and_clip),
bounds,
LayoutSize::new(500.0, 500.0),
LayoutSize::new(0.0, 0.0),
api::ImageRendering::Auto,
@ -239,9 +240,10 @@ impl Example for App {
ColorF::WHITE,
);
let bounds = (600, 600).by(200, 200);
builder.push_image(
&api::LayoutPrimitiveInfo::new((600, 600).by(200, 200)),
&space_and_clip,
&CommonItemProperties::new(bounds, space_and_clip),
bounds,
LayoutSize::new(200.0, 200.0),
LayoutSize::new(0.0, 0.0),
api::ImageRendering::Auto,

Просмотреть файл

@ -116,12 +116,12 @@ impl Example for App {
);
builder.push_simple_stacking_context(
&LayoutPrimitiveInfo::new(doc.content_rect),
doc.content_rect.origin,
space_and_clip.spatial_id,
true,
);
builder.push_rect(
&LayoutPrimitiveInfo::new(local_rect),
&space_and_clip,
&CommonItemProperties::new(local_rect, space_and_clip),
doc.color,
);
builder.pop_stacking_context();

Просмотреть файл

@ -113,7 +113,6 @@ impl App {
None,
);
let info = LayoutPrimitiveInfo::new(document.content_rect);
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
let mut builder = DisplayListBuilder::new(
document.pipeline_id,
@ -121,11 +120,15 @@ impl App {
);
builder.push_simple_stacking_context(
&info,
document.content_rect.origin,
space_and_clip.spatial_id,
true,
);
builder.push_rect(&info, &space_and_clip, ColorF::new(1.0, 1.0, 0.0, 1.0));
builder.push_rect(
&CommonItemProperties::new(document.content_rect, space_and_clip),
ColorF::new(1.0, 1.0, 0.0, 1.0)
);
builder.pop_stacking_context();
txn.set_root_pipeline(pipeline_id);
@ -158,18 +161,19 @@ impl Example for App {
self.init_output_document(api, FramebufferIntSize::new(200, 200), device_pixel_ratio);
}
let info = LayoutPrimitiveInfo::new((100, 100).to(200, 200));
let bounds = (100, 100).to(200, 200);
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
builder.push_simple_stacking_context(
&info,
bounds.origin,
space_and_clip.spatial_id,
true,
);
builder.push_image(
&info,
&space_and_clip,
info.rect.size,
&CommonItemProperties::new(bounds, space_and_clip),
bounds,
bounds.size,
LayoutSize::zero(),
ImageRendering::Auto,
AlphaType::PremultipliedAlpha,

Просмотреть файл

@ -38,14 +38,17 @@ impl Example for App {
let mut sub_builder = DisplayListBuilder::new(sub_pipeline_id, sub_bounds.size);
let mut space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
let info = LayoutPrimitiveInfo::new(sub_bounds);
sub_builder.push_simple_stacking_context(
&info,
sub_bounds.origin,
space_and_clip.spatial_id,
true,
);
// green rect visible == success
sub_builder.push_rect(&info, &space_and_clip, ColorF::new(0.0, 1.0, 0.0, 1.0));
sub_builder.push_rect(
&CommonItemProperties::new(sub_bounds, space_and_clip),
ColorF::new(0.0, 1.0, 0.0, 1.0)
);
sub_builder.pop_stacking_context();
let mut txn = Transaction::new();
@ -59,7 +62,7 @@ impl Example for App {
api.send_transaction(document_id, txn);
space_and_clip.spatial_id = builder.push_reference_frame(
&sub_bounds,
sub_bounds.origin,
space_and_clip.spatial_id,
TransformStyle::Flat,
PropertyBinding::Binding(PropertyBindingKey::new(42), LayoutTransform::identity()),
@ -67,14 +70,18 @@ impl Example for App {
);
// And this is for the root pipeline
let info = LayoutPrimitiveInfo::new(sub_bounds);
builder.push_simple_stacking_context(
&info,
sub_bounds.origin,
space_and_clip.spatial_id,
true,
);
// red rect under the iframe: if this is visible, things have gone wrong
builder.push_rect(&info, &space_and_clip, ColorF::new(1.0, 0.0, 0.0, 1.0));
builder.push_iframe(&info, &space_and_clip, sub_pipeline_id, false);
builder.push_rect(
&CommonItemProperties::new(sub_bounds, space_and_clip),
ColorF::new(1.0, 0.0, 0.0, 1.0)
);
builder.push_iframe(sub_bounds, sub_bounds, &space_and_clip, sub_pipeline_id, false);
builder.pop_stacking_context();
builder.pop_reference_frame();
}

Просмотреть файл

@ -39,23 +39,22 @@ impl Example for App {
);
let bounds = (0, 0).to(512, 512);
let info = LayoutPrimitiveInfo::new(bounds);
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
builder.push_simple_stacking_context(
&info,
bounds.origin,
space_and_clip.spatial_id,
true,
);
let image_size = LayoutSize::new(100.0, 100.0);
let info = LayoutPrimitiveInfo::with_clip_rect(
LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
bounds,
);
builder.push_image(
&info,
&space_and_clip,
&CommonItemProperties::new(
LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
space_and_clip,
),
bounds,
image_size,
LayoutSize::zero(),
ImageRendering::Auto,
@ -64,13 +63,12 @@ impl Example for App {
ColorF::WHITE,
);
let info = LayoutPrimitiveInfo::with_clip_rect(
LayoutRect::new(LayoutPoint::new(250.0, 100.0), image_size),
bounds,
);
builder.push_image(
&info,
&space_and_clip,
&CommonItemProperties::new(
LayoutRect::new(LayoutPoint::new(250.0, 100.0), image_size),
space_and_clip,
),
bounds,
image_size,
LayoutSize::zero(),
ImageRendering::Pixelated,

Просмотреть файл

@ -189,17 +189,21 @@ impl Window {
let space_and_clip = SpaceAndClipInfo::root_scroll(self.pipeline_id);
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
let info = LayoutPrimitiveInfo::new(bounds);
builder.push_simple_stacking_context(
&info,
bounds.origin,
space_and_clip.spatial_id,
true,
);
let info = LayoutPrimitiveInfo::new(LayoutRect::new(
LayoutPoint::new(100.0, 100.0),
LayoutSize::new(100.0, 200.0)
));
builder.push_rect(&info, &space_and_clip, ColorF::new(0.0, 1.0, 0.0, 1.0));
builder.push_rect(
&CommonItemProperties::new(
LayoutRect::new(
LayoutPoint::new(100.0, 200.0),
LayoutSize::new(100.0, 200.0),
),
space_and_clip,
),
ColorF::new(0.0, 1.0, 0.0, 1.0));
let text_bounds = LayoutRect::new(
LayoutPoint::new(100.0, 50.0),
@ -256,10 +260,12 @@ impl Window {
},
];
let info = LayoutPrimitiveInfo::new(text_bounds);
builder.push_text(
&info,
&space_and_clip,
&CommonItemProperties::new(
text_bounds,
space_and_clip,
),
text_bounds,
&glyphs,
self.font_instance_key,
ColorF::new(1.0, 1.0, 0.0, 1.0),

Просмотреть файл

@ -32,13 +32,11 @@ impl Example for App {
pipeline_id: PipelineId,
_document_id: DocumentId,
) {
let info = LayoutPrimitiveInfo::new(
LayoutRect::new(LayoutPoint::zero(), builder.content_size())
);
let root_space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
builder.push_simple_stacking_context(
&info,
LayoutPoint::zero(),
root_space_and_clip.spatial_id,
true,
);
if true {
@ -46,8 +44,9 @@ impl Example for App {
// let's make a scrollbox
let scrollbox = (0, 0).to(300, 400);
builder.push_simple_stacking_context(
&LayoutPrimitiveInfo::new((10, 10).by(0, 0)),
LayoutPoint::new(10., 10.),
root_space_and_clip.spatial_id,
true,
);
// set the scrolling clip
let space_and_clip1 = builder.define_scroll_frame(
@ -63,21 +62,23 @@ impl Example for App {
// now put some content into it.
// start with a white background
let mut info = LayoutPrimitiveInfo::new((0, 0).to(1000, 1000));
info.tag = Some((0, 1));
builder.push_rect(&info, &space_and_clip1, ColorF::new(1.0, 1.0, 1.0, 1.0));
let mut info = CommonItemProperties::new((0, 0).to(1000, 1000), space_and_clip1);
info.hit_info = Some((0, 1));
builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0));
// let's make a 50x50 blue square as a visual reference
let mut info = LayoutPrimitiveInfo::new((0, 0).to(50, 50));
info.tag = Some((0, 2));
builder.push_rect(&info, &space_and_clip1, ColorF::new(0.0, 0.0, 1.0, 1.0));
let mut info = CommonItemProperties::new((0, 0).to(50, 50), space_and_clip1);
info.hit_info = Some((0, 2));
builder.push_rect(&info, ColorF::new(0.0, 0.0, 1.0, 1.0));
// and a 50x50 green square next to it with an offset clip
// to see what that looks like
let mut info =
LayoutPrimitiveInfo::with_clip_rect((50, 0).to(100, 50), (60, 10).to(110, 60));
info.tag = Some((0, 3));
builder.push_rect(&info, &space_and_clip1, ColorF::new(0.0, 1.0, 0.0, 1.0));
let mut info = CommonItemProperties::new(
(50, 0).to(100, 50).intersection(&(60, 10).to(110, 60)).unwrap(),
space_and_clip1,
);
info.hit_info = Some((0, 3));
builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));
// Below the above rectangles, set up a nested scrollbox. It's still in
// the same stacking context, so note that the rects passed in need to
@ -95,15 +96,18 @@ impl Example for App {
// give it a giant gray background just to distinguish it and to easily
// visually identify the nested scrollbox
let mut info = LayoutPrimitiveInfo::new((-1000, -1000).to(5000, 5000));
info.tag = Some((0, 4));
builder.push_rect(&info, &space_and_clip2, ColorF::new(0.5, 0.5, 0.5, 1.0));
let mut info = CommonItemProperties::new(
(-1000, -1000).to(5000, 5000),
space_and_clip2,
);
info.hit_info = Some((0, 4));
builder.push_rect(&info, ColorF::new(0.5, 0.5, 0.5, 1.0));
// add a teal square to visualize the scrolling/clipping behaviour
// as you scroll the nested scrollbox
let mut info = LayoutPrimitiveInfo::new((0, 200).to(50, 250));
info.tag = Some((0, 5));
builder.push_rect(&info, &space_and_clip2, ColorF::new(0.0, 1.0, 1.0, 1.0));
let mut info = CommonItemProperties::new((0, 200).to(50, 250), space_and_clip2);
info.hit_info = Some((0, 5));
builder.push_rect(&info, ColorF::new(0.0, 1.0, 1.0, 1.0));
// Add a sticky frame. It will "stick" twice while scrolling, once
// at a margin of 10px from the bottom, for 40 pixels of scrolling,
@ -118,22 +122,27 @@ impl Example for App {
LayoutVector2D::new(0.0, 0.0)
);
let mut info = LayoutPrimitiveInfo::new((50, 350).by(50, 50));
info.tag = Some((0, 6));
builder.push_rect(
&info,
&SpaceAndClipInfo {
let mut info = CommonItemProperties::new(
(50, 350).by(50, 50),
SpaceAndClipInfo {
spatial_id: sticky_id,
clip_id: space_and_clip2.clip_id,
},
);
info.hit_info = Some((0, 6));
builder.push_rect(
&info,
ColorF::new(0.5, 0.5, 1.0, 1.0),
);
// just for good measure add another teal square further down and to
// the right, which can be scrolled into view by the user
let mut info = LayoutPrimitiveInfo::new((250, 350).to(300, 400));
info.tag = Some((0, 7));
builder.push_rect(&info, &space_and_clip2, ColorF::new(0.0, 1.0, 1.0, 1.0));
let mut info = CommonItemProperties::new(
(250, 350).to(300, 400),
space_and_clip2,
);
info.hit_info = Some((0, 7));
builder.push_rect(&info, ColorF::new(0.0, 1.0, 1.0, 1.0));
builder.pop_stacking_context();
}

Просмотреть файл

@ -97,12 +97,12 @@ impl Example for App {
_document_id: DocumentId,
) {
let bounds = (0, 0).to(512, 512);
let info = LayoutPrimitiveInfo::new(bounds);
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
builder.push_simple_stacking_context(
&info,
bounds.origin,
space_and_clip.spatial_id,
true,
);
let x0 = 50.0;
@ -136,17 +136,17 @@ impl Example for App {
for (i, key) in self.stress_keys.iter().enumerate() {
let x = (i % 128) as f32;
let y = (i / 128) as f32;
let info = LayoutPrimitiveInfo::with_clip_rect(
let info = CommonItemProperties::new(
LayoutRect::new(
LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y),
image_size,
),
bounds,
space_and_clip,
);
builder.push_image(
&info,
&space_and_clip,
bounds,
image_size,
LayoutSize::zero(),
ImageRendering::Auto,
@ -158,13 +158,13 @@ impl Example for App {
if let Some(image_key) = self.image_key {
let image_size = LayoutSize::new(100.0, 100.0);
let info = LayoutPrimitiveInfo::with_clip_rect(
let info = CommonItemProperties::new(
LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
bounds,
space_and_clip,
);
builder.push_image(
&info,
&space_and_clip,
bounds,
image_size,
LayoutSize::zero(),
ImageRendering::Auto,
@ -176,13 +176,13 @@ impl Example for App {
let swap_key = self.swap_keys[self.swap_index];
let image_size = LayoutSize::new(64.0, 64.0);
let info = LayoutPrimitiveInfo::with_clip_rect(
let info = CommonItemProperties::new(
LayoutRect::new(LayoutPoint::new(100.0, 400.0), image_size),
bounds,
space_and_clip,
);
builder.push_image(
&info,
&space_and_clip,
bounds,
image_size,
LayoutSize::zero(),
ImageRendering::Auto,

Просмотреть файл

@ -94,12 +94,12 @@ impl Example for App {
_document_id: DocumentId,
) {
let bounds = LayoutRect::new(LayoutPoint::zero(), builder.content_size());
let info = LayoutPrimitiveInfo::new(bounds);
let space_and_clip = SpaceAndClipInfo::root_scroll(pipeline_id);
builder.push_simple_stacking_context(
&info,
bounds.origin,
space_and_clip.spatial_id,
true,
);
let yuv_chanel1 = api.generate_image_key();
@ -155,26 +155,26 @@ impl Example for App {
None,
);
let info = LayoutPrimitiveInfo::with_clip_rect(
let info = CommonItemProperties::new(
LayoutRect::new(LayoutPoint::new(100.0, 0.0), LayoutSize::new(100.0, 100.0)),
bounds,
space_and_clip,
);
builder.push_yuv_image(
&info,
&space_and_clip,
bounds,
YuvData::NV12(yuv_chanel1, yuv_chanel2),
ColorDepth::Color8,
YuvColorSpace::Rec601,
ImageRendering::Auto,
);
let info = LayoutPrimitiveInfo::with_clip_rect(
let info = CommonItemProperties::new(
LayoutRect::new(LayoutPoint::new(300.0, 0.0), LayoutSize::new(100.0, 100.0)),
bounds,
space_and_clip,
);
builder.push_yuv_image(
&info,
&space_and_clip,
bounds,
YuvData::PlanarYCbCr(yuv_chanel1, yuv_chanel2_1, yuv_chanel3),
ColorDepth::Color8,
YuvColorSpace::Rec601,

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderRadius, BorderSide, BorderStyle, ColorF, ColorU};
use api::{LayoutPrimitiveInfo, NormalBorder as ApiNormalBorder, RepeatMode};
use api::{NormalBorder as ApiNormalBorder, RepeatMode};
use api::units::*;
use ellipse::Ellipse;
use euclid::vec2;
@ -13,6 +13,7 @@ use prim_store::{BorderSegmentInfo, BrushSegment, NinePatchDescriptor};
use prim_store::{EdgeAaSegmentMask, ScrollNodeAndClipChain};
use prim_store::borders::{NormalBorderPrim, NormalBorderData};
use util::{lerp, RectHelpers};
use internal_types::LayoutPrimitiveInfo;
// Using 2048 as the maximum radius in device space before which we
// start stretching is up for debate.

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, LayoutPrimitiveInfo, PrimitiveKeyKind};
use api::{BorderRadius, BoxShadowClipMode, ClipMode, ColorF, PrimitiveKeyKind};
use api::MAX_BLUR_RADIUS;
use api::units::*;
use clip::ClipItemKey;
@ -12,6 +12,7 @@ use gpu_types::BoxShadowStretchMode;
use prim_store::ScrollNodeAndClipChain;
use render_task::RenderTaskCacheEntryHandle;
use util::RectHelpers;
use internal_types::LayoutPrimitiveInfo;
#[derive(Debug, Clone, MallocSizeOf)]
#[cfg_attr(feature = "capture", derive(Serialize))]

Просмотреть файл

@ -3,13 +3,13 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter};
use api::{ClipId, ColorF, ComplexClipRegion, RasterSpace};
use api::{DisplayItemRef, ExtendMode, ExternalScrollId};
use api::{ClipId, ColorF, CommonItemProperties, ComplexClipRegion, RasterSpace};
use api::{DisplayItem, DisplayItemRef, ExtendMode, ExternalScrollId};
use api::{FilterOp, FontInstanceKey, GlyphInstance, GlyphOptions, GradientStop};
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, ColorDepth};
use api::{LayoutPrimitiveInfo, LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
use api::{LineOrientation, LineStyle, NinePatchBorderSource, PipelineId};
use api::{PropertyBinding, ReferenceFrame, ReferenceFrameKind, ScrollFrameDisplayItem, ScrollSensitivity};
use api::{Shadow, SpaceAndClipInfo, SpatialId, SpecificDisplayItem, StackingContext, StickyFrameDisplayItem};
use api::{Shadow, SpaceAndClipInfo, SpatialId, StackingContext, StickyFrameDisplayItem};
use api::{ClipMode, PrimitiveKeyKind, TransformStyle, YuvColorSpace, YuvData, TempFilterData};
use api::units::*;
use clip::{ClipChainId, ClipRegion, ClipItemKey, ClipStore};
@ -19,7 +19,7 @@ use glyph_rasterizer::FontInstance;
use hit_test::{HitTestingItem, HitTestingScene};
use image::simplify_repeated_primitive;
use intern::Interner;
use internal_types::{FastHashMap, FastHashSet};
use internal_types::{FastHashMap, FastHashSet, LayoutPrimitiveInfo};
use picture::{Picture3DContext, PictureCompositeMode, PicturePrimitive, PictureOptions};
use picture::{BlitReason, PrimitiveList, TileCache};
use prim_store::{PrimitiveInstance, PrimitiveSceneData};
@ -51,6 +51,8 @@ struct ClipNode {
count: usize,
}
impl ClipNode {
fn new(id: ClipChainId, count: usize) -> Self {
ClipNode {
@ -651,12 +653,11 @@ impl<'a> DisplayListFlattener<'a> {
fn flatten_sticky_frame(
&mut self,
item: &DisplayItemRef,
info: &StickyFrameDisplayItem,
parent_node_index: SpatialNodeIndex,
) {
let current_offset = self.current_offset(parent_node_index);
let frame_rect = item.rect().translate(&current_offset);
let frame_rect = info.bounds.translate(&current_offset);
let sticky_frame_info = StickyFrameInfo::new(
frame_rect,
info.margins,
@ -683,7 +684,7 @@ impl<'a> DisplayListFlattener<'a> {
let complex_clips = self.get_complex_clips(pipeline_id, item.complex_clip().0);
let current_offset = self.current_offset(parent_node_index);
let clip_region = ClipRegion::create_for_clip_node(
*item.clip_rect(),
info.clip_rect,
complex_clips,
info.image_mask,
&current_offset,
@ -693,9 +694,9 @@ impl<'a> DisplayListFlattener<'a> {
// SpatialNode::scroll(..) API as well as for properly setting sticky
// positioning offsets.
let frame_rect = clip_region.main;
let content_size = item.rect().size;
let content_size = info.content_rect.size;
self.add_clip_node(info.clip_id, item.space_and_clip_info(), clip_region);
self.add_clip_node(info.clip_id, &info.parent_space_and_clip, clip_region);
self.add_scroll_frame(
info.scroll_frame_id,
@ -816,7 +817,6 @@ impl<'a> DisplayListFlattener<'a> {
fn flatten_iframe(
&mut self,
item: &DisplayItemRef,
info: &IframeDisplayItem,
spatial_node_index: SpatialNodeIndex,
) {
@ -832,15 +832,15 @@ impl<'a> DisplayListFlattener<'a> {
let current_offset = self.current_offset(spatial_node_index);
let clip_chain_index = self.add_clip_node(
ClipId::root(iframe_pipeline_id),
item.space_and_clip_info(),
&info.space_and_clip,
ClipRegion::create_for_clip_node_with_local_clip(
item.clip_rect(),
&info.clip_rect,
&current_offset,
),
);
self.pipeline_clip_chain_stack.push(clip_chain_index);
let bounds = item.rect();
let bounds = info.bounds;
let origin = current_offset + bounds.origin.to_vector();
let spatial_node_index = self.push_reference_frame(
SpatialId::root_reference_frame(iframe_pipeline_id),
@ -876,32 +876,79 @@ impl<'a> DisplayListFlattener<'a> {
self.pipeline_clip_chain_stack.pop();
}
fn get_space(&mut self, spatial_id: &SpatialId) -> SpatialNodeIndex {
self.id_to_index_mapper.get_spatial_node_index(*spatial_id)
}
fn get_clip_and_scroll(
&mut self,
clip_id: &ClipId,
spatial_id: &SpatialId,
apply_pipeline_clip: bool
) -> ScrollNodeAndClipChain {
ScrollNodeAndClipChain::new(
self.id_to_index_mapper.get_spatial_node_index(*spatial_id),
if !apply_pipeline_clip && clip_id.is_root() {
ClipChainId::NONE
} else if clip_id.is_valid() {
self.id_to_index_mapper.get_clip_chain_id(*clip_id)
} else {
ClipChainId::INVALID
},
)
}
fn process_common_properties(
&mut self,
common: &CommonItemProperties,
apply_pipeline_clip: bool
) -> (LayoutPrimitiveInfo, ScrollNodeAndClipChain) {
self.process_common_properties_with_bounds(common, &common.clip_rect, apply_pipeline_clip)
}
fn process_common_properties_with_bounds(
&mut self,
common: &CommonItemProperties,
bounds: &LayoutRect,
apply_pipeline_clip: bool
) -> (LayoutPrimitiveInfo, ScrollNodeAndClipChain) {
let clip_and_scroll = self.get_clip_and_scroll(
&common.clip_id,
&common.spatial_id,
apply_pipeline_clip
);
let current_offset = self.current_offset(clip_and_scroll.spatial_node_index);
let clip_rect = common.clip_rect.translate(&current_offset);
let rect = bounds.translate(&current_offset);
let layout = LayoutPrimitiveInfo {
rect,
clip_rect,
is_backface_visible: common.is_backface_visible,
hit_info: common.hit_info,
};
(layout, clip_and_scroll)
}
fn flatten_item<'b>(
&'b mut self,
item: DisplayItemRef<'a, 'b>,
pipeline_id: PipelineId,
apply_pipeline_clip: bool,
) -> Option<BuiltDisplayListIter<'a>> {
let space_and_clip = item.space_and_clip_info();
let clip_and_scroll = ScrollNodeAndClipChain::new(
self.id_to_index_mapper.get_spatial_node_index(space_and_clip.spatial_id),
if !apply_pipeline_clip && space_and_clip.clip_id.is_root() {
ClipChainId::NONE
} else if space_and_clip.clip_id.is_valid() {
self.id_to_index_mapper.get_clip_chain_id(space_and_clip.clip_id)
} else {
ClipChainId::INVALID
},
);
let prim_info = item.get_layout_primitive_info(
&self.current_offset(clip_and_scroll.spatial_node_index),
);
match *item.item() {
SpecificDisplayItem::Image(ref info) => {
DisplayItem::Image(ref info) => {
let (mut layout, clip_and_scroll) = self.process_common_properties_with_bounds(
&info.common,
&info.bounds,
apply_pipeline_clip,
);
self.add_image(
clip_and_scroll,
&prim_info,
&layout,
info.stretch_size,
info.tile_spacing,
None,
@ -911,53 +958,99 @@ impl<'a> DisplayListFlattener<'a> {
info.color,
);
}
SpecificDisplayItem::YuvImage(ref info) => {
DisplayItem::YuvImage(ref info) => {
let (mut layout, clip_and_scroll) = self.process_common_properties_with_bounds(
&info.common,
&info.bounds,
apply_pipeline_clip,
);
self.add_yuv_image(
clip_and_scroll,
&prim_info,
&layout,
info.yuv_data,
info.color_depth,
info.color_space,
info.image_rendering,
);
}
SpecificDisplayItem::Text(ref text_info) => {
DisplayItem::Text(ref info) => {
let (mut layout, clip_and_scroll) = self.process_common_properties_with_bounds(
&info.common,
&info.bounds,
apply_pipeline_clip,
);
self.add_text(
clip_and_scroll,
&prim_info,
&text_info.font_key,
&text_info.color,
&layout,
&info.font_key,
&info.color,
item.glyphs(),
text_info.glyph_options,
info.glyph_options,
pipeline_id,
);
}
SpecificDisplayItem::Rectangle(ref info) => {
DisplayItem::Rectangle(ref info) => {
let (layout, clip_and_scroll) = self.process_common_properties(
&info.common,
apply_pipeline_clip,
);
self.add_solid_rectangle(
clip_and_scroll,
&prim_info,
&layout,
info.color,
);
}
SpecificDisplayItem::ClearRectangle => {
self.add_clear_rectangle(
DisplayItem::HitTest(ref info) => {
let (layout, clip_and_scroll) = self.process_common_properties(
&info.common,
apply_pipeline_clip,
);
self.add_solid_rectangle(
clip_and_scroll,
&prim_info,
&layout,
ColorF::TRANSPARENT,
);
}
SpecificDisplayItem::Line(ref info) => {
DisplayItem::ClearRectangle(ref info) => {
let (layout, clip_and_scroll) = self.process_common_properties(
&info.common,
apply_pipeline_clip,
);
self.add_clear_rectangle(
clip_and_scroll,
&layout,
);
}
DisplayItem::Line(ref info) => {
let (mut layout, clip_and_scroll) = self.process_common_properties_with_bounds(
&info.common,
&info.area,
apply_pipeline_clip,
);
self.add_line(
clip_and_scroll,
&prim_info,
&layout,
info.wavy_line_thickness,
info.orientation,
info.color,
info.style,
);
}
SpecificDisplayItem::Gradient(ref info) => {
DisplayItem::Gradient(ref info) => {
let (mut layout, clip_and_scroll) = self.process_common_properties_with_bounds(
&info.common,
&info.bounds,
apply_pipeline_clip,
);
if let Some(prim_key_kind) = self.create_linear_gradient_prim(
&prim_info,
&layout,
info.gradient.start_point,
info.gradient.end_point,
item.gradient_stops(),
@ -969,15 +1062,21 @@ impl<'a> DisplayListFlattener<'a> {
) {
self.add_nonshadowable_primitive(
clip_and_scroll,
&prim_info,
&layout,
Vec::new(),
prim_key_kind,
);
}
}
SpecificDisplayItem::RadialGradient(ref info) => {
DisplayItem::RadialGradient(ref info) => {
let (mut layout, clip_and_scroll) = self.process_common_properties_with_bounds(
&info.common,
&info.bounds,
apply_pipeline_clip,
);
let prim_key_kind = self.create_radial_gradient_prim(
&prim_info,
&layout,
info.gradient.center,
info.gradient.start_offset * info.gradient.radius.width,
info.gradient.end_offset * info.gradient.radius.width,
@ -989,86 +1088,96 @@ impl<'a> DisplayListFlattener<'a> {
pipeline_id,
None,
);
self.add_nonshadowable_primitive(
clip_and_scroll,
&prim_info,
&layout,
Vec::new(),
prim_key_kind,
);
}
SpecificDisplayItem::BoxShadow(ref box_shadow_info) => {
let current_offset = self.current_offset(clip_and_scroll.spatial_node_index);
let bounds = box_shadow_info
.box_bounds
.translate(&current_offset);
let mut prim_info = prim_info.clone();
prim_info.rect = bounds;
DisplayItem::BoxShadow(ref info) => {
let (mut layout, clip_and_scroll) = self.process_common_properties_with_bounds(
&info.common,
&info.box_bounds,
apply_pipeline_clip,
);
self.add_box_shadow(
clip_and_scroll,
&prim_info,
&box_shadow_info.offset,
box_shadow_info.color,
box_shadow_info.blur_radius,
box_shadow_info.spread_radius,
box_shadow_info.border_radius,
box_shadow_info.clip_mode,
&layout,
&info.offset,
info.color,
info.blur_radius,
info.spread_radius,
info.border_radius,
info.clip_mode,
);
}
SpecificDisplayItem::Border(ref info) => {
DisplayItem::Border(ref info) => {
let (mut layout, clip_and_scroll) = self.process_common_properties_with_bounds(
&info.common,
&info.bounds,
apply_pipeline_clip,
);
self.add_border(
clip_and_scroll,
&prim_info,
&layout,
info,
item.gradient_stops(),
pipeline_id,
);
}
SpecificDisplayItem::PushStackingContext(ref info) => {
DisplayItem::PushStackingContext(ref info) => {
let space = self.get_space(&info.spatial_id);
let mut subtraversal = item.sub_iter();
self.flatten_stacking_context(
&mut subtraversal,
pipeline_id,
&info.stacking_context,
clip_and_scroll.spatial_node_index,
item.rect().origin,
space,
info.origin,
item.filters(),
item.filter_datas(),
prim_info.is_backface_visible,
info.is_backface_visible,
apply_pipeline_clip,
);
return Some(subtraversal);
}
SpecificDisplayItem::PushReferenceFrame(ref info) => {
DisplayItem::PushReferenceFrame(ref info) => {
let parent_space = self.get_space(&info.parent_spatial_id);
let mut subtraversal = item.sub_iter();
self.flatten_reference_frame(
&mut subtraversal,
pipeline_id,
clip_and_scroll.spatial_node_index,
item.rect().origin,
parent_space,
info.origin,
&info.reference_frame,
apply_pipeline_clip,
);
return Some(subtraversal);
}
SpecificDisplayItem::Iframe(ref info) => {
DisplayItem::Iframe(ref info) => {
let space = self.get_space(&info.space_and_clip.spatial_id);
self.flatten_iframe(
&item,
info,
clip_and_scroll.spatial_node_index,
space,
);
}
SpecificDisplayItem::Clip(ref info) => {
let current_offset = self.current_offset(clip_and_scroll.spatial_node_index);
DisplayItem::Clip(ref info) => {
let parent_space = self.get_space(&info.parent_space_and_clip.spatial_id);
let current_offset = self.current_offset(parent_space);
let complex_clips = self.get_complex_clips(pipeline_id, item.complex_clip().0);
let clip_region = ClipRegion::create_for_clip_node(
*item.clip_rect(),
info.clip_rect,
complex_clips,
info.image_mask,
&current_offset,
);
self.add_clip_node(info.id, space_and_clip, clip_region);
self.add_clip_node(info.id, &info.parent_space_and_clip, clip_region);
}
SpecificDisplayItem::ClipChain(ref info) => {
DisplayItem::ClipChain(ref info) => {
// For a user defined clip-chain the parent (if specified) must
// refer to another user defined clip-chain. If none is specified,
// the parent is the root clip-chain for the given pipeline. This
@ -1137,35 +1246,42 @@ impl<'a> DisplayListFlattener<'a> {
// this ClipId available as a source to other user defined clip chains.
self.id_to_index_mapper.add_clip_chain(ClipId::ClipChain(info.id), clip_chain_id, 0);
},
SpecificDisplayItem::ScrollFrame(ref info) => {
DisplayItem::ScrollFrame(ref info) => {
let parent_space = self.get_space(&info.parent_space_and_clip.spatial_id);
self.flatten_scroll_frame(
&item,
info,
clip_and_scroll.spatial_node_index,
parent_space,
pipeline_id,
);
}
SpecificDisplayItem::StickyFrame(ref info) => {
DisplayItem::StickyFrame(ref info) => {
let parent_space = self.get_space(&info.parent_spatial_id);
self.flatten_sticky_frame(
&item,
info,
clip_and_scroll.spatial_node_index,
parent_space,
);
}
// Do nothing; these are dummy items for the display list parser
SpecificDisplayItem::SetGradientStops => {}
SpecificDisplayItem::SetFilterOps => {}
SpecificDisplayItem::SetFilterData => {}
DisplayItem::SetGradientStops => {}
DisplayItem::SetFilterOps => {}
DisplayItem::SetFilterData => {}
SpecificDisplayItem::PopReferenceFrame |
SpecificDisplayItem::PopStackingContext => {
DisplayItem::PopReferenceFrame |
DisplayItem::PopStackingContext => {
unreachable!("Should have returned in parent method.")
}
SpecificDisplayItem::PushShadow(shadow) => {
self.push_shadow(shadow, clip_and_scroll);
DisplayItem::PushShadow(info) => {
let clip_and_scroll = self.get_clip_and_scroll(
&info.space_and_clip.clip_id,
&info.space_and_clip.spatial_id,
apply_pipeline_clip
);
self.push_shadow(info.shadow, clip_and_scroll);
}
SpecificDisplayItem::PopAllShadows => {
DisplayItem::PopAllShadows => {
self.pop_all_shadows();
}
}
@ -1257,7 +1373,7 @@ impl<'a> DisplayListFlattener<'a> {
info: &LayoutPrimitiveInfo,
clip_and_scroll: ScrollNodeAndClipChain
) {
let tag = match info.tag {
let tag = match info.hit_info {
Some(tag) => tag,
None => return,
};

Просмотреть файл

@ -3,12 +3,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{BorderRadius, ClipMode, HitTestFlags, HitTestItem, HitTestResult, ItemTag};
use api::{LayoutPrimitiveInfo, PipelineId};
use api::PipelineId;
use api::units::*;
use clip::{ClipChainId, ClipDataStore, ClipNode, ClipItem, ClipStore};
use clip::{rounded_rectangle_contains_point};
use clip_scroll_tree::{SpatialNodeIndex, ClipScrollTree};
use internal_types::FastHashMap;
use internal_types::{FastHashMap, LayoutPrimitiveInfo};
use std::{ops, u32};
use std::sync::Arc;
use util::{LayoutToWorldFastTransform, WorldToLayoutFastTransform};

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{DebugCommand, DocumentId, ExternalImageData, ExternalImageId};
use api::{ImageFormat, NotificationRequest};
use api::{ImageFormat, ItemTag, NotificationRequest};
use api::units::*;
use device::TextureFilter;
use renderer::PipelineInfo;
@ -323,3 +323,25 @@ impl ResourceCacheError {
}
}
}
/// Primitive metadata we pass around in a bunch of places
#[derive(Copy, Clone, Debug)]
pub struct LayoutPrimitiveInfo {
/// NOTE: this is *ideally* redundant with the clip_rect
/// but that's an ongoing project, so for now it exists and is used :(
pub rect: LayoutRect,
pub clip_rect: LayoutRect,
pub is_backface_visible: bool,
pub hit_info: Option<ItemTag>,
}
impl LayoutPrimitiveInfo {
pub fn with_clip_rect(rect: LayoutRect, clip_rect: LayoutRect) -> Self {
Self {
rect,
clip_rect,
is_backface_visible: true,
hit_info: None,
}
}
}

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{LayoutPrimitiveInfo, NormalBorder, PremultipliedColorF, Shadow};
use api::{NormalBorder, PremultipliedColorF, Shadow};
use api::units::*;
use border::create_border_segments;
use border::NormalBorderAu;
@ -10,6 +10,7 @@ use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState};
use gpu_cache::GpuDataRequest;
use intern;
use internal_types::LayoutPrimitiveInfo;
use prim_store::{
BorderSegmentInfo, BrushSegment, NinePatchDescriptor, PrimKey,
PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,
@ -358,7 +359,7 @@ fn test_struct_sizes() {
assert_eq!(mem::size_of::<NormalBorderPrim>(), 84, "NormalBorderPrim size changed");
assert_eq!(mem::size_of::<NormalBorderTemplate>(), 208, "NormalBorderTemplate size changed");
assert_eq!(mem::size_of::<NormalBorderKey>(), 96, "NormalBorderKey size changed");
assert_eq!(mem::size_of::<ImageBorder>(), 92, "ImageBorder size changed");
assert_eq!(mem::size_of::<ImageBorder>(), 84, "ImageBorder size changed");
assert_eq!(mem::size_of::<ImageBorderTemplate>(), 72, "ImageBorderTemplate size changed");
assert_eq!(mem::size_of::<ImageBorderKey>(), 104, "ImageBorderKey size changed");
assert_eq!(mem::size_of::<ImageBorderKey>(), 96, "ImageBorderKey size changed");
}

Просмотреть файл

@ -4,7 +4,7 @@
use api::{
ColorF, ColorU, ExtendMode, GradientStop,
LayoutPrimitiveInfo, PremultipliedColorF, LineOrientation,
PremultipliedColorF, LineOrientation,
};
use api::units::{LayoutPoint, LayoutSize, LayoutVector2D};
use display_list_flattener::IsVisible;
@ -12,6 +12,7 @@ use euclid::approxeq::ApproxEq;
use frame_builder::FrameBuildingState;
use gpu_cache::{GpuCacheHandle, GpuDataRequest};
use intern::{Internable, InternDebug, Handle as InternHandle};
use internal_types::LayoutPrimitiveInfo;
use prim_store::{BrushSegment, GradientTileRange, VectorKey};
use prim_store::{PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData};
use prim_store::{PrimKeyCommonData, PrimTemplateCommonData, PrimitiveStore};

Просмотреть файл

@ -4,7 +4,7 @@
use api::{
AlphaType, ColorDepth, ColorF, ColorU,
ImageKey as ApiImageKey, ImageRendering, LayoutPrimitiveInfo,
ImageKey as ApiImageKey, ImageRendering,
PremultipliedColorF, Shadow, YuvColorSpace, YuvFormat,
};
use api::units::*;
@ -12,6 +12,7 @@ use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::FrameBuildingState;
use gpu_cache::{GpuDataRequest};
use intern::{Internable, InternDebug, Handle as InternHandle};
use internal_types::LayoutPrimitiveInfo;
use prim_store::{
EdgeAaSegmentMask, OpacityBindingIndex, PrimitiveInstanceKind,
PrimitiveOpacity, PrimitiveSceneData, PrimKey, PrimKeyCommonData,
@ -533,10 +534,10 @@ fn test_struct_sizes() {
// test expectations and move on.
// (b) You made a structure larger. This is not necessarily a problem, but should only
// be done with care, and after checking if talos performance regresses badly.
assert_eq!(mem::size_of::<Image>(), 56, "Image size changed");
assert_eq!(mem::size_of::<ImageTemplate>(), 108, "ImageTemplate size changed");
assert_eq!(mem::size_of::<ImageKey>(), 68, "ImageKey size changed");
assert_eq!(mem::size_of::<YuvImage>(), 36, "YuvImage size changed");
assert_eq!(mem::size_of::<YuvImageTemplate>(), 56, "YuvImageTemplate size changed");
assert_eq!(mem::size_of::<YuvImageKey>(), 48, "YuvImageKey size changed");
assert_eq!(mem::size_of::<Image>(), 52, "Image size changed");
assert_eq!(mem::size_of::<ImageTemplate>(), 104, "ImageTemplate size changed");
assert_eq!(mem::size_of::<ImageKey>(), 64, "ImageKey size changed");
assert_eq!(mem::size_of::<YuvImage>(), 28, "YuvImage size changed");
assert_eq!(mem::size_of::<YuvImageTemplate>(), 48, "YuvImageTemplate size changed");
assert_eq!(mem::size_of::<YuvImageKey>(), 40, "YuvImageKey size changed");
}

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{
ColorF, ColorU, LayoutPrimitiveInfo,
ColorF, ColorU,
LineOrientation, LineStyle, PremultipliedColorF, Shadow,
};
use api::units::{Au, LayoutSizeAu, LayoutVector2D};
@ -11,6 +11,7 @@ use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState};
use gpu_cache::GpuDataRequest;
use intern;
use internal_types::LayoutPrimitiveInfo;
use prim_store::{
PrimKey, PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,
InternablePrimitive, PrimitiveSceneData, PrimitiveStore,

Просмотреть файл

@ -6,7 +6,7 @@ use api::{BorderRadius, ClipMode, ColorF};
use api::{FilterOp, ImageRendering, RepeatMode};
use api::{PremultipliedColorF, PropertyBinding, Shadow, GradientStop};
use api::{BoxShadowClipMode, LineStyle, LineOrientation};
use api::{LayoutPrimitiveInfo, PrimitiveKeyKind};
use api::PrimitiveKeyKind;
use api::units::*;
use border::{get_max_scale_for_border, build_border_instances};
use border::BorderSegmentCacheKey;
@ -52,6 +52,7 @@ use texture_cache::TEXTURE_REGION_DIMENSIONS;
use util::{ScaleOffset, MatrixHelpers, MaxRect, Recycler, TransformedRectKind};
use util::{pack_as_float, project_rect, raster_rect_to_device_pixels};
use util::{scale_factors, clamp_to_scale_factor};
use internal_types::LayoutPrimitiveInfo;
use smallvec::SmallVec;
pub mod borders;

Просмотреть файл

@ -3,13 +3,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{
ColorU, FilterOp, LayoutPrimitiveInfo, MixBlendMode,
ColorU, FilterOp, MixBlendMode,
PropertyBinding, PropertyBindingId,
};
use api::units::{Au, LayoutSize, LayoutVector2D};
use intern::ItemUid;
use display_list_flattener::IsVisible;
use intern::{Internable, InternDebug, Handle as InternHandle};
use internal_types::LayoutPrimitiveInfo;
use picture::PictureCompositeMode;
use prim_store::{
PrimKey, PrimKeyCommonData, PrimTemplate, PrimTemplateCommonData,

Просмотреть файл

@ -2,13 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use api::{ColorF, GlyphInstance, LayoutPrimitiveInfo, RasterSpace, Shadow};
use api::{ColorF, GlyphInstance, RasterSpace, Shadow};
use api::units::{DevicePixelScale, LayoutToWorldTransform, LayoutVector2D};
use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState, PictureContext};
use glyph_rasterizer::{FontInstance, FontTransform, GlyphKey, FONT_SIZE_LIMIT};
use gpu_cache::GpuCache;
use intern;
use internal_types::LayoutPrimitiveInfo;
use prim_store::{PrimitiveOpacity, PrimitiveSceneData, PrimitiveScratchBuffer};
use prim_store::{PrimitiveStore, PrimKeyCommonData, PrimTemplateCommonData};
use render_task::{RenderTaskTree};

Просмотреть файл

@ -10,7 +10,7 @@
use api::{ApiMsg, BuiltDisplayList, ClearCache, DebugCommand, DebugFlags};
#[cfg(feature = "debugger")]
use api::{BuiltDisplayListIter, SpecificDisplayItem};
use api::{BuiltDisplayListIter, DisplayItem};
use api::{DocumentId, DocumentLayer, ExternalScrollId, FrameMsg, HitTestFlags, HitTestResult};
use api::{IdNamespace, MemoryReport, PipelineId, RenderNotifier, SceneMsg, ScrollClamping};
use api::{ScrollLocation, ScrollNodeState, TransactionMsg, ResourceUpdate, BlobImageKey};
@ -1525,7 +1525,7 @@ impl RenderBackend {
};
match *item.item() {
display_item @ SpecificDisplayItem::PushStackingContext(..) => {
display_item @ DisplayItem::PushStackingContext(..) => {
let mut subtraversal = item.sub_iter();
let mut child_node =
debug_server::TreeNode::new(&display_item.debug_name().to_string());
@ -1533,7 +1533,7 @@ impl RenderBackend {
node.add_child(child_node);
Some(subtraversal)
}
SpecificDisplayItem::PopStackingContext => {
DisplayItem::PopStackingContext => {
return;
}
display_item => {
@ -1774,7 +1774,7 @@ impl RenderBackend {
let data_stores = CaptureConfig::deserialize::<DataStores, _>(root, &data_stores_name)
.expect(&format!("Unable to open {}.ron", data_stores_name));
let mut doc = Document {
let doc = Document {
id: id,
scene: scene.clone(),
removed_pipelines: Vec::new(),

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use euclid::{SideOffsets2D, TypedRect};
use euclid::SideOffsets2D;
use std::ops::Not;
// local imports
use font;
@ -15,10 +15,13 @@ use units::*;
// Taken from nsCSSRendering.cpp in Gecko.
pub const MAX_BLUR_RADIUS: f32 = 300.;
// NOTE: some of these structs have an "IMPLICIT" comment.
// This indicates that the BuiltDisplayList will have serialized
// a list of values nearby that this item consumes. The traversal
// iterator should handle finding these.
// ******************************************************************
// * NOTE: some of these structs have an "IMPLICIT" comment. *
// * This indicates that the BuiltDisplayList will have serialized *
// * a list of values nearby that this item consumes. The traversal *
// * iterator should handle finding these. DebugDisplayItem should *
// * make them explicit. *
// ******************************************************************
/// A tag that can be used to identify items during hit testing. If the tag
/// is missing then the item doesn't take part in hit testing at all. This
@ -29,54 +32,39 @@ pub const MAX_BLUR_RADIUS: f32 = 300.;
/// events.
pub type ItemTag = (u64, u16);
/// The DI is generic over the specifics, while allows to use
/// the "complete" version of it for convenient serialization.
/// A grouping of fields a lot of display items need, just to avoid
/// repeating these over and over in this file.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct GenericDisplayItem<T> {
pub item: T,
pub layout: LayoutPrimitiveInfo,
pub space_and_clip: SpaceAndClipInfo,
}
pub type DisplayItem = GenericDisplayItem<SpecificDisplayItem>;
/// A modified version of DI where every field is borrowed instead of owned.
/// It allows us to reduce copies during serialization.
#[derive(Serialize)]
pub struct SerializedDisplayItem<'a> {
pub item: &'a SpecificDisplayItem,
pub layout: &'a LayoutPrimitiveInfo,
pub space_and_clip: &'a SpaceAndClipInfo,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct PrimitiveInfo<T> {
pub rect: TypedRect<f32, T>,
pub clip_rect: TypedRect<f32, T>,
pub struct CommonItemProperties {
/// Bounds of the display item to clip to. Many items are logically
/// infinite, and rely on this clip_rect to define their bounds
/// (solid colors, background-images, gradients, etc).
pub clip_rect: LayoutRect,
/// Additional clips
pub clip_id: ClipId,
/// The coordinate-space the item is in (yes, it can be really granular)
pub spatial_id: SpatialId,
/// Opaque bits for our clients to use for hit-testing. This is the most
/// dubious "common" field, but because it's an Option, it usually only
/// wastes a single byte (for None).
pub hit_info: Option<ItemTag>,
/// The CSS backface-visibility property (yes, it can be really granular)
pub is_backface_visible: bool,
pub tag: Option<ItemTag>,
}
impl LayoutPrimitiveInfo {
pub fn new(rect: TypedRect<f32, LayoutPixel>) -> Self {
Self::with_clip_rect(rect, rect)
}
pub fn with_clip_rect(
rect: TypedRect<f32, LayoutPixel>,
clip_rect: TypedRect<f32, LayoutPixel>,
) -> Self {
PrimitiveInfo {
rect,
impl CommonItemProperties {
/// Convenience for tests.
pub fn new(clip_rect: LayoutRect, space_and_clip: SpaceAndClipInfo) -> Self {
Self {
clip_rect,
spatial_id: space_and_clip.spatial_id,
clip_id: space_and_clip.clip_id,
hit_info: None,
is_backface_visible: true,
tag: None,
}
}
}
pub type LayoutPrimitiveInfo = PrimitiveInfo<LayoutPixel>;
/// Per-primitive information about the nodes in the clip tree and
/// the spatial tree that the primitive belongs to.
///
@ -102,71 +90,88 @@ impl SpaceAndClipInfo {
#[repr(u8)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub enum SpecificDisplayItem {
Clip(ClipDisplayItem),
ScrollFrame(ScrollFrameDisplayItem),
StickyFrame(StickyFrameDisplayItem),
pub enum DisplayItem {
// These are the "real content" display items
Rectangle(RectangleDisplayItem),
ClearRectangle,
Line(LineDisplayItem),
ClearRectangle(ClearRectangleDisplayItem),
HitTest(HitTestDisplayItem),
Text(TextDisplayItem),
Image(ImageDisplayItem),
YuvImage(YuvImageDisplayItem),
Line(LineDisplayItem),
Border(BorderDisplayItem),
BoxShadow(BoxShadowDisplayItem),
PushShadow(PushShadowDisplayItem),
Gradient(GradientDisplayItem),
RadialGradient(RadialGradientDisplayItem),
Image(ImageDisplayItem),
YuvImage(YuvImageDisplayItem),
// Clips
Clip(ClipDisplayItem),
ClipChain(ClipChainItem),
// Spaces and Frames that content can be scoped under.
ScrollFrame(ScrollFrameDisplayItem),
StickyFrame(StickyFrameDisplayItem),
Iframe(IframeDisplayItem),
PushReferenceFrame(ReferenceFrameDisplayListItem),
PopReferenceFrame,
PushStackingContext(PushStackingContextDisplayItem),
PopStackingContext,
// These marker items indicate an array of data follows, to be used for the
// next non-marker item.
SetGradientStops,
PushShadow(Shadow),
PopAllShadows,
SetFilterOps,
SetFilterData,
// These marker items terminate a scope introduced by a previous item.
PopReferenceFrame,
PopStackingContext,
PopAllShadows,
}
/// This is a "complete" version of the DI specifics,
/// containing the auxiliary data within the corresponding
/// enumeration variants, to be used for debug serialization.
/// This is a "complete" version of the DisplayItem, with all implicit trailing
/// arrays included, for debug serialization (captures).
#[cfg(any(feature = "serialize", feature = "deserialize"))]
#[cfg_attr(feature = "serialize", derive(Serialize))]
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
pub enum CompletelySpecificDisplayItem {
Clip(ClipDisplayItem, Vec<ComplexClipRegion>),
ClipChain(ClipChainItem, Vec<ClipId>),
ScrollFrame(ScrollFrameDisplayItem, Vec<ComplexClipRegion>),
StickyFrame(StickyFrameDisplayItem),
pub enum DebugDisplayItem {
Rectangle(RectangleDisplayItem),
ClearRectangle,
Line(LineDisplayItem),
ClearRectangle(ClearRectangleDisplayItem),
HitTest(HitTestDisplayItem),
Text(TextDisplayItem, Vec<font::GlyphInstance>),
Image(ImageDisplayItem),
YuvImage(YuvImageDisplayItem),
Line(LineDisplayItem),
Border(BorderDisplayItem),
BoxShadow(BoxShadowDisplayItem),
PushShadow(PushShadowDisplayItem),
Gradient(GradientDisplayItem),
RadialGradient(RadialGradientDisplayItem),
Image(ImageDisplayItem),
YuvImage(YuvImageDisplayItem),
Clip(ClipDisplayItem, Vec<ComplexClipRegion>),
ClipChain(ClipChainItem, Vec<ClipId>),
ScrollFrame(ScrollFrameDisplayItem, Vec<ComplexClipRegion>),
StickyFrame(StickyFrameDisplayItem),
Iframe(IframeDisplayItem),
PushReferenceFrame(ReferenceFrameDisplayListItem),
PopReferenceFrame,
PushStackingContext(PushStackingContextDisplayItem),
PopStackingContext,
SetGradientStops(Vec<GradientStop>),
PushShadow(Shadow),
PopAllShadows,
SetFilterOps(Vec<FilterOp>),
SetFilterData(FilterData),
PopReferenceFrame,
PopStackingContext,
PopAllShadows,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ClipDisplayItem {
pub id: ClipId,
pub parent_space_and_clip: SpaceAndClipInfo,
pub clip_rect: LayoutRect,
pub image_mask: Option<ImageMask>,
}
} // IMPLICIT: complex_clips: Vec<ComplexClipRegion>
/// The minimum and maximum allowable offset for a sticky frame in a single dimension.
#[repr(C)]
@ -192,6 +197,8 @@ impl StickyOffsetBounds {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct StickyFrameDisplayItem {
pub id: SpatialId,
pub parent_spatial_id: SpatialId,
pub bounds: LayoutRect,
/// The margins that should be maintained between the edge of the parent viewport and this
/// sticky frame. A margin of None indicates that the sticky frame should not stick at all
@ -226,8 +233,15 @@ pub enum ScrollSensitivity {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ScrollFrameDisplayItem {
/// The id of the clip this scroll frame creates
pub clip_id: ClipId,
/// The id of the space this scroll frame creates
pub scroll_frame_id: SpatialId,
/// The size of the contents this contains (so the backend knows how far it can scroll).
// FIXME: this can *probably* just be a size? Origin seems to just get thrown out.
pub content_rect: LayoutRect,
pub clip_rect: LayoutRect,
pub parent_space_and_clip: SpaceAndClipInfo,
pub external_id: Option<ExternalScrollId>,
pub image_mask: Option<ImageMask>,
pub scroll_sensitivity: ScrollSensitivity,
@ -239,14 +253,44 @@ pub struct ScrollFrameDisplayItem {
pub external_scroll_offset: LayoutVector2D,
}
/// A solid color to draw (may not actually be a rectangle due to complex clips)
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct RectangleDisplayItem {
pub common: CommonItemProperties,
pub color: ColorF,
}
/// Clears all colors from the area, making it possible to cut holes in the window.
/// (useful for things like the macos frosted-glass effect).
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ClearRectangleDisplayItem {
pub common: CommonItemProperties,
}
/// A minimal hit-testable item for the parent browser's convenience, and is
/// slimmer than a RectangleDisplayItem (no color). The existence of this as a
/// distinct item also makes it easier to inspect/debug display items.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct HitTestDisplayItem {
pub common: CommonItemProperties,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct LineDisplayItem {
pub orientation: LineOrientation, // toggles whether above values are interpreted as x/y values
pub common: CommonItemProperties,
/// We need a separate rect from common.clip_rect to encode cute
/// tricks that firefox does to make a series of text-decorations seamlessly
/// line up -- snapping the decorations to a multiple of their period, and
/// then clipping them to their "proper" area. This rect is that "logical"
/// snapped area that may be clipped to the right size by the clip_rect.
pub area: LayoutRect,
/// Whether the rect is interpretted as vertical or horizontal
pub orientation: LineOrientation,
/// This could potentially be implied from area, but we currently prefer
/// that this is the responsibility of the layout engine. Value irrelevant
/// for non-wavy lines.
// FIXME: this was done before we could use tagged unions in enums, but now
// it should just be part of LineStyle::Wavy.
pub wavy_line_thickness: f32,
pub color: ColorF,
pub style: LineStyle,
@ -270,6 +314,15 @@ pub enum LineStyle {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct TextDisplayItem {
pub common: CommonItemProperties,
/// The area all the glyphs should be found in. Strictly speaking this isn't
/// necessarily needed, but layout engines should already "know" this, and we
/// use it cull and size things quickly before glyph layout is done. Currently
/// the glyphs *can* be outside these bounds, but that should imply they
/// can be cut off.
// FIXME: these are currently sometimes ignored to keep some old wrench tests
// working, but we should really just fix the tests!
pub bounds: LayoutRect,
pub font_key: font::FontInstanceKey,
pub color: ColorF,
pub glyph_options: Option<font::GlyphOptions>,
@ -395,6 +448,8 @@ pub enum BorderDetails {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BorderDisplayItem {
pub common: CommonItemProperties,
pub bounds: LayoutRect,
pub widths: LayoutSideOffsets,
pub details: BorderDetails,
}
@ -452,6 +507,7 @@ pub enum BoxShadowClipMode {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct BoxShadowDisplayItem {
pub common: CommonItemProperties,
pub box_bounds: LayoutRect,
pub offset: LayoutVector2D,
pub color: ColorF,
@ -461,6 +517,12 @@ pub struct BoxShadowDisplayItem {
pub clip_mode: BoxShadowClipMode,
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct PushShadowDisplayItem {
pub space_and_clip: SpaceAndClipInfo,
pub shadow: Shadow,
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct Shadow {
@ -484,11 +546,20 @@ pub struct Gradient {
pub extend_mode: ExtendMode,
} // IMPLICIT: stops: Vec<GradientStop>
/// The area
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct GradientDisplayItem {
pub gradient: Gradient,
/// NOTE: common.clip_rect is the area the gradient covers
pub common: CommonItemProperties,
/// The area to tile the gradient over (first tile starts at origin of this rect)
// FIXME: this should ideally just be `tile_origin` here, with the clip_rect
// defining the bounds of the item. Needs non-trivial backend changes.
pub bounds: LayoutRect,
/// How big a tile of the of the gradient should be (common case: bounds.size)
pub tile_size: LayoutSize,
/// The space between tiles of the gradient (common case: 0)
pub tile_spacing: LayoutSize,
pub gradient: Gradient,
}
#[repr(C)]
@ -507,14 +578,20 @@ pub struct RadialGradient {
pub extend_mode: ExtendMode,
} // IMPLICIT stops: Vec<GradientStop>
/// Just an abstraction for bundling up a bunch of clips into a "super clip".
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ClipChainItem {
pub id: ClipChainId,
pub parent: Option<ClipChainId>,
} // IMPLICIT stops: Vec<ClipId>
} // IMPLICIT clip_ids: Vec<ClipId>
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct RadialGradientDisplayItem {
pub common: CommonItemProperties,
/// The area to tile the gradient over (first tile starts at origin of this rect)
// FIXME: this should ideally just be `tile_origin` here, with the clip_rect
// defining the bounds of the item. Needs non-trivial backend changes.
pub bounds: LayoutRect,
pub gradient: RadialGradient,
pub tile_size: LayoutSize,
pub tile_spacing: LayoutSize,
@ -522,6 +599,8 @@ pub struct RadialGradientDisplayItem {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ReferenceFrameDisplayListItem {
pub origin: LayoutPoint,
pub parent_spatial_id: SpatialId,
pub reference_frame: ReferenceFrame,
}
@ -545,6 +624,9 @@ pub struct ReferenceFrame {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct PushStackingContextDisplayItem {
pub origin: LayoutPoint,
pub spatial_id: SpatialId,
pub is_backface_visible: bool,
pub stacking_context: StackingContext,
}
@ -754,17 +836,30 @@ impl FilterData {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct IframeDisplayItem {
pub bounds: LayoutRect,
pub clip_rect: LayoutRect,
pub space_and_clip: SpaceAndClipInfo,
pub pipeline_id: PipelineId,
pub ignore_missing_pipeline: bool,
}
/// This describes an image or, more generally, a background-image and its tiling.
/// (A background-image repeats in a grid to fill the specified area).
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct ImageDisplayItem {
pub image_key: ImageKey,
pub common: CommonItemProperties,
/// The area to tile the image over (first tile starts at origin of this rect)
// FIXME: this should ideally just be `tile_origin` here, with the clip_rect
// defining the bounds of the item. Needs non-trivial backend changes.
pub bounds: LayoutRect,
/// How large to make a single tile of the image (common case: bounds.size)
pub stretch_size: LayoutSize,
/// The space between tiles (common case: 0)
pub tile_spacing: LayoutSize,
pub image_key: ImageKey,
pub image_rendering: ImageRendering,
pub alpha_type: AlphaType,
/// A hack used by gecko to color a simple bitmap font used for tofu glyphs
pub color: ColorF,
}
@ -784,6 +879,8 @@ pub enum AlphaType {
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
pub struct YuvImageDisplayItem {
pub common: CommonItemProperties,
pub bounds: LayoutRect,
pub yuv_data: YuvData,
pub color_depth: ColorDepth,
pub color_space: YuvColorSpace,
@ -1061,33 +1158,34 @@ impl ExternalScrollId {
}
}
impl SpecificDisplayItem {
impl DisplayItem {
pub fn debug_name(&self) -> &'static str {
match *self {
SpecificDisplayItem::Border(..) => "border",
SpecificDisplayItem::BoxShadow(..) => "box_shadow",
SpecificDisplayItem::ClearRectangle => "clear_rectangle",
SpecificDisplayItem::Clip(..) => "clip",
SpecificDisplayItem::ClipChain(..) => "clip_chain",
SpecificDisplayItem::Gradient(..) => "gradient",
SpecificDisplayItem::Iframe(..) => "iframe",
SpecificDisplayItem::Image(..) => "image",
SpecificDisplayItem::Line(..) => "line",
SpecificDisplayItem::PopAllShadows => "pop_all_shadows",
SpecificDisplayItem::PopReferenceFrame => "pop_reference_frame",
SpecificDisplayItem::PopStackingContext => "pop_stacking_context",
SpecificDisplayItem::PushShadow(..) => "push_shadow",
SpecificDisplayItem::PushReferenceFrame(..) => "push_reference_frame",
SpecificDisplayItem::PushStackingContext(..) => "push_stacking_context",
SpecificDisplayItem::SetFilterOps => "set_filter_ops",
SpecificDisplayItem::SetFilterData => "set_filter_data",
SpecificDisplayItem::RadialGradient(..) => "radial_gradient",
SpecificDisplayItem::Rectangle(..) => "rectangle",
SpecificDisplayItem::ScrollFrame(..) => "scroll_frame",
SpecificDisplayItem::SetGradientStops => "set_gradient_stops",
SpecificDisplayItem::StickyFrame(..) => "sticky_frame",
SpecificDisplayItem::Text(..) => "text",
SpecificDisplayItem::YuvImage(..) => "yuv_image",
DisplayItem::Border(..) => "border",
DisplayItem::BoxShadow(..) => "box_shadow",
DisplayItem::ClearRectangle(..) => "clear_rectangle",
DisplayItem::HitTest(..) => "hit_test",
DisplayItem::Clip(..) => "clip",
DisplayItem::ClipChain(..) => "clip_chain",
DisplayItem::Gradient(..) => "gradient",
DisplayItem::Iframe(..) => "iframe",
DisplayItem::Image(..) => "image",
DisplayItem::Line(..) => "line",
DisplayItem::PopAllShadows => "pop_all_shadows",
DisplayItem::PopReferenceFrame => "pop_reference_frame",
DisplayItem::PopStackingContext => "pop_stacking_context",
DisplayItem::PushShadow(..) => "push_shadow",
DisplayItem::PushReferenceFrame(..) => "push_reference_frame",
DisplayItem::PushStackingContext(..) => "push_stacking_context",
DisplayItem::SetFilterOps => "set_filter_ops",
DisplayItem::SetFilterData => "set_filter_data",
DisplayItem::RadialGradient(..) => "radial_gradient",
DisplayItem::Rectangle(..) => "rectangle",
DisplayItem::ScrollFrame(..) => "scroll_frame",
DisplayItem::SetGradientStops => "set_gradient_stops",
DisplayItem::StickyFrame(..) => "sticky_frame",
DisplayItem::Text(..) => "text",
DisplayItem::YuvImage(..) => "yuv_image",
}
}
}

Просмотреть файл

@ -121,6 +121,7 @@ pub struct BuiltDisplayListIter<'a> {
}
/// Internal info used for more detailed analysis of serialized display lists
#[allow(dead_code)]
struct DebugStats {
/// Last address in the buffer we pointed to, for computing serialized sizes
last_addr: usize,
@ -242,12 +243,7 @@ impl<'a> BuiltDisplayListIter<'a> {
BuiltDisplayListIter {
list,
data,
cur_item: di::DisplayItem {
// Dummy data, will be overwritten by `next`
item: di::SpecificDisplayItem::PopStackingContext,
layout: di::LayoutPrimitiveInfo::new(LayoutRect::zero()),
space_and_clip: di::SpaceAndClipInfo::root_scroll(PipelineId::dummy())
},
cur_item: di::DisplayItem::PopStackingContext,
cur_stops: ItemRange::default(),
cur_glyphs: ItemRange::default(),
cur_filters: ItemRange::default(),
@ -267,7 +263,7 @@ impl<'a> BuiltDisplayListIter<'a> {
}
pub fn next<'b>(&'b mut self) -> Option<DisplayItemRef<'a, 'b>> {
use SpecificDisplayItem::*;
use DisplayItem::*;
match self.peeking {
Peek::IsPeeking => {
@ -287,20 +283,17 @@ impl<'a> BuiltDisplayListIter<'a> {
loop {
self.next_raw()?;
if let SetGradientStops = self.cur_item.item {
// SetGradientStops is a dummy item that most consumers should ignore
continue;
match self.cur_item {
SetGradientStops |
SetFilterOps |
SetFilterData => {
// These are marker items for populating other display items, don't yield them.
continue;
}
_ => {
break;
}
}
if let SetFilterOps = self.cur_item.item {
// SetFilterOps is a dummy item that most consumers should ignore
continue;
}
if let SetFilterData = self.cur_item.item {
// SetFilterData is a dummy item that most consumers should ignore
continue;
}
break;
}
Some(self.as_ref())
@ -310,7 +303,7 @@ impl<'a> BuiltDisplayListIter<'a> {
/// and may leave irrelevant ranges live (so a Clip may have GradientStops if
/// for some reason you ask).
pub fn next_raw<'b>(&'b mut self) -> Option<DisplayItemRef<'a, 'b>> {
use SpecificDisplayItem::*;
use DisplayItem::*;
if self.data.is_empty() {
return None;
@ -324,7 +317,7 @@ impl<'a> BuiltDisplayListIter<'a> {
self.log_item_stats();
match self.cur_item.item {
match self.cur_item {
SetGradientStops => {
self.cur_stops = skip_slice::<di::GradientStop>(self.list, &mut self.data).0;
let temp = self.cur_stops;
@ -359,7 +352,7 @@ impl<'a> BuiltDisplayListIter<'a> {
Clip(_) | ScrollFrame(_) => {
self.cur_complex_clip = self.skip_slice::<di::ComplexClipRegion>();
let name = if let Clip(_) = self.cur_item.item {
let name = if let Clip(_) = self.cur_item {
"clip.complex_clips"
} else {
"scroll_frame.complex_clips"
@ -390,9 +383,9 @@ impl<'a> BuiltDisplayListIter<'a> {
let mut depth = 0;
while let Some(item) = self.next() {
match *item.item() {
di::SpecificDisplayItem::PushStackingContext(..) => depth += 1,
di::SpecificDisplayItem::PopStackingContext if depth == 0 => return,
di::SpecificDisplayItem::PopStackingContext => depth -= 1,
di::DisplayItem::PushStackingContext(..) => depth += 1,
di::DisplayItem::PopStackingContext if depth == 0 => return,
di::DisplayItem::PopStackingContext => depth -= 1,
_ => {}
}
debug_assert!(depth >= 0);
@ -401,7 +394,7 @@ impl<'a> BuiltDisplayListIter<'a> {
pub fn current_stacking_context_empty(&mut self) -> bool {
match self.peek() {
Some(item) => *item.item() == di::SpecificDisplayItem::PopStackingContext,
Some(item) => *item.item() == di::DisplayItem::PopStackingContext,
None => true,
}
}
@ -439,7 +432,7 @@ impl<'a> BuiltDisplayListIter<'a> {
fn log_item_stats(&mut self) {
let num_bytes = self.debug_num_bytes();
let item_name = self.cur_item.item.debug_name();
let item_name = self.cur_item.debug_name();
let entry = self.debug_stats.stats.entry(item_name).or_default();
entry.total_count += 1;
@ -480,36 +473,10 @@ impl<'a> BuiltDisplayListIter<'a> {
// Some of these might just become ItemRanges
impl<'a, 'b> DisplayItemRef<'a, 'b> {
pub fn display_item(&self) -> &di::DisplayItem {
pub fn item(&self) -> &di::DisplayItem {
&self.iter.cur_item
}
pub fn rect(&self) -> LayoutRect {
self.iter.cur_item.layout.rect
}
pub fn get_layout_primitive_info(&self, offset: &LayoutVector2D) -> di::LayoutPrimitiveInfo {
let layout = self.iter.cur_item.layout;
di::LayoutPrimitiveInfo {
rect: layout.rect.translate(offset),
clip_rect: layout.clip_rect.translate(offset),
is_backface_visible: layout.is_backface_visible,
tag: layout.tag,
}
}
pub fn clip_rect(&self) -> &LayoutRect {
&self.iter.cur_item.layout.clip_rect
}
pub fn space_and_clip_info(&self) -> &di::SpaceAndClipInfo {
&self.iter.cur_item.space_and_clip
}
pub fn item(&self) -> &di::SpecificDisplayItem {
&self.iter.cur_item.item
}
pub fn complex_clip(&self) -> (ItemRange<di::ComplexClipRegion>, usize) {
self.iter.cur_complex_clip
}
@ -538,10 +505,6 @@ impl<'a, 'b> DisplayItemRef<'a, 'b> {
self.iter.display_list()
}
pub fn is_backface_visible(&self) -> bool {
self.iter.cur_item.layout.is_backface_visible
}
// Creates a new iterator where this element's iterator is, to hack around borrowck.
pub fn sub_iter(&self) -> BuiltDisplayListIter<'a> {
BuiltDisplayListIter::new_with_list_and_data(self.iter.list, self.iter.data)
@ -590,75 +553,72 @@ impl<'a, T: for<'de> Deserialize<'de>> ::std::iter::ExactSizeIterator for AuxIte
#[cfg(feature = "serialize")]
impl Serialize for BuiltDisplayList {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
use display_item::CompletelySpecificDisplayItem::*;
use display_item::GenericDisplayItem;
use display_item::DisplayItem as Real;
use display_item::DebugDisplayItem as Debug;
let mut seq = serializer.serialize_seq(None)?;
let mut traversal = self.iter();
while let Some(item) = traversal.next_raw() {
let display_item = item.display_item();
let serial_di = GenericDisplayItem {
item: match display_item.item {
di::SpecificDisplayItem::Clip(v) => Clip(
v,
item.iter.list.get(item.iter.cur_complex_clip.0).collect()
),
di::SpecificDisplayItem::ClipChain(v) => ClipChain(
v,
item.iter.list.get(item.iter.cur_clip_chain_items).collect(),
),
di::SpecificDisplayItem::ScrollFrame(v) => ScrollFrame(
v,
item.iter.list.get(item.iter.cur_complex_clip.0).collect()
),
di::SpecificDisplayItem::StickyFrame(v) => StickyFrame(v),
di::SpecificDisplayItem::Rectangle(v) => Rectangle(v),
di::SpecificDisplayItem::ClearRectangle => ClearRectangle,
di::SpecificDisplayItem::Line(v) => Line(v),
di::SpecificDisplayItem::Text(v) => Text(
v,
item.iter.list.get(item.iter.cur_glyphs).collect()
),
di::SpecificDisplayItem::Image(v) => Image(v),
di::SpecificDisplayItem::YuvImage(v) => YuvImage(v),
di::SpecificDisplayItem::Border(v) => Border(v),
di::SpecificDisplayItem::BoxShadow(v) => BoxShadow(v),
di::SpecificDisplayItem::Gradient(v) => Gradient(v),
di::SpecificDisplayItem::RadialGradient(v) => RadialGradient(v),
di::SpecificDisplayItem::Iframe(v) => Iframe(v),
di::SpecificDisplayItem::PushReferenceFrame(v) => PushReferenceFrame(v),
di::SpecificDisplayItem::PopReferenceFrame => PopReferenceFrame,
di::SpecificDisplayItem::PushStackingContext(v) => PushStackingContext(v),
di::SpecificDisplayItem::PopStackingContext => PopStackingContext,
di::SpecificDisplayItem::SetFilterOps => SetFilterOps(
item.iter.list.get(item.iter.cur_filters).collect()
),
di::SpecificDisplayItem::SetFilterData => {
debug_assert!(!item.iter.cur_filter_data.is_empty());
let temp_filter_data = &item.iter.cur_filter_data[item.iter.cur_filter_data.len()-1];
let serial_di = match *item.item() {
Real::Clip(v) => Debug::Clip(
v,
item.iter.list.get(item.iter.cur_complex_clip.0).collect()
),
Real::ClipChain(v) => Debug::ClipChain(
v,
item.iter.list.get(item.iter.cur_clip_chain_items).collect(),
),
Real::ScrollFrame(v) => Debug::ScrollFrame(
v,
item.iter.list.get(item.iter.cur_complex_clip.0).collect()
),
Real::Text(v) => Debug::Text(
v,
item.iter.list.get(item.iter.cur_glyphs).collect()
),
Real::SetFilterOps => Debug::SetFilterOps(
item.iter.list.get(item.iter.cur_filters).collect()
),
Real::SetFilterData => {
debug_assert!(!item.iter.cur_filter_data.is_empty());
let temp_filter_data = &item.iter.cur_filter_data[item.iter.cur_filter_data.len()-1];
let func_types: Vec<di::ComponentTransferFuncType> =
item.iter.list.get(temp_filter_data.func_types).collect();
debug_assert!(func_types.len() == 4);
SetFilterData(di::FilterData {
func_r_type: func_types[0],
r_values: item.iter.list.get(temp_filter_data.r_values).collect(),
func_g_type: func_types[1],
g_values: item.iter.list.get(temp_filter_data.g_values).collect(),
func_b_type: func_types[2],
b_values: item.iter.list.get(temp_filter_data.b_values).collect(),
func_a_type: func_types[3],
a_values: item.iter.list.get(temp_filter_data.a_values).collect(),
})
},
di::SpecificDisplayItem::SetGradientStops => SetGradientStops(
item.iter.list.get(item.iter.cur_stops).collect()
),
di::SpecificDisplayItem::PushShadow(v) => PushShadow(v),
di::SpecificDisplayItem::PopAllShadows => PopAllShadows,
let func_types: Vec<di::ComponentTransferFuncType> =
item.iter.list.get(temp_filter_data.func_types).collect();
debug_assert!(func_types.len() == 4);
Debug::SetFilterData(di::FilterData {
func_r_type: func_types[0],
r_values: item.iter.list.get(temp_filter_data.r_values).collect(),
func_g_type: func_types[1],
g_values: item.iter.list.get(temp_filter_data.g_values).collect(),
func_b_type: func_types[2],
b_values: item.iter.list.get(temp_filter_data.b_values).collect(),
func_a_type: func_types[3],
a_values: item.iter.list.get(temp_filter_data.a_values).collect(),
})
},
layout: display_item.layout,
space_and_clip: display_item.space_and_clip,
Real::SetGradientStops => Debug::SetGradientStops(
item.iter.list.get(item.iter.cur_stops).collect()
),
Real::StickyFrame(v) => Debug::StickyFrame(v),
Real::Rectangle(v) => Debug::Rectangle(v),
Real::ClearRectangle(v) => Debug::ClearRectangle(v),
Real::HitTest(v) => Debug::HitTest(v),
Real::Line(v) => Debug::Line(v),
Real::Image(v) => Debug::Image(v),
Real::YuvImage(v) => Debug::YuvImage(v),
Real::Border(v) => Debug::Border(v),
Real::BoxShadow(v) => Debug::BoxShadow(v),
Real::Gradient(v) => Debug::Gradient(v),
Real::RadialGradient(v) => Debug::RadialGradient(v),
Real::Iframe(v) => Debug::Iframe(v),
Real::PushReferenceFrame(v) => Debug::PushReferenceFrame(v),
Real::PushStackingContext(v) => Debug::PushStackingContext(v),
Real::PushShadow(v) => Debug::PushShadow(v),
Real::PopReferenceFrame => Debug::PopReferenceFrame,
Real::PopStackingContext => Debug::PopStackingContext,
Real::PopAllShadows => Debug::PopAllShadows,
};
seq.serialize_element(&serial_di)?
}
@ -676,91 +636,86 @@ impl<'de> Deserialize<'de> for BuiltDisplayList {
where
D: Deserializer<'de>,
{
use display_item::CompletelySpecificDisplayItem::*;
use display_item::{CompletelySpecificDisplayItem, GenericDisplayItem};
use display_item::DisplayItem as Real;
use display_item::DebugDisplayItem as Debug;
let list = Vec::<GenericDisplayItem<CompletelySpecificDisplayItem>>
::deserialize(deserializer)?;
let list = Vec::<Debug>::deserialize(deserializer)?;
let mut data = Vec::new();
let mut temp = Vec::new();
let mut total_clip_nodes = FIRST_CLIP_NODE_INDEX;
let mut total_spatial_nodes = FIRST_SPATIAL_NODE_INDEX;
for complete in list {
let item = di::DisplayItem {
item: match complete.item {
Clip(specific_item, complex_clips) => {
total_clip_nodes += 1;
DisplayListBuilder::push_iter_impl(&mut temp, complex_clips);
di::SpecificDisplayItem::Clip(specific_item)
},
ClipChain(specific_item, clip_chain_ids) => {
DisplayListBuilder::push_iter_impl(&mut temp, clip_chain_ids);
di::SpecificDisplayItem::ClipChain(specific_item)
}
ScrollFrame(specific_item, complex_clips) => {
total_spatial_nodes += 1;
total_clip_nodes += 1;
DisplayListBuilder::push_iter_impl(&mut temp, complex_clips);
di::SpecificDisplayItem::ScrollFrame(specific_item)
}
StickyFrame(specific_item) => {
total_spatial_nodes += 1;
di::SpecificDisplayItem::StickyFrame(specific_item)
}
Rectangle(specific_item) => di::SpecificDisplayItem::Rectangle(specific_item),
ClearRectangle => di::SpecificDisplayItem::ClearRectangle,
Line(specific_item) => di::SpecificDisplayItem::Line(specific_item),
Text(specific_item, glyphs) => {
DisplayListBuilder::push_iter_impl(&mut temp, glyphs);
di::SpecificDisplayItem::Text(specific_item)
},
Image(specific_item) => di::SpecificDisplayItem::Image(specific_item),
YuvImage(specific_item) => di::SpecificDisplayItem::YuvImage(specific_item),
Border(specific_item) => di::SpecificDisplayItem::Border(specific_item),
BoxShadow(specific_item) => di::SpecificDisplayItem::BoxShadow(specific_item),
Gradient(specific_item) => di::SpecificDisplayItem::Gradient(specific_item),
RadialGradient(specific_item) =>
di::SpecificDisplayItem::RadialGradient(specific_item),
Iframe(specific_item) => {
total_clip_nodes += 1;
di::SpecificDisplayItem::Iframe(specific_item)
}
PushReferenceFrame(v) => {
total_spatial_nodes += 1;
di::SpecificDisplayItem::PushReferenceFrame(v)
}
PopReferenceFrame => di::SpecificDisplayItem::PopReferenceFrame,
PushStackingContext(specific_item) => {
di::SpecificDisplayItem::PushStackingContext(specific_item)
},
SetFilterOps(filters) => {
DisplayListBuilder::push_iter_impl(&mut temp, filters);
di::SpecificDisplayItem::SetFilterOps
},
SetFilterData(filter_data) => {
let func_types: Vec<di::ComponentTransferFuncType> =
[filter_data.func_r_type,
filter_data.func_g_type,
filter_data.func_b_type,
filter_data.func_a_type].to_vec();
DisplayListBuilder::push_iter_impl(&mut temp, func_types);
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.r_values);
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.g_values);
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.b_values);
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.a_values);
di::SpecificDisplayItem::SetFilterData
},
PopStackingContext => di::SpecificDisplayItem::PopStackingContext,
SetGradientStops(stops) => {
DisplayListBuilder::push_iter_impl(&mut temp, stops);
di::SpecificDisplayItem::SetGradientStops
},
PushShadow(specific_item) => di::SpecificDisplayItem::PushShadow(specific_item),
PopAllShadows => di::SpecificDisplayItem::PopAllShadows,
let item = match complete {
Debug::Clip(v, complex_clips) => {
total_clip_nodes += 1;
DisplayListBuilder::push_iter_impl(&mut temp, complex_clips);
Real::Clip(v)
},
layout: complete.layout,
space_and_clip: complete.space_and_clip,
Debug::ClipChain(v, clip_chain_ids) => {
DisplayListBuilder::push_iter_impl(&mut temp, clip_chain_ids);
Real::ClipChain(v)
}
Debug::ScrollFrame(v, complex_clips) => {
total_spatial_nodes += 1;
total_clip_nodes += 1;
DisplayListBuilder::push_iter_impl(&mut temp, complex_clips);
Real::ScrollFrame(v)
}
Debug::StickyFrame(v) => {
total_spatial_nodes += 1;
Real::StickyFrame(v)
}
Debug::Text(v, glyphs) => {
DisplayListBuilder::push_iter_impl(&mut temp, glyphs);
Real::Text(v)
},
Debug::Iframe(v) => {
total_clip_nodes += 1;
Real::Iframe(v)
}
Debug::PushReferenceFrame(v) => {
total_spatial_nodes += 1;
Real::PushReferenceFrame(v)
}
Debug::SetFilterOps(filters) => {
DisplayListBuilder::push_iter_impl(&mut temp, filters);
Real::SetFilterOps
},
Debug::SetFilterData(filter_data) => {
let func_types: Vec<di::ComponentTransferFuncType> =
[filter_data.func_r_type,
filter_data.func_g_type,
filter_data.func_b_type,
filter_data.func_a_type].to_vec();
DisplayListBuilder::push_iter_impl(&mut temp, func_types);
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.r_values);
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.g_values);
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.b_values);
DisplayListBuilder::push_iter_impl(&mut temp, filter_data.a_values);
Real::SetFilterData
},
Debug::SetGradientStops(stops) => {
DisplayListBuilder::push_iter_impl(&mut temp, stops);
Real::SetGradientStops
},
Debug::Rectangle(v) => Real::Rectangle(v),
Debug::ClearRectangle(v) => Real::ClearRectangle(v),
Debug::HitTest(v) => Real::HitTest(v),
Debug::Line(v) => Real::Line(v),
Debug::Image(v) => Real::Image(v),
Debug::YuvImage(v) => Real::YuvImage(v),
Debug::Border(v) => Real::Border(v),
Debug::BoxShadow(v) => Real::BoxShadow(v),
Debug::Gradient(v) => Real::Gradient(v),
Debug::RadialGradient(v) => Real::RadialGradient(v),
Debug::PushStackingContext(v) => Real::PushStackingContext(v),
Debug::PushShadow(v) => Real::PushShadow(v),
Debug::PopStackingContext => Real::PopStackingContext,
Debug::PopReferenceFrame => Real::PopReferenceFrame,
Debug::PopAllShadows => Real::PopAllShadows,
};
serialize_fast(&mut data, &item);
// the aux data is serialized after the item, hence the temporary
@ -1113,7 +1068,7 @@ impl DisplayListBuilder {
let mut iter = BuiltDisplayListIter::new(&temp);
while let Some(item) = iter.next_raw() {
if index >= range.start.unwrap_or(0) && range.end.map_or(true, |e| index < e) {
writeln!(sink, "{}{:?}", " ".repeat(indent), item.display_item()).unwrap();
writeln!(sink, "{}{:?}", " ".repeat(indent), item.item()).unwrap();
}
index += 1;
}
@ -1129,30 +1084,8 @@ impl DisplayListBuilder {
/// display items. Pushing unexpected or invalid items here may
/// result in WebRender panicking or behaving in unexpected ways.
#[inline]
pub fn push_item(
&mut self,
item: &di::SpecificDisplayItem,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
) {
serialize_fast(
&mut self.data,
di::SerializedDisplayItem {
item,
layout,
space_and_clip,
},
)
}
#[inline]
fn push_new_empty_item(&mut self, item: &di::SpecificDisplayItem) {
let pipeline_id = self.pipeline_id;
self.push_item(
item,
&di::LayoutPrimitiveInfo::new(LayoutRect::zero()),
&di::SpaceAndClipInfo::root_scroll(pipeline_id),
)
pub fn push_item(&mut self, item: &di::DisplayItem) {
serialize_fast(&mut self.data, item);
}
fn push_iter_impl<I>(data: &mut Vec<u8>, iter_source: I)
@ -1202,45 +1135,61 @@ impl DisplayListBuilder {
pub fn push_rect(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
color: ColorF,
) {
let item = di::SpecificDisplayItem::Rectangle(di::RectangleDisplayItem { color });
self.push_item(&item, layout, space_and_clip);
let item = di::DisplayItem::Rectangle(di::RectangleDisplayItem {
common: *common,
color
});
self.push_item(&item);
}
pub fn push_clear_rect(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
) {
self.push_item(&di::SpecificDisplayItem::ClearRectangle, layout, space_and_clip);
let item = di::DisplayItem::ClearRectangle(di::ClearRectangleDisplayItem {
common: *common,
});
self.push_item(&item);
}
pub fn push_hit_test(
&mut self,
common: &di::CommonItemProperties,
) {
let item = di::DisplayItem::HitTest(di::HitTestDisplayItem {
common: *common,
});
self.push_item(&item);
}
pub fn push_line(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
area: &LayoutRect,
wavy_line_thickness: f32,
orientation: di::LineOrientation,
color: &ColorF,
style: di::LineStyle,
) {
let item = di::SpecificDisplayItem::Line(di::LineDisplayItem {
let item = di::DisplayItem::Line(di::LineDisplayItem {
common: *common,
area: *area,
wavy_line_thickness,
orientation,
color: *color,
style,
});
self.push_item(&item, layout, space_and_clip);
self.push_item(&item);
}
pub fn push_image(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
bounds: LayoutRect,
stretch_size: LayoutSize,
tile_spacing: LayoutSize,
image_rendering: di::ImageRendering,
@ -1248,7 +1197,9 @@ impl DisplayListBuilder {
key: ImageKey,
color: ColorF,
) {
let item = di::SpecificDisplayItem::Image(di::ImageDisplayItem {
let item = di::DisplayItem::Image(di::ImageDisplayItem {
common: *common,
bounds,
image_key: key,
stretch_size,
tile_spacing,
@ -1257,45 +1208,49 @@ impl DisplayListBuilder {
color,
});
self.push_item(&item, layout, space_and_clip);
self.push_item(&item);
}
/// Push a yuv image. All planar data in yuv image should use the same buffer type.
pub fn push_yuv_image(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
bounds: LayoutRect,
yuv_data: di::YuvData,
color_depth: ColorDepth,
color_space: di::YuvColorSpace,
image_rendering: di::ImageRendering,
) {
let item = di::SpecificDisplayItem::YuvImage(di::YuvImageDisplayItem {
let item = di::DisplayItem::YuvImage(di::YuvImageDisplayItem {
common: *common,
bounds,
yuv_data,
color_depth,
color_space,
image_rendering,
});
self.push_item(&item, layout, space_and_clip);
self.push_item(&item);
}
pub fn push_text(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
bounds: LayoutRect,
glyphs: &[GlyphInstance],
font_key: FontInstanceKey,
color: ColorF,
glyph_options: Option<GlyphOptions>,
) {
let item = di::SpecificDisplayItem::Text(di::TextDisplayItem {
let item = di::DisplayItem::Text(di::TextDisplayItem {
common: *common,
bounds: bounds,
color,
font_key,
glyph_options,
});
for split_glyphs in glyphs.chunks(MAX_TEXT_RUN_LENGTH) {
self.push_item(&item, layout, space_and_clip);
self.push_item(&item);
self.push_iter(split_glyphs);
}
}
@ -1332,20 +1287,24 @@ impl DisplayListBuilder {
pub fn push_border(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
bounds: LayoutRect,
widths: LayoutSideOffsets,
details: di::BorderDetails,
) {
let item = di::SpecificDisplayItem::Border(di::BorderDisplayItem { details, widths });
let item = di::DisplayItem::Border(di::BorderDisplayItem {
common: *common,
bounds,
details,
widths,
});
self.push_item(&item, layout, space_and_clip);
self.push_item(&item);
}
pub fn push_box_shadow(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
box_bounds: LayoutRect,
offset: LayoutVector2D,
color: ColorF,
@ -1354,7 +1313,8 @@ impl DisplayListBuilder {
border_radius: di::BorderRadius,
clip_mode: di::BoxShadowClipMode,
) {
let item = di::SpecificDisplayItem::BoxShadow(di::BoxShadowDisplayItem {
let item = di::DisplayItem::BoxShadow(di::BoxShadowDisplayItem {
common: *common,
box_bounds,
offset,
color,
@ -1364,7 +1324,7 @@ impl DisplayListBuilder {
clip_mode,
});
self.push_item(&item, layout, space_and_clip);
self.push_item(&item);
}
/// Pushes a linear gradient to be displayed.
@ -1383,19 +1343,21 @@ impl DisplayListBuilder {
/// The gradient is only visible within the local clip.
pub fn push_gradient(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
bounds: LayoutRect,
gradient: di::Gradient,
tile_size: LayoutSize,
tile_spacing: LayoutSize,
) {
let item = di::SpecificDisplayItem::Gradient(di::GradientDisplayItem {
let item = di::DisplayItem::Gradient(di::GradientDisplayItem {
common: *common,
bounds,
gradient,
tile_size,
tile_spacing,
});
self.push_item(&item, layout, space_and_clip);
self.push_item(&item);
}
/// Pushes a radial gradient to be displayed.
@ -1403,32 +1365,36 @@ impl DisplayListBuilder {
/// See [`push_gradient`](#method.push_gradient) for explanation.
pub fn push_radial_gradient(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
common: &di::CommonItemProperties,
bounds: LayoutRect,
gradient: di::RadialGradient,
tile_size: LayoutSize,
tile_spacing: LayoutSize,
) {
let item = di::SpecificDisplayItem::RadialGradient(di::RadialGradientDisplayItem {
let item = di::DisplayItem::RadialGradient(di::RadialGradientDisplayItem {
common: *common,
bounds,
gradient,
tile_size,
tile_spacing,
});
self.push_item(&item, layout, space_and_clip);
self.push_item(&item);
}
pub fn push_reference_frame(
&mut self,
rect: &LayoutRect,
parent: di::SpatialId,
origin: LayoutPoint,
parent_spatial_id: di::SpatialId,
transform_style: di::TransformStyle,
transform: PropertyBinding<LayoutTransform>,
kind: di::ReferenceFrameKind,
) -> di::SpatialId {
let id = self.generate_spatial_index();
let item = di::SpecificDisplayItem::PushReferenceFrame(di::ReferenceFrameDisplayListItem {
let item = di::DisplayItem::PushReferenceFrame(di::ReferenceFrameDisplayListItem {
parent_spatial_id,
origin,
reference_frame: di::ReferenceFrame {
transform_style,
transform,
@ -1437,22 +1403,19 @@ impl DisplayListBuilder {
},
});
let layout = di::LayoutPrimitiveInfo::new(*rect);
self.push_item(&item, &layout, &di::SpaceAndClipInfo {
spatial_id: parent,
clip_id: di::ClipId::invalid(),
});
self.push_item(&item);
id
}
pub fn pop_reference_frame(&mut self) {
self.push_new_empty_item(&di::SpecificDisplayItem::PopReferenceFrame);
self.push_item(&di::DisplayItem::PopReferenceFrame);
}
pub fn push_stacking_context(
&mut self,
layout: &di::LayoutPrimitiveInfo,
origin: LayoutPoint,
spatial_id: di::SpatialId,
is_backface_visible: bool,
clip_id: Option<di::ClipId>,
transform_style: di::TransformStyle,
mix_blend_mode: di::MixBlendMode,
@ -1461,9 +1424,8 @@ impl DisplayListBuilder {
raster_space: di::RasterSpace,
cache_tiles: bool,
) {
if filters.len() > 0 {
self.push_new_empty_item(&di::SpecificDisplayItem::SetFilterOps);
self.push_item(&di::DisplayItem::SetFilterOps);
self.push_iter(filters);
}
@ -1471,7 +1433,7 @@ impl DisplayListBuilder {
let func_types = [
filter_data.func_r_type, filter_data.func_g_type,
filter_data.func_b_type, filter_data.func_a_type];
self.push_new_empty_item(&di::SpecificDisplayItem::SetFilterData);
self.push_item(&di::DisplayItem::SetFilterData);
self.push_iter(&func_types);
self.push_iter(&filter_data.r_values);
self.push_iter(&filter_data.g_values);
@ -1479,7 +1441,10 @@ impl DisplayListBuilder {
self.push_iter(&filter_data.a_values);
}
let item = di::SpecificDisplayItem::PushStackingContext(di::PushStackingContextDisplayItem {
let item = di::DisplayItem::PushStackingContext(di::PushStackingContextDisplayItem {
origin,
spatial_id,
is_backface_visible,
stacking_context: di::StackingContext {
transform_style,
mix_blend_mode,
@ -1489,32 +1454,32 @@ impl DisplayListBuilder {
},
});
self.push_item(&item, layout, &di::SpaceAndClipInfo {
spatial_id,
clip_id: di::ClipId::invalid(),
});
self.push_item(&item);
}
/// Helper for examples/ code.
pub fn push_simple_stacking_context(
&mut self,
layout: &di::LayoutPrimitiveInfo,
origin: LayoutPoint,
spatial_id: di::SpatialId,
is_backface_visible: bool,
) {
self.push_simple_stacking_context_with_filters(layout, spatial_id, &[], &[]);
self.push_simple_stacking_context_with_filters(origin, spatial_id, is_backface_visible, &[], &[]);
}
/// Helper for examples/ code.
pub fn push_simple_stacking_context_with_filters(
&mut self,
layout: &di::LayoutPrimitiveInfo,
origin: LayoutPoint,
spatial_id: di::SpatialId,
is_backface_visible: bool,
filters: &[di::FilterOp],
filter_datas: &[di::FilterData],
) {
self.push_stacking_context(
layout,
origin,
spatial_id,
is_backface_visible,
None,
di::TransformStyle::Flat,
di::MixBlendMode::Normal,
@ -1526,14 +1491,14 @@ impl DisplayListBuilder {
}
pub fn pop_stacking_context(&mut self) {
self.push_new_empty_item(&di::SpecificDisplayItem::PopStackingContext);
self.push_item(&di::DisplayItem::PopStackingContext);
}
pub fn push_stops(&mut self, stops: &[di::GradientStop]) {
if stops.is_empty() {
return;
}
self.push_new_empty_item(&di::SpecificDisplayItem::SetGradientStops);
self.push_item(&di::DisplayItem::SetGradientStops);
self.push_iter(stops);
}
@ -1569,7 +1534,10 @@ impl DisplayListBuilder {
{
let clip_id = self.generate_clip_index();
let scroll_frame_id = self.generate_spatial_index();
let item = di::SpecificDisplayItem::ScrollFrame(di::ScrollFrameDisplayItem {
let item = di::DisplayItem::ScrollFrame(di::ScrollFrameDisplayItem {
content_rect,
clip_rect,
parent_space_and_clip: *parent_space_and_clip,
clip_id,
scroll_frame_id,
external_id,
@ -1578,11 +1546,7 @@ impl DisplayListBuilder {
external_scroll_offset,
});
self.push_item(
&item,
&di::LayoutPrimitiveInfo::with_clip_rect(content_rect, clip_rect),
parent_space_and_clip,
);
self.push_item(&item);
self.push_iter(complex_clips);
di::SpaceAndClipInfo {
@ -1601,7 +1565,7 @@ impl DisplayListBuilder {
I::IntoIter: ExactSizeIterator + Clone,
{
let id = self.generate_clip_chain_id();
self.push_new_empty_item(&di::SpecificDisplayItem::ClipChain(di::ClipChainItem { id, parent }));
self.push_item(&di::DisplayItem::ClipChain(di::ClipChainItem { id, parent }));
self.push_iter(clips);
id
}
@ -1618,16 +1582,14 @@ impl DisplayListBuilder {
I::IntoIter: ExactSizeIterator + Clone,
{
let id = self.generate_clip_index();
let item = di::SpecificDisplayItem::Clip(di::ClipDisplayItem {
let item = di::DisplayItem::Clip(di::ClipDisplayItem {
id,
parent_space_and_clip: *parent_space_and_clip,
clip_rect,
image_mask,
});
self.push_item(
&item,
&di::LayoutPrimitiveInfo::new(clip_rect),
parent_space_and_clip,
);
self.push_item(&item);
self.push_iter(complex_clips);
id
}
@ -1642,50 +1604,52 @@ impl DisplayListBuilder {
previously_applied_offset: LayoutVector2D,
) -> di::SpatialId {
let id = self.generate_spatial_index();
let item = di::SpecificDisplayItem::StickyFrame(di::StickyFrameDisplayItem {
let item = di::DisplayItem::StickyFrame(di::StickyFrameDisplayItem {
parent_spatial_id,
id,
bounds: frame_rect,
margins,
vertical_offset_bounds,
horizontal_offset_bounds,
previously_applied_offset,
});
self.push_item(
&item,
&di::LayoutPrimitiveInfo::new(frame_rect),
&di::SpaceAndClipInfo {
spatial_id: parent_spatial_id,
clip_id: di::ClipId::invalid(),
},
);
self.push_item(&item);
id
}
pub fn push_iframe(
&mut self,
layout: &di::LayoutPrimitiveInfo,
bounds: LayoutRect,
clip_rect: LayoutRect,
space_and_clip: &di::SpaceAndClipInfo,
pipeline_id: PipelineId,
ignore_missing_pipeline: bool
) {
let item = di::SpecificDisplayItem::Iframe(di::IframeDisplayItem {
let item = di::DisplayItem::Iframe(di::IframeDisplayItem {
bounds,
clip_rect,
space_and_clip: *space_and_clip,
pipeline_id,
ignore_missing_pipeline,
});
self.push_item(&item, layout, space_and_clip);
self.push_item(&item);
}
pub fn push_shadow(
&mut self,
layout: &di::LayoutPrimitiveInfo,
space_and_clip: &di::SpaceAndClipInfo,
shadow: di::Shadow,
) {
self.push_item(&di::SpecificDisplayItem::PushShadow(shadow), layout, space_and_clip);
let item = di::DisplayItem::PushShadow(di::PushShadowDisplayItem {
space_and_clip: *space_and_clip,
shadow,
});
self.push_item(&item);
}
pub fn pop_all_shadows(&mut self) {
self.push_new_empty_item(&di::SpecificDisplayItem::PopAllShadows);
self.push_item(&di::DisplayItem::PopAllShadows);
}
pub fn finalize(self) -> (PipelineId, LayoutSize, BuiltDisplayList) {

Просмотреть файл

@ -78,6 +78,32 @@ impl<'a> RawtestHarness<'a> {
self.wrench.api.send_transaction(self.wrench.document_id, txn);
}
fn make_common_properties(&self, clip_rect: LayoutRect) -> CommonItemProperties {
let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
CommonItemProperties {
clip_rect,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible: true,
hit_info: None,
}
}
fn make_common_properties_with_clip_and_spatial(
&self,
clip_rect: LayoutRect,
clip_id: ClipId,
spatial_id: SpatialId
) -> CommonItemProperties {
CommonItemProperties {
clip_rect,
clip_id,
spatial_id,
is_backface_visible: true,
hit_info: None,
}
}
fn test_resize_image(&mut self) {
println!("\tresize image...");
// This test changes the size of an image to make it go switch back and forth
@ -98,11 +124,11 @@ impl<'a> RawtestHarness<'a> {
);
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0.0, 0.0, 64.0, 64.0));
let info = self.make_common_properties(rect(0.0, 0.0, 64.0, 64.0));
builder.push_image(
&info,
&SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id),
info.clip_rect,
size2(64.0, 64.0),
size2(64.0, 64.0),
ImageRendering::Auto,
@ -127,11 +153,11 @@ impl<'a> RawtestHarness<'a> {
);
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0.0, 0.0, 1024.0, 1024.0));
let info = self.make_common_properties(rect(0.0, 0.0, 1024.0, 1024.0));
builder.push_image(
&info,
&SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id),
info.clip_rect,
size2(1024.0, 1024.0),
size2(1024.0, 1024.0),
ImageRendering::Auto,
@ -153,11 +179,11 @@ impl<'a> RawtestHarness<'a> {
);
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0.0, 0.0, 1024.0, 1024.0));
let info = self.make_common_properties(rect(0.0, 0.0, 1024.0, 1024.0));
builder.push_image(
&info,
&SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id),
info.clip_rect,
size2(1024.0, 1024.0),
size2(1024.0, 1024.0),
ImageRendering::Auto,
@ -191,12 +217,12 @@ impl<'a> RawtestHarness<'a> {
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(448.899994, 74.0, 151.000031, 56.));
let info = self.make_common_properties(rect(448.899994, 74.0, 151.000031, 56.));
// setup some malicious image size parameters
builder.push_image(
&info,
&SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id),
info.clip_rect,
size2(151., 56.0),
size2(151.0, 56.0),
ImageRendering::Auto,
@ -254,8 +280,6 @@ impl<'a> RawtestHarness<'a> {
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0., -9600.0, 1510.000031, 111256.));
let image_size = size2(1510., 111256.);
let root_space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
@ -266,10 +290,18 @@ impl<'a> RawtestHarness<'a> {
None,
);
let info = CommonItemProperties {
clip_rect: rect(0., -9600.0, 1510.000031, 111256.),
clip_id,
spatial_id: root_space_and_clip.spatial_id,
is_backface_visible: true,
hit_info: None,
};
// setup some malicious image size parameters
builder.push_image(
&info,
&SpaceAndClipInfo { clip_id, spatial_id: root_space_and_clip.spatial_id },
info.clip_rect,
image_size * 2.,
image_size,
ImageRendering::Auto,
@ -352,8 +384,7 @@ impl<'a> RawtestHarness<'a> {
);
let layout_size = LayoutSize::new(800.0, 800.0);
let image_size = size2(800.0, 800.0);
let info = LayoutPrimitiveInfo::new(rect(0.0, 0.0, 800.0, 800.0));
let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
let info = self.make_common_properties(rect(0.0, 0.0, 800.0, 800.0));
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let mut txn = Transaction::new();
@ -374,7 +405,7 @@ impl<'a> RawtestHarness<'a> {
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
image_size,
image_size,
ImageRendering::Auto,
@ -411,7 +442,7 @@ impl<'a> RawtestHarness<'a> {
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
image_size,
image_size,
ImageRendering::Auto,
@ -443,7 +474,6 @@ impl<'a> RawtestHarness<'a> {
point2(0, window_size.height - test_size.height),
test_size,
);
let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
// This exposes a crash in tile decomposition
let mut txn = Transaction::new();
@ -459,14 +489,14 @@ impl<'a> RawtestHarness<'a> {
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0., 0.0, 1510., 1510.));
let info = self.make_common_properties(rect(0., 0.0, 1510., 1510.));
let image_size = size2(1510., 1510.);
// setup some malicious image size parameters
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
image_size,
image_size,
ImageRendering::Auto,
@ -485,14 +515,14 @@ impl<'a> RawtestHarness<'a> {
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(-10000., 0.0, 1510., 1510.));
let info = self.make_common_properties(rect(-10000., 0.0, 1510., 1510.));
let image_size = size2(1510., 1510.);
// setup some malicious image size parameters
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
image_size,
image_size,
ImageRendering::Auto,
@ -516,14 +546,14 @@ impl<'a> RawtestHarness<'a> {
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0., 0.0, 1510., 1510.));
let info = self.make_common_properties(rect(0., 0.0, 1510., 1510.));
let image_size = size2(1510., 1510.);
// setup some malicious image size parameters
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
image_size,
image_size,
ImageRendering::Auto,
@ -558,7 +588,6 @@ impl<'a> RawtestHarness<'a> {
test_size,
);
let layout_size = LayoutSize::new(400., 400.);
let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
let mut txn = Transaction::new();
{
@ -582,11 +611,11 @@ impl<'a> RawtestHarness<'a> {
// draw the blob the first time
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0.0, 60.0, 200.0, 200.0));
let info = self.make_common_properties(rect(0.0, 60.0, 200.0, 200.0));
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
size2(200.0, 200.0),
size2(0.0, 0.0),
ImageRendering::Auto,
@ -607,10 +636,10 @@ impl<'a> RawtestHarness<'a> {
// make a new display list that refers to the first image
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(1.0, 60.0, 200.0, 200.0));
let info = self.make_common_properties(rect(1.0, 60.0, 200.0, 200.0));
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
size2(200.0, 200.0),
size2(0.0, 0.0),
ImageRendering::Auto,
@ -649,7 +678,6 @@ impl<'a> RawtestHarness<'a> {
test_size,
);
let layout_size = LayoutSize::new(400., 400.);
let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
let mut txn = Transaction::new();
let (blob_img, blob_img2) = {
@ -692,12 +720,12 @@ impl<'a> RawtestHarness<'a> {
// create two blob images and draw them
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0.0, 60.0, 200.0, 200.0));
let info2 = LayoutPrimitiveInfo::new(rect(200.0, 60.0, 200.0, 200.0));
let info = self.make_common_properties(rect(0.0, 60.0, 200.0, 200.0));
let info2 = self.make_common_properties(rect(200.0, 60.0, 200.0, 200.0));
let push_images = |builder: &mut DisplayListBuilder| {
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
size2(200.0, 200.0),
size2(0.0, 0.0),
ImageRendering::Auto,
@ -707,7 +735,7 @@ impl<'a> RawtestHarness<'a> {
);
builder.push_image(
&info2,
&space_and_clip,
info2.clip_rect,
size2(200.0, 200.0),
size2(0.0, 0.0),
ImageRendering::Auto,
@ -779,7 +807,6 @@ impl<'a> RawtestHarness<'a> {
test_size,
);
let layout_size = LayoutSize::new(400., 400.);
let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
let mut txn = Transaction::new();
let blob_img = {
@ -795,11 +822,11 @@ impl<'a> RawtestHarness<'a> {
// draw the blobs the first time
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0.0, 60.0, 200.0, 200.0));
let info = self.make_common_properties(rect(0.0, 60.0, 200.0, 200.0));
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
size2(200.0, 200.0),
size2(0.0, 0.0),
ImageRendering::Auto,
@ -824,10 +851,10 @@ impl<'a> RawtestHarness<'a> {
// make a new display list that refers to the first image
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0.0, 60.0, 200.0, 200.0));
let info = self.make_common_properties(rect(0.0, 60.0, 200.0, 200.0));
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
size2(200.0, 200.0),
size2(0.0, 0.0),
ImageRendering::Auto,
@ -850,10 +877,10 @@ impl<'a> RawtestHarness<'a> {
// make a new display list that refers to the first image
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(rect(0.0, 60.0, 200.0, 200.0));
let info = self.make_common_properties(rect(0.0, 60.0, 200.0, 200.0));
builder.push_image(
&info,
&space_and_clip,
info.clip_rect,
size2(200.0, 200.0),
size2(0.0, 0.0),
ImageRendering::Auto,
@ -892,8 +919,10 @@ impl<'a> RawtestHarness<'a> {
None
);
builder.push_rect(
&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
&SpaceAndClipInfo { spatial_id, clip_id },
&self.make_common_properties_with_clip_and_spatial(
rect(100., 100., 100., 100.),
clip_id,
spatial_id),
ColorF::new(0.0, 0.0, 1.0, 1.0),
);
@ -910,12 +939,13 @@ impl<'a> RawtestHarness<'a> {
clip_id
};
builder.push_rect(
&PrimitiveInfo::new(rect(110., 110., 50., 50.)),
&space_and_clip,
&self.make_common_properties_with_clip_and_spatial(
rect(110., 110., 50., 50.),
clip_id,
spatial_id),
ColorF::new(0.0, 1.0, 0.0, 1.0),
);
builder.push_shadow(
&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
&space_and_clip,
Shadow {
offset: LayoutVector2D::new(1.0, 1.0),
@ -924,9 +954,16 @@ impl<'a> RawtestHarness<'a> {
should_inflate: true,
},
);
let info = CommonItemProperties {
clip_rect: rect(110., 110., 50., 2.),
clip_id,
spatial_id,
is_backface_visible: true,
hit_info: None,
};
builder.push_line(
&PrimitiveInfo::new(rect(110., 110., 50., 2.)),
&space_and_clip,
&info,
&info.clip_rect,
0.0, LineOrientation::Horizontal,
&ColorF::new(0.0, 0.0, 0.0, 1.0),
LineStyle::Solid,
@ -943,8 +980,10 @@ impl<'a> RawtestHarness<'a> {
None
);
builder.push_rect(
&PrimitiveInfo::new(rect(150., 150., 100., 100.)),
&SpaceAndClipInfo { spatial_id, clip_id },
&self.make_common_properties_with_clip_and_spatial(
rect(150., 150., 100., 100.),
clip_id,
spatial_id),
ColorF::new(0.0, 0.0, 1.0, 1.0),
);
builder.clear_save();
@ -975,7 +1014,6 @@ impl<'a> RawtestHarness<'a> {
test_size,
);
let layout_size = LayoutSize::new(400., 400.);
let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
let mut do_test = |shadow_is_red| {
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
@ -986,8 +1024,7 @@ impl<'a> RawtestHarness<'a> {
};
builder.push_shadow(
&PrimitiveInfo::new(rect(100., 100., 100., 100.)),
&space_and_clip,
&SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id),
Shadow {
offset: LayoutVector2D::new(1.0, 1.0),
blur_radius: 1.0,
@ -995,9 +1032,10 @@ impl<'a> RawtestHarness<'a> {
should_inflate: true,
},
);
let info = self.make_common_properties(rect(110., 110., 50., 2.));
builder.push_line(
&PrimitiveInfo::new(rect(110., 110., 50., 2.)),
&space_and_clip,
&info,
&info.clip_rect,
0.0, LineOrientation::Horizontal,
&ColorF::new(0.0, 0.0, 0.0, 1.0),
LineStyle::Solid,
@ -1039,9 +1077,10 @@ impl<'a> RawtestHarness<'a> {
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = self.make_common_properties(rect(300.0, 70.0, 150.0, 50.0));
builder.push_image(
&LayoutPrimitiveInfo::new(rect(300.0, 70.0, 150.0, 50.0)),
&SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id),
&info,
info.clip_rect,
size2(150.0, 50.0),
size2(0.0, 0.0),
ImageRendering::Auto,
@ -1108,11 +1147,10 @@ impl<'a> RawtestHarness<'a> {
let doc_id = self.wrench.api.add_document(window_size, 1);
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let info = LayoutPrimitiveInfo::new(LayoutRect::new(LayoutPoint::zero(),
let info = self.make_common_properties(LayoutRect::new(LayoutPoint::zero(),
LayoutSize::new(100.0, 100.0)));
builder.push_rect(
&info,
&SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id),
ColorF::new(0.0, 1.0, 0.0, 1.0),
);
@ -1140,20 +1178,20 @@ impl<'a> RawtestHarness<'a> {
let layout_size = LayoutSize::new(400., 400.);
let mut builder = DisplayListBuilder::new(self.wrench.root_pipeline_id, layout_size);
let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
// Add a rectangle that covers the entire scene.
let mut info = LayoutPrimitiveInfo::new(LayoutRect::new(LayoutPoint::zero(), layout_size));
info.tag = Some((0, 1));
builder.push_rect(&info, &space_and_clip, ColorF::new(1.0, 1.0, 1.0, 1.0));
let mut info = self.make_common_properties(LayoutRect::new(LayoutPoint::zero(), layout_size));
info.hit_info = Some((0, 1));
builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0));
// Add a simple 100x100 rectangle at 100,0.
let mut info = LayoutPrimitiveInfo::new(LayoutRect::new(
let mut info = self.make_common_properties(LayoutRect::new(
LayoutPoint::new(100., 0.),
LayoutSize::new(100., 100.)
));
info.tag = Some((0, 2));
builder.push_rect(&info, &space_and_clip, ColorF::new(1.0, 1.0, 1.0, 1.0));
info.hit_info = Some((0, 2));
builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0));
let space_and_clip = SpaceAndClipInfo::root_scroll(self.wrench.root_pipeline_id);
let make_rounded_complex_clip = |rect: &LayoutRect, radius: f32| -> ComplexClipRegion {
ComplexClipRegion::new(
@ -1172,13 +1210,12 @@ impl<'a> RawtestHarness<'a> {
None,
);
builder.push_rect(
&LayoutPrimitiveInfo {
tag: Some((0, 4)),
.. LayoutPrimitiveInfo::new(rect)
},
&SpaceAndClipInfo {
&CommonItemProperties {
hit_info: Some((0, 4)),
clip_rect: rect,
clip_id: temp_clip_id,
spatial_id: space_and_clip.spatial_id,
is_backface_visible: true,
},
ColorF::new(1.0, 1.0, 1.0, 1.0),
);
@ -1193,13 +1230,12 @@ impl<'a> RawtestHarness<'a> {
);
let clip_chain_id = builder.define_clip_chain(None, vec![clip_id]);
builder.push_rect(
&LayoutPrimitiveInfo {
tag: Some((0, 5)),
.. LayoutPrimitiveInfo::new(rect)
},
&SpaceAndClipInfo {
&CommonItemProperties {
hit_info: Some((0, 5)),
clip_rect: rect,
clip_id: ClipId::ClipChain(clip_chain_id),
spatial_id: space_and_clip.spatial_id,
is_backface_visible: true,
},
ColorF::new(1.0, 1.0, 1.0, 1.0),
);

Просмотреть файл

@ -20,6 +20,17 @@ use yaml_helper::{StringEnum, YamlHelper, make_perspective};
use yaml_rust::{Yaml, YamlLoader};
use PLATFORM_DEFAULT_FACE_NAME;
macro_rules! try_intersect {
($first: expr, $second: expr) => {
if let Some(rect) = ($first).intersection($second) {
rect
} else {
warn!("skipping item with non-intersecting bounds and clip_rect");
return;
};
}
}
fn rsrc_path(item: &Yaml, aux_dir: &PathBuf) -> PathBuf {
let filename = item.as_str().unwrap();
let mut file = aux_dir.clone();
@ -351,7 +362,13 @@ impl YamlFrameReader {
let content_size = self.get_root_size_from_yaml(wrench, yaml);
let mut builder = DisplayListBuilder::new(pipeline_id, content_size);
let mut info = LayoutPrimitiveInfo::new(LayoutRect::zero());
let mut info = CommonItemProperties {
clip_rect: LayoutRect::zero(),
clip_id: ClipId::invalid(),
spatial_id: SpatialId::new(0, PipelineId::dummy()),
is_backface_visible: true,
hit_info: None,
};
self.add_stacking_context_from_yaml(&mut builder, wrench, yaml, true, &mut info);
self.display_lists.push(builder.finalize());
@ -766,35 +783,55 @@ impl YamlFrameReader {
&mut self,
dl: &mut DisplayListBuilder,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let bounds_key = if item["type"].is_badvalue() {
"rect"
} else {
"bounds"
};
info.rect = self.resolve_rect(&item[bounds_key]);
info.clip_rect = try_intersect!(
self.resolve_rect(&item[bounds_key]),
&info.clip_rect
);
let color = self.resolve_colorf(&item["color"], ColorF::BLACK);
dl.push_rect(&info, &self.top_space_and_clip(), color);
dl.push_rect(&info, color);
}
fn handle_clear_rect(
&mut self,
dl: &mut DisplayListBuilder,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
info.rect = item["bounds"]
.as_rect()
.expect("clear-rect type must have bounds");
dl.push_clear_rect(&info, &self.top_space_and_clip());
info.clip_rect = try_intersect!(
item["bounds"].as_rect().expect("clear-rect type must have bounds"),
&info.clip_rect
);
dl.push_clear_rect(&info);
}
fn handle_hit_test(
&mut self,
dl: &mut DisplayListBuilder,
item: &Yaml,
info: &mut CommonItemProperties,
) {
info.clip_rect = try_intersect!(
item["bounds"].as_rect().expect("hit-test type must have bounds"),
&info.clip_rect
);
dl.push_hit_test(&info);
}
fn handle_line(
&mut self,
dl: &mut DisplayListBuilder,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let color = item["color"].as_colorf().unwrap_or(ColorF::BLACK);
let orientation = item["orientation"]
@ -812,6 +849,7 @@ impl YamlFrameReader {
0.0
};
let area;
if item["baseline"].is_badvalue() {
let bounds_key = if item["type"].is_badvalue() {
"rect"
@ -819,7 +857,7 @@ impl YamlFrameReader {
"bounds"
};
info.rect = item[bounds_key]
area = item[bounds_key]
.as_rect()
.expect("line type must have bounds");
} else {
@ -829,7 +867,7 @@ impl YamlFrameReader {
let end = item["end"].as_f32().expect("line must have end");
let width = item["width"].as_f32().expect("line must have width");
info.rect = match orientation {
area = match orientation {
LineOrientation::Horizontal => {
LayoutRect::new(LayoutPoint::new(start, baseline),
LayoutSize::new(end - start, width))
@ -843,7 +881,7 @@ impl YamlFrameReader {
dl.push_line(
&info,
&self.top_space_and_clip(),
&area,
wavy_line_thickness,
orientation,
&color,
@ -855,7 +893,7 @@ impl YamlFrameReader {
&mut self,
dl: &mut DisplayListBuilder,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let bounds_key = if item["type"].is_badvalue() {
"gradient"
@ -865,19 +903,25 @@ impl YamlFrameReader {
let bounds = item[bounds_key]
.as_rect()
.expect("gradient must have bounds");
info.rect = bounds;
let gradient = self.to_gradient(dl, item);
let tile_size = item["tile-size"].as_size().unwrap_or(bounds.size);
let tile_spacing = item["tile-spacing"].as_size().unwrap_or(LayoutSize::zero());
dl.push_gradient(&info, &self.top_space_and_clip(), gradient, tile_size, tile_spacing);
dl.push_gradient(
&info,
bounds,
gradient,
tile_size,
tile_spacing
);
}
fn handle_radial_gradient(
&mut self,
dl: &mut DisplayListBuilder,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let bounds_key = if item["type"].is_badvalue() {
"radial-gradient"
@ -887,14 +931,13 @@ impl YamlFrameReader {
let bounds = item[bounds_key]
.as_rect()
.expect("radial gradient must have bounds");
info.rect = bounds;
let gradient = self.to_radial_gradient(dl, item);
let tile_size = item["tile-size"].as_size().unwrap_or(bounds.size);
let tile_spacing = item["tile-spacing"].as_size().unwrap_or(LayoutSize::zero());
dl.push_radial_gradient(
&info,
&self.top_space_and_clip(),
bounds,
gradient,
tile_size,
tile_spacing,
@ -906,16 +949,14 @@ impl YamlFrameReader {
dl: &mut DisplayListBuilder,
wrench: &mut Wrench,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let bounds_key = if item["type"].is_badvalue() {
"border"
} else {
"bounds"
};
info.rect = item[bounds_key]
.as_rect()
.expect("borders must have bounds");
let bounds = item[bounds_key].as_rect().expect("borders must have bounds");
let widths = item["width"]
.as_vec_f32()
.expect("borders must have width(s)");
@ -984,10 +1025,10 @@ impl YamlFrameReader {
"image" | "gradient" | "radial-gradient" => {
let image_width = item["image-width"]
.as_i64()
.unwrap_or(info.rect.size.width as i64);
.unwrap_or(bounds.size.width as i64);
let image_height = item["image-height"]
.as_i64()
.unwrap_or(info.rect.size.height as i64);
.unwrap_or(bounds.size.height as i64);
let fill = item["fill"].as_bool().unwrap_or(false);
let slice = item["slice"].as_vec_u32();
@ -1060,7 +1101,7 @@ impl YamlFrameReader {
None
};
if let Some(details) = border_details {
dl.push_border(&info, &self.top_space_and_clip(), widths, details);
dl.push_border(&info, bounds, widths, details);
}
}
@ -1068,7 +1109,7 @@ impl YamlFrameReader {
&mut self,
dl: &mut DisplayListBuilder,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let bounds_key = if item["type"].is_badvalue() {
"box-shadow"
@ -1078,7 +1119,6 @@ impl YamlFrameReader {
let bounds = item[bounds_key]
.as_rect()
.expect("box shadow must have bounds");
info.rect = bounds;
let box_bounds = item["box-bounds"].as_rect().unwrap_or(bounds);
let offset = self.resolve_vector(&item["offset"], LayoutVector2D::zero());
let color = item["color"]
@ -1101,7 +1141,6 @@ impl YamlFrameReader {
dl.push_box_shadow(
&info,
&self.top_space_and_clip(),
box_bounds,
offset,
color,
@ -1117,7 +1156,7 @@ impl YamlFrameReader {
dl: &mut DisplayListBuilder,
wrench: &mut Wrench,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
// TODO(gw): Support other YUV color depth and spaces.
let color_depth = ColorDepth::Color8;
@ -1157,14 +1196,14 @@ impl YamlFrameReader {
};
let bounds = item["bounds"].as_vec_f32().unwrap();
info.rect = LayoutRect::new(
let bounds = LayoutRect::new(
LayoutPoint::new(bounds[0], bounds[1]),
LayoutSize::new(bounds[2], bounds[3]),
);
dl.push_yuv_image(
&info,
&self.top_space_and_clip(),
bounds,
yuv_data,
color_depth,
color_space,
@ -1177,7 +1216,7 @@ impl YamlFrameReader {
dl: &mut DisplayListBuilder,
wrench: &mut Wrench,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let filename = &item[if item["type"].is_badvalue() {
"image"
@ -1190,7 +1229,7 @@ impl YamlFrameReader {
self.add_or_get_image(&file, tiling, wrench);
let bounds_raws = item["bounds"].as_vec_f32().unwrap();
info.rect = if bounds_raws.len() == 2 {
let bounds = if bounds_raws.len() == 2 {
LayoutRect::new(LayoutPoint::new(bounds_raws[0], bounds_raws[1]), image_dims)
} else if bounds_raws.len() == 4 {
LayoutRect::new(
@ -1203,7 +1242,6 @@ impl YamlFrameReader {
item["bounds"]
);
};
let stretch_size = item["stretch-size"].as_size().unwrap_or(image_dims);
let tile_spacing = item["tile-spacing"]
.as_size()
@ -1227,7 +1265,7 @@ impl YamlFrameReader {
};
dl.push_image(
&info,
&self.top_space_and_clip(),
bounds,
stretch_size,
tile_spacing,
rendering,
@ -1242,7 +1280,7 @@ impl YamlFrameReader {
dl: &mut DisplayListBuilder,
wrench: &mut Wrench,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let size = item["size"].as_pt_to_au().unwrap_or(Au::from_f32_px(16.0));
let color = item["color"].as_colorf().unwrap_or(ColorF::BLACK);
@ -1307,6 +1345,7 @@ impl YamlFrameReader {
.map(|k| {
GlyphInstance {
index: *k.1,
// In the future we want to change the API to be relative, eliminating this
point: LayoutPoint::new(
origin.x + glyph_offsets[k.0 * 2],
origin.y + glyph_offsets[k.0 * 2 + 1],
@ -1347,11 +1386,10 @@ impl YamlFrameReader {
.collect::<Vec<_>>();
(glyphs, bounds)
};
info.rect = rect;
dl.push_text(
&info,
&self.top_space_and_clip(),
rect,
&glyphs,
font_instance_key,
color,
@ -1363,12 +1401,21 @@ impl YamlFrameReader {
&mut self,
dl: &mut DisplayListBuilder,
item: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
info.rect = item["bounds"].as_rect().expect("iframe must have bounds");
let bounds = item["bounds"].as_rect().expect("iframe must have bounds");
let pipeline_id = item["id"].as_pipeline_id().unwrap();
let ignore = item["ignore_missing_pipeline"].as_bool().unwrap_or(true);
dl.push_iframe(&info, &self.top_space_and_clip(), pipeline_id, ignore);
dl.push_iframe(
bounds,
info.clip_rect,
&SpaceAndClipInfo {
spatial_id: info.spatial_id,
clip_id: info.clip_id
},
pipeline_id,
ignore
);
}
fn get_complex_clip_for_item(&mut self, yaml: &Yaml) -> Option<ComplexClipRegion> {
@ -1454,12 +1501,18 @@ impl YamlFrameReader {
}
}
let mut info = LayoutPrimitiveInfo::with_clip_rect(LayoutRect::zero(), clip_rect);
info.is_backface_visible = item["backface-visible"].as_bool().unwrap_or(true);;
info.tag = self.to_hit_testing_tag(&item["hit-testing-tag"]);
let space_and_clip = self.top_space_and_clip();
let mut info = CommonItemProperties {
clip_rect,
clip_id: space_and_clip.clip_id,
spatial_id: space_and_clip.spatial_id,
hit_info: self.to_hit_testing_tag(&item["hit-testing-tag"]),
is_backface_visible: item["backface-visible"].as_bool().unwrap_or(true),
};
match item_type {
"rect" => self.handle_rect(dl, item, &mut info),
"hit-test" => self.handle_hit_test(dl, item, &mut info),
"clear-rect" => self.handle_clear_rect(dl, item, &mut info),
"line" => self.handle_line(dl, item, &mut info),
"image" => self.handle_image(dl, wrench, item, &mut info),
@ -1628,15 +1681,14 @@ impl YamlFrameReader {
&mut self,
dl: &mut DisplayListBuilder,
yaml: &Yaml,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let blur_radius = yaml["blur-radius"].as_f32().unwrap_or(0.0);
let offset = yaml["offset"].as_vector().unwrap_or(LayoutVector2D::zero());
let color = yaml["color"].as_colorf().unwrap_or(ColorF::BLACK);
dl.push_shadow(
&info,
&self.top_space_and_clip(),
&SpaceAndClipInfo { spatial_id: info.spatial_id, clip_id: info.clip_id },
Shadow {
blur_radius,
offset,
@ -1751,7 +1803,7 @@ impl YamlFrameReader {
};
let reference_frame_id = dl.push_reference_frame(
&bounds,
bounds.origin,
*self.spatial_id_stack.last().unwrap(),
transform_style,
transform.or_else(|| perspective).unwrap_or_default().into(),
@ -1789,7 +1841,7 @@ impl YamlFrameReader {
wrench: &mut Wrench,
yaml: &Yaml,
is_root: bool,
info: &mut LayoutPrimitiveInfo,
info: &mut CommonItemProperties,
) {
let default_bounds = LayoutRect::new(LayoutPoint::zero(), wrench.window_size_f32());
let mut bounds = yaml["bounds"].as_rect().unwrap_or(default_bounds);
@ -1804,7 +1856,6 @@ impl YamlFrameReader {
None
};
// note: this API is deprecated, use the standard clip-and-scroll field instead
let clip_node_id = self.to_clip_id(&yaml["clip-node"], dl.pipeline_id);
let transform_style = yaml["transform-style"]
@ -1828,12 +1879,10 @@ impl YamlFrameReader {
let filters = yaml["filters"].as_vec_filter_op().unwrap_or(vec![]);
let filter_datas = yaml["filter-datas"].as_vec_filter_data().unwrap_or(vec![]);
info.rect = bounds;
info.clip_rect = bounds;
dl.push_stacking_context(
&info,
bounds.origin,
*self.spatial_id_stack.last().unwrap(),
info.is_backface_visible,
clip_node_id,
transform_style,
mix_blend_mode,

Просмотреть файл

@ -16,7 +16,6 @@ use super::CURRENT_FRAME_NUMBER;
use time;
use webrender;
use webrender::api::*;
use webrender::api::SpecificDisplayItem as Sdi;
use webrender::api::channel::Payload;
use webrender::api::units::*;
use yaml_helper::StringEnum;
@ -190,6 +189,33 @@ fn maybe_radius_yaml(radius: &BorderRadius) -> Option<Yaml> {
}
}
fn common_node(v: &mut Table, clip_id_mapper: &mut ClipIdMapper, info: &CommonItemProperties) {
rect_node(v, "clip-rect", &info.clip_rect);
bool_node(v, "backface-visible", info.is_backface_visible);
clip_and_scroll_node(v, clip_id_mapper, info.clip_id, info.spatial_id);
if let Some(tag) = info.hit_info {
yaml_node(
v,
"hit-testing-tag",
Yaml::Array(vec![Yaml::Integer(tag.0 as i64), Yaml::Integer(tag.1 as i64)])
);
}
}
fn clip_and_scroll_node(
v: &mut Table,
clip_id_mapper: &mut ClipIdMapper,
clip_id: ClipId,
spatial_id: SpatialId
) {
let clip_id = if clip_id.is_root() { None } else { Some(clip_id) };
yaml_node(v, "clip-and-scroll",
clip_id_mapper.map_clip_and_scroll_ids(clip_id, spatial_id)
);
}
fn write_reference_frame(
parent: &mut Table,
reference_frame: &ReferenceFrame,
@ -564,7 +590,7 @@ impl YamlFrameWriter {
let mut referenced_pipeline_ids = vec![];
let mut traversal = dl.iter();
while let Some(item) = traversal.next() {
if let &SpecificDisplayItem::Iframe(k) = item.item() {
if let &DisplayItem::Iframe(k) = item.item() {
referenced_pipeline_ids.push(k.pipeline_id);
}
}
@ -825,35 +851,24 @@ impl YamlFrameWriter {
};
let mut v = new_table();
let info = base.get_layout_primitive_info(&LayoutVector2D::zero());
rect_node(&mut v, "bounds", &info.rect);
rect_node(&mut v, "clip-rect", &info.clip_rect);
if let Some(tag) = info.tag {
yaml_node(
&mut v,
"hit-testing-tag",
Yaml::Array(vec![Yaml::Integer(tag.0 as i64), Yaml::Integer(tag.1 as i64)])
);
}
let space_and_clip = base.space_and_clip_info();
let clip_id = if space_and_clip.clip_id.is_root() { None } else { Some(space_and_clip.clip_id) };
yaml_node(&mut v, "clip-and-scroll",
clip_id_mapper.map_clip_and_scroll_ids(clip_id, space_and_clip.spatial_id)
);
bool_node(&mut v, "backface-visible", base.is_backface_visible());
match *base.item() {
Sdi::Rectangle(item) => {
DisplayItem::Rectangle(item) => {
str_node(&mut v, "type", "rect");
common_node(&mut v, clip_id_mapper, &item.common);
color_node(&mut v, "color", item.color);
}
Sdi::ClearRectangle => {
str_node(&mut v, "type", "clear-rect");;
DisplayItem::HitTest(item) => {
str_node(&mut v, "type", "hit-test");
common_node(&mut v, clip_id_mapper, &item.common);
}
Sdi::Line(item) => {
DisplayItem::ClearRectangle(item) => {
str_node(&mut v, "type", "clear-rect");
common_node(&mut v, clip_id_mapper, &item.common);
}
DisplayItem::Line(item) => {
str_node(&mut v, "type", "line");
common_node(&mut v, clip_id_mapper, &item.common);
rect_node(&mut v, "bounds", &item.area);
if let LineStyle::Wavy = item.style {
f32_node(&mut v, "thickness", item.wavy_line_thickness);
}
@ -861,7 +876,7 @@ impl YamlFrameWriter {
color_node(&mut v, "color", item.color);
str_node(&mut v, "style", item.style.as_str());
}
Sdi::Text(item) => {
DisplayItem::Text(item) => {
let gi = display_list.get(base.glyphs());
let mut indices: Vec<u32> = vec![];
let mut offsets: Vec<f32> = vec![];
@ -870,6 +885,8 @@ impl YamlFrameWriter {
offsets.push(g.point.x);
offsets.push(g.point.y);
}
common_node(&mut v, clip_id_mapper, &item.common);
rect_node(&mut v, "bounds", &item.bounds);
u32_vec_node(&mut v, "glyphs", &indices);
f32_vec_node(&mut v, "offsets", &offsets);
@ -915,7 +932,9 @@ impl YamlFrameWriter {
}
}
}
Sdi::Image(item) => {
DisplayItem::Image(item) => {
common_node(&mut v, clip_id_mapper, &item.common);
rect_node(&mut v, "bounds", &item.bounds);
if let Some(path) = self.path_for_image(item.image_key) {
path_node(&mut v, "image", &path);
}
@ -938,13 +957,16 @@ impl YamlFrameWriter {
AlphaType::Alpha => str_node(&mut v, "alpha-type", "alpha"),
};
}
Sdi::YuvImage(_) => {
DisplayItem::YuvImage(item) => {
str_node(&mut v, "type", "yuv-image");
common_node(&mut v, clip_id_mapper, &item.common);
// TODO
println!("TODO YAML YuvImage");
}
Sdi::Border(item) => {
DisplayItem::Border(item) => {
str_node(&mut v, "type", "border");
rect_node(&mut v, "bounds", &item.bounds);
common_node(&mut v, clip_id_mapper, &item.common);
match item.details {
BorderDetails::Normal(ref details) => {
let trbl =
@ -1058,8 +1080,9 @@ impl YamlFrameWriter {
}
}
}
Sdi::BoxShadow(item) => {
DisplayItem::BoxShadow(item) => {
str_node(&mut v, "type", "box-shadow");
common_node(&mut v, clip_id_mapper, &item.common);
rect_node(&mut v, "box-bounds", &item.box_bounds);
vector_node(&mut v, "offset", &item.offset);
color_node(&mut v, "color", item.color);
@ -1074,8 +1097,10 @@ impl YamlFrameWriter {
};
str_node(&mut v, "clip-mode", clip_mode);
}
Sdi::Gradient(item) => {
DisplayItem::Gradient(item) => {
str_node(&mut v, "type", "gradient");
rect_node(&mut v, "bounds", &item.bounds);
common_node(&mut v, clip_id_mapper, &item.common);
point_node(&mut v, "start", &item.gradient.start_point);
point_node(&mut v, "end", &item.gradient.end_point);
size_node(&mut v, "tile-size", &item.tile_size);
@ -1092,8 +1117,10 @@ impl YamlFrameWriter {
item.gradient.extend_mode == ExtendMode::Repeat,
);
}
Sdi::RadialGradient(item) => {
DisplayItem::RadialGradient(item) => {
str_node(&mut v, "type", "radial-gradient");
rect_node(&mut v, "bounds", &item.bounds);
common_node(&mut v, clip_id_mapper, &item.common);
size_node(&mut v, "tile-size", &item.tile_size);
size_node(&mut v, "tile-spacing", &item.tile_spacing);
radial_gradient_to_yaml(
@ -1103,13 +1130,29 @@ impl YamlFrameWriter {
display_list
);
}
Sdi::Iframe(item) => {
DisplayItem::Iframe(item) => {
str_node(&mut v, "type", "iframe");
rect_node(&mut v, "bounds", &item.bounds);
rect_node(&mut v, "clip_rect", &item.clip_rect);
clip_and_scroll_node(
&mut v,
clip_id_mapper,
item.space_and_clip.clip_id,
item.space_and_clip.spatial_id
);
u32_vec_node(&mut v, "id", &[item.pipeline_id.0, item.pipeline_id.1]);
bool_node(&mut v, "ignore_missing_pipeline", item.ignore_missing_pipeline);
}
Sdi::PushStackingContext(item) => {
DisplayItem::PushStackingContext(item) => {
str_node(&mut v, "type", "stacking-context");
clip_and_scroll_node(
&mut v,
clip_id_mapper,
item.stacking_context.clip_id.unwrap_or(ClipId::invalid()),
item.spatial_id
);
point_node(&mut v, "origin", &item.origin);
bool_node(&mut v, "backface-visible", item.is_backface_visible);
let filters = display_list.get(base.filters());
write_stacking_context(
&mut v,
@ -1124,7 +1167,7 @@ impl YamlFrameWriter {
self.write_display_list(&mut v, display_list, scene, &mut sub_iter, clip_id_mapper);
continue_traversal = Some(sub_iter);
}
Sdi::PushReferenceFrame(item) => {
DisplayItem::PushReferenceFrame(item) => {
str_node(&mut v, "type", "reference-frame");
write_reference_frame(
&mut v,
@ -1137,8 +1180,14 @@ impl YamlFrameWriter {
self.write_display_list(&mut v, display_list, scene, &mut sub_iter, clip_id_mapper);
continue_traversal = Some(sub_iter);
}
Sdi::Clip(item) => {
DisplayItem::Clip(item) => {
str_node(&mut v, "type", "clip");
clip_and_scroll_node(
&mut v,
clip_id_mapper,
item.parent_space_and_clip.clip_id,
item.parent_space_and_clip.spatial_id);
rect_node(&mut v, "clip-rect", &item.clip_rect);
usize_node(&mut v, "id", clip_id_mapper.add_clip_id(item.id));
let (complex_clips, complex_clip_count) = base.complex_clip();
@ -1154,7 +1203,7 @@ impl YamlFrameWriter {
yaml_node(&mut v, "image-mask", mask_yaml);
}
}
Sdi::ClipChain(item) => {
DisplayItem::ClipChain(item) => {
str_node(&mut v, "type", "clip-chain");
let id = ClipId::ClipChain(item.id);
@ -1170,11 +1219,11 @@ impl YamlFrameWriter {
yaml_node(&mut v, "parent", clip_id_mapper.map_clip_id(&parent));
}
}
Sdi::ScrollFrame(item) => {
DisplayItem::ScrollFrame(item) => {
str_node(&mut v, "type", "scroll-frame");
usize_node(&mut v, "id", clip_id_mapper.add_spatial_id(item.scroll_frame_id));
size_node(&mut v, "content-size", &base.rect().size);
rect_node(&mut v, "bounds", &base.clip_rect());
size_node(&mut v, "content-size", &item.content_rect.size);
rect_node(&mut v, "bounds", &item.clip_rect);
vector_node(&mut v, "external-scroll-offset", &item.external_scroll_offset);
let (complex_clips, complex_clip_count) = base.complex_clip();
@ -1190,10 +1239,10 @@ impl YamlFrameWriter {
yaml_node(&mut v, "image-mask", mask_yaml);
}
}
Sdi::StickyFrame(item) => {
DisplayItem::StickyFrame(item) => {
str_node(&mut v, "type", "sticky-frame");
usize_node(&mut v, "id", clip_id_mapper.add_spatial_id(item.id));
rect_node(&mut v, "bounds", &base.clip_rect());
rect_node(&mut v, "bounds", &item.bounds);
if let Some(margin) = item.margins.top {
f32_node(&mut v, "margin-top", margin);
@ -1227,24 +1276,19 @@ impl YamlFrameWriter {
yaml_node(&mut v, "previously-applied-offset", Yaml::Array(applied));
}
Sdi::PopReferenceFrame |
Sdi::PopStackingContext => return,
DisplayItem::PopReferenceFrame |
DisplayItem::PopStackingContext => return,
Sdi::PopCacheMarker => return,
Sdi::PushCacheMarker(_) => {
str_node(&mut v, "type", "cache-marker");
}
Sdi::SetGradientStops => panic!("dummy item yielded?"),
Sdi::SetFilterOps => panic!("dummy item yielded?"),
Sdi::SetFilterData => panic!("dummy item yielded?"),
Sdi::PushShadow(shadow) => {
DisplayItem::SetGradientStops => panic!("dummy item yielded?"),
DisplayItem::SetFilterOps => panic!("dummy item yielded?"),
DisplayItem::SetFilterData => panic!("dummy item yielded?"),
DisplayItem::PushShadow(item) => {
str_node(&mut v, "type", "shadow");
vector_node(&mut v, "offset", &shadow.offset);
color_node(&mut v, "color", shadow.color);
f32_node(&mut v, "blur-radius", shadow.blur_radius);
vector_node(&mut v, "offset", &item.shadow.offset);
color_node(&mut v, "color", item.shadow.color);
f32_node(&mut v, "blur-radius", item.shadow.blur_radius);
}
Sdi::PopAllShadows => {
DisplayItem::PopAllShadows => {
str_node(&mut v, "type", "pop-all-shadows");
}
}

Просмотреть файл

@ -5107,8 +5107,7 @@ bool nsDisplayCompositorHitTestInfo::CreateWebRenderCommands(
const wr::LayoutRect rect = wr::ToRoundedLayoutRect(devRect);
aBuilder.PushRect(rect, rect, !BackfaceIsHidden(),
wr::ToColorF(gfx::Color()));
aBuilder.PushHitTest(rect, rect, !BackfaceIsHidden());
aBuilder.ClearHitTestInfo();
return true;