Replace Servo DL items with WR ones

The Servo internal display list items are already pretty much
equivalent to the WebRender ones. Except that Servo items contain
base information and associated glyphs and gradient stops which are
stored implicitly in WebRender. Remove the display items for
rectangles, text, images, border, gradients and box shadow and
replace them with their WebRender counter parts.
This commit is contained in:
Pyfisch 2018-08-06 19:47:00 +02:00
parent 025ba5cbe3
commit 9e971f9d8f
4 changed files with 381 additions and 465 deletions

View file

@ -13,7 +13,7 @@
use app_units::Au; use app_units::Au;
use display_list::ToLayout; use display_list::ToLayout;
use display_list::items::{BorderDetails, Gradient, RadialGradient, WebRenderImageInfo}; use display_list::items::WebRenderImageInfo;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Vector2D}; use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Vector2D};
use model::{self, MaybeAuto}; use model::{self, MaybeAuto};
use style::computed_values::background_attachment::single_value::T as BackgroundAttachment; use style::computed_values::background_attachment::single_value::T as BackgroundAttachment;
@ -34,8 +34,9 @@ use style::values::generics::image::EndingShape as GenericEndingShape;
use style::values::generics::image::GradientItem as GenericGradientItem; use style::values::generics::image::GradientItem as GenericGradientItem;
use style::values::specified::background::BackgroundRepeatKeyword; use style::values::specified::background::BackgroundRepeatKeyword;
use style::values::specified::position::{X, Y}; use style::values::specified::position::{X, Y};
use webrender_api::{BorderRadius, BorderSide, BorderStyle, ColorF, ExtendMode, GradientStop}; use webrender_api::{BorderDetails, BorderRadius, BorderSide, BorderStyle, ColorF, ExtendMode};
use webrender_api::{LayoutSize, NinePatchBorder, NinePatchBorderSource, NormalBorder}; use webrender_api::{Gradient, GradientStop, LayoutSize, NinePatchBorder, NinePatchBorderSource};
use webrender_api::{NormalBorder, RadialGradient};
/// A helper data structure for gradients. /// A helper data structure for gradients.
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
@ -543,7 +544,7 @@ pub fn convert_linear_gradient(
stops: &[GradientItem], stops: &[GradientItem],
direction: LineDirection, direction: LineDirection,
repeating: bool, repeating: bool,
) -> Gradient { ) -> (Gradient, Vec<GradientStop>) {
let angle = match direction { let angle = match direction {
LineDirection::Angle(angle) => angle.radians(), LineDirection::Angle(angle) => angle.radians(),
LineDirection::Horizontal(x) => match x { LineDirection::Horizontal(x) => match x {
@ -591,12 +592,14 @@ pub fn convert_linear_gradient(
let center = Point2D::new(size.width / 2, size.height / 2); let center = Point2D::new(size.width / 2, size.height / 2);
(
Gradient { Gradient {
start_point: (center - delta).to_layout(), start_point: (center - delta).to_layout(),
end_point: (center + delta).to_layout(), end_point: (center + delta).to_layout(),
stops,
extend_mode: as_gradient_extend_mode(repeating), extend_mode: as_gradient_extend_mode(repeating),
} },
stops,
)
} }
pub fn convert_radial_gradient( pub fn convert_radial_gradient(
@ -606,7 +609,7 @@ pub fn convert_radial_gradient(
shape: EndingShape, shape: EndingShape,
center: Position, center: Position,
repeating: bool, repeating: bool,
) -> RadialGradient { ) -> (RadialGradient, Vec<GradientStop>) {
let center = Point2D::new( let center = Point2D::new(
center.horizontal.to_used_value(size.width), center.horizontal.to_used_value(size.width),
center.vertical.to_used_value(size.height), center.vertical.to_used_value(size.height),
@ -629,12 +632,17 @@ pub fn convert_radial_gradient(
let stops = convert_gradient_stops(style, stops, radius.width); let stops = convert_gradient_stops(style, stops, radius.width);
(
RadialGradient { RadialGradient {
center: center.to_layout(), center: center.to_layout(),
radius: radius.to_layout(), radius: radius.to_layout(),
stops: stops,
extend_mode: as_gradient_extend_mode(repeating), extend_mode: as_gradient_extend_mode(repeating),
} // FIXME(pyfisch): These values are calculated by WR.
start_offset: 0.0,
end_offset: 0.0,
},
stops,
)
} }
/// Returns the the distance to the nearest or farthest corner depending on the comperator. /// Returns the the distance to the nearest or farthest corner depending on the comperator.
@ -799,7 +807,7 @@ pub fn build_image_border_details(
let corners = &border_style_struct.border_image_slice.offsets; let corners = &border_style_struct.border_image_slice.offsets;
let border_image_repeat = &border_style_struct.border_image_repeat; let border_image_repeat = &border_style_struct.border_image_repeat;
if let Some(image_key) = webrender_image.key { if let Some(image_key) = webrender_image.key {
Some(BorderDetails::Image(NinePatchBorder { Some(BorderDetails::NinePatch(NinePatchBorder {
source: NinePatchBorderSource::Image(image_key), source: NinePatchBorderSource::Image(image_key),
width: webrender_image.width, width: webrender_image.width,
height: webrender_image.height, height: webrender_image.height,

View file

@ -20,15 +20,13 @@ use display_list::background::{calculate_border_image_outset, calculate_inner_bo
use display_list::background::{compute_background_clip, compute_background_placement}; use display_list::background::{compute_background_clip, compute_background_placement};
use display_list::background::{convert_linear_gradient, convert_radial_gradient, get_cyclic}; use display_list::background::{convert_linear_gradient, convert_radial_gradient, get_cyclic};
use display_list::background::simple_normal_border; use display_list::background::simple_normal_border;
use display_list::items::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR}; use display_list::items::{BaseDisplayItem, BLUR_INFLATION_FACTOR, ClipScrollNode};
use display_list::items::{BoxShadowDisplayItem, ClipScrollNode};
use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling}; use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
use display_list::items::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList}; use display_list::items::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList};
use display_list::items::{DisplayListSection, GradientBorder, GradientDisplayItem}; use display_list::items::{DisplayListSection, CommonDisplayItem};
use display_list::items::{IframeDisplayItem, ImageDisplayItem, LineDisplayItem, OpaqueNode}; use display_list::items::{IframeDisplayItem, LineDisplayItem, OpaqueNode};
use display_list::items::{PopAllTextShadowsDisplayItem, PushTextShadowDisplayItem}; use display_list::items::{PopAllTextShadowsDisplayItem, PushTextShadowDisplayItem};
use display_list::items::{RadialGradientBorder, RadialGradientDisplayItem, SolidColorDisplayItem}; use display_list::items::{StackingContext, StackingContextType, StickyFrameData};
use display_list::items::{StackingContext, StackingContextType, StickyFrameData, TextDisplayItem};
use display_list::items::{TextOrientation, WebRenderImageInfo}; use display_list::items::{TextOrientation, WebRenderImageInfo};
use euclid::{rect, Point2D, Rect, SideOffsets2D, Size2D, TypedSize2D, Vector2D}; use euclid::{rect, Point2D, Rect, SideOffsets2D, Size2D, TypedSize2D, Vector2D};
use flex::FlexFlow; use flex::FlexFlow;
@ -71,10 +69,10 @@ use style_traits::CSSPixel;
use style_traits::ToCss; use style_traits::ToCss;
use style_traits::cursor::CursorKind; use style_traits::cursor::CursorKind;
use table_cell::CollapsedBordersForCell; use table_cell::CollapsedBordersForCell;
use webrender_api::{self, BorderRadius, BorderSide, BoxShadowClipMode, ColorF, ExternalScrollId}; use webrender_api::{self, BorderDetails, BorderRadius, BorderSide, BoxShadowClipMode, ColorF};
use webrender_api::{FilterOp, GlyphInstance, ImageRendering, LayoutRect, LayoutSize}; use webrender_api::{ExternalScrollId, FilterOp, GlyphInstance, ImageRendering, LayoutRect};
use webrender_api::{LayoutTransform, LayoutVector2D, LineStyle, NormalBorder, ScrollSensitivity}; use webrender_api::{LayoutSize, LayoutTransform, LayoutVector2D, LineStyle, NormalBorder};
use webrender_api::StickyOffsetBounds; use webrender_api::{StickyOffsetBounds, ScrollSensitivity};
fn establishes_containing_block_for_absolute( fn establishes_containing_block_for_absolute(
flags: StackingContextCollectionFlags, flags: StackingContextCollectionFlags,
@ -371,15 +369,17 @@ impl<'a> DisplayListBuildState<'a> {
clip_scroll_nodes: state.clip_scroll_nodes, clip_scroll_nodes: state.clip_scroll_nodes,
processing_scrolling_overflow_element: false, processing_scrolling_overflow_element: false,
current_stacking_context_id: StackingContextId::root(), current_stacking_context_id: StackingContextId::root(),
current_clipping_and_scrolling: current_clipping_and_scrolling: ClippingAndScrolling::simple(
ClippingAndScrolling::simple(ClipScrollNodeIndex::root_scroll_node()), ClipScrollNodeIndex::root_scroll_node(),
),
iframe_sizes: Vec::new(), iframe_sizes: Vec::new(),
indexable_text: IndexableText::default(), indexable_text: IndexableText::default(),
} }
} }
fn add_display_item(&mut self, display_item: DisplayItem) { fn add_display_item(&mut self, display_item: DisplayItem) {
let items = self.items let items = self
.items
.entry(display_item.stacking_context_id()) .entry(display_item.stacking_context_id())
.or_insert(Vec::new()); .or_insert(Vec::new());
items.push(display_item); items.push(display_item);
@ -408,9 +408,9 @@ impl<'a> DisplayListBuildState<'a> {
section: DisplayListSection, section: DisplayListSection,
) -> BaseDisplayItem { ) -> BaseDisplayItem {
let clipping_and_scrolling = if self.is_background_or_border_of_clip_scroll_node(section) { let clipping_and_scrolling = if self.is_background_or_border_of_clip_scroll_node(section) {
ClippingAndScrolling::simple(self.parent_clip_scroll_node_index( ClippingAndScrolling::simple(
self.current_clipping_and_scrolling.scrolling, self.parent_clip_scroll_node_index(self.current_clipping_and_scrolling.scrolling),
)) )
} else { } else {
self.current_clipping_and_scrolling self.current_clipping_and_scrolling
}; };
@ -474,13 +474,15 @@ impl<'a> DisplayListBuildState<'a> {
list: &mut Vec<DisplayItem>, list: &mut Vec<DisplayItem>,
stacking_context: StackingContext, stacking_context: StackingContext,
) { ) {
let mut child_items = self.items let mut child_items = self
.items
.remove(&stacking_context.id) .remove(&stacking_context.id)
.unwrap_or(Vec::new()); .unwrap_or(Vec::new());
child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section)); child_items.sort_by(|a, b| a.base().section.cmp(&b.base().section));
child_items.reverse(); child_items.reverse();
let mut info = self.stacking_context_info let mut info = self
.stacking_context_info
.remove(&stacking_context.id) .remove(&stacking_context.id)
.unwrap(); .unwrap();
@ -821,7 +823,8 @@ impl FragmentDisplayListBuilding for Fragment {
true true
}, },
// FIXME: In the future, if #15144 is fixed we can remove this case. See #18510. // FIXME: In the future, if #15144 is fixed we can remove this case. See #18510.
SpecificFragmentInfo::TruncatedFragment(ref mut info) => info.full SpecificFragmentInfo::TruncatedFragment(ref mut info) => info
.full
.collect_stacking_contexts_for_blocklike_fragment(state), .collect_stacking_contexts_for_blocklike_fragment(state),
_ => false, _ => false,
} }
@ -918,10 +921,12 @@ impl FragmentDisplayListBuilding for Fragment {
style.get_cursor(CursorKind::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { state.add_display_item(DisplayItem::Rectangle(CommonDisplayItem::new(
base: base, base,
webrender_api::RectangleDisplayItem {
color: background_color.to_layout(), color: background_color.to_layout(),
}))); },
)));
}); });
// The background image is painted on top of the background color. // The background image is painted on top of the background color.
@ -1047,13 +1052,16 @@ impl FragmentDisplayListBuilding for Fragment {
); );
debug!("(building display list) adding background image."); debug!("(building display list) adding background image.");
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem { state.add_display_item(DisplayItem::Image(CommonDisplayItem::new(
base: base, base,
id: webrender_image.key.unwrap(), webrender_api::ImageDisplayItem {
image_key: webrender_image.key.unwrap(),
stretch_size: placement.tile_size.to_layout(), stretch_size: placement.tile_size.to_layout(),
tile_spacing: placement.tile_spacing.to_layout(), tile_spacing: placement.tile_spacing.to_layout(),
image_rendering: style.get_inherited_box().image_rendering.to_layout(), image_rendering: style.get_inherited_box().image_rendering.to_layout(),
}))); alpha_type: webrender_api::AlphaType::PremultipliedAlpha,
},
)));
}); });
} }
@ -1154,22 +1162,22 @@ impl FragmentDisplayListBuilding for Fragment {
let display_item = match gradient.kind { let display_item = match gradient.kind {
GradientKind::Linear(angle_or_corner) => { GradientKind::Linear(angle_or_corner) => {
let gradient = convert_linear_gradient( let (gradient, stops) = convert_linear_gradient(
style, style,
placement.tile_size, placement.tile_size,
&gradient.items[..], &gradient.items[..],
angle_or_corner, angle_or_corner,
gradient.repeating, gradient.repeating,
); );
DisplayItem::Gradient(Box::new(GradientDisplayItem { let item = webrender_api::GradientDisplayItem {
base: base, gradient,
gradient: gradient, tile_size: placement.tile_size.to_layout(),
tile: placement.tile_size.to_layout(),
tile_spacing: placement.tile_spacing.to_layout(), tile_spacing: placement.tile_spacing.to_layout(),
})) };
DisplayItem::Gradient(CommonDisplayItem::with_data(base, item, stops))
}, },
GradientKind::Radial(shape, center, _angle) => { GradientKind::Radial(shape, center, _angle) => {
let gradient = convert_radial_gradient( let (gradient, stops) = convert_radial_gradient(
style, style,
placement.tile_size, placement.tile_size,
&gradient.items[..], &gradient.items[..],
@ -1177,12 +1185,12 @@ impl FragmentDisplayListBuilding for Fragment {
center, center,
gradient.repeating, gradient.repeating,
); );
DisplayItem::RadialGradient(Box::new(RadialGradientDisplayItem { let item = webrender_api::RadialGradientDisplayItem {
base: base, gradient,
gradient: gradient, tile_size: placement.tile_size.to_layout(),
tile: placement.tile_size.to_layout(),
tile_spacing: placement.tile_spacing.to_layout(), tile_spacing: placement.tile_spacing.to_layout(),
})) };
DisplayItem::RadialGradient(CommonDisplayItem::with_data(base, item, stops))
}, },
}; };
state.add_display_item(display_item); state.add_display_item(display_item);
@ -1216,8 +1224,9 @@ impl FragmentDisplayListBuilding for Fragment {
display_list_section, display_list_section,
); );
let border_radius = build_border_radius(absolute_bounds, style.get_border()); let border_radius = build_border_radius(absolute_bounds, style.get_border());
state.add_display_item(DisplayItem::BoxShadow(Box::new(BoxShadowDisplayItem { state.add_display_item(DisplayItem::BoxShadow(CommonDisplayItem::new(
base: base, base,
webrender_api::BoxShadowDisplayItem {
box_bounds: absolute_bounds.to_layout(), box_bounds: absolute_bounds.to_layout(),
color: style.resolve_color(box_shadow.base.color).to_layout(), color: style.resolve_color(box_shadow.base.color).to_layout(),
offset: LayoutVector2D::new( offset: LayoutVector2D::new(
@ -1232,7 +1241,8 @@ impl FragmentDisplayListBuilding for Fragment {
} else { } else {
BoxShadowClipMode::Outset BoxShadowClipMode::Outset
}, },
}))); },
)));
} }
} }
@ -1312,6 +1322,7 @@ impl FragmentDisplayListBuilding for Fragment {
); );
let size = bounds.outer_rect(outset).size; let size = bounds.outer_rect(outset).size;
let mut stops = Vec::new();
let details = match border_style_struct.border_image_source { let details = match border_style_struct.border_image_source {
Either::First(_) => Some(BorderDetails::Normal(NormalBorder { Either::First(_) => Some(BorderDetails::Normal(NormalBorder {
left: BorderSide { left: BorderSide {
@ -1333,36 +1344,53 @@ impl FragmentDisplayListBuilding for Fragment {
radius: border_radius, radius: border_radius,
})), })),
Either::Second(Image::Gradient(ref gradient)) => Some(match gradient.kind { Either::Second(Image::Gradient(ref gradient)) => Some(match gradient.kind {
GradientKind::Linear(angle_or_corner) => BorderDetails::Gradient(GradientBorder { GradientKind::Linear(angle_or_corner) => {
gradient: convert_linear_gradient( let (wr_gradient, linear_stops) = convert_linear_gradient(
style, style,
bounds.size, bounds.size,
&gradient.items[..], &gradient.items[..],
angle_or_corner, angle_or_corner,
gradient.repeating, gradient.repeating,
), );
stops = linear_stops;
BorderDetails::NinePatch(webrender_api::NinePatchBorder {
source: webrender_api::NinePatchBorderSource::Gradient(wr_gradient),
width: 0,
height: 0,
slice: SideOffsets2D::zero(),
fill: false,
repeat_horizontal: webrender_api::RepeatMode::Stretch,
repeat_vertical: webrender_api::RepeatMode::Stretch,
outset: outset_layout, outset: outset_layout,
}), })
},
GradientKind::Radial(shape, center, _angle) => { GradientKind::Radial(shape, center, _angle) => {
BorderDetails::RadialGradient(RadialGradientBorder { let (wr_gradient, radial_stops) = convert_radial_gradient(
gradient: convert_radial_gradient(
style, style,
bounds.size, bounds.size,
&gradient.items[..], &gradient.items[..],
shape, shape,
center, center,
gradient.repeating, gradient.repeating,
), );
stops = radial_stops;
BorderDetails::NinePatch(webrender_api::NinePatchBorder {
source: webrender_api::NinePatchBorderSource::RadialGradient(wr_gradient),
width: 0,
height: 0,
slice: SideOffsets2D::zero(),
fill: false,
repeat_horizontal: webrender_api::RepeatMode::Stretch,
repeat_vertical: webrender_api::RepeatMode::Stretch,
outset: outset_layout, outset: outset_layout,
}) })
}, },
}), }),
Either::Second(Image::PaintWorklet(ref paint_worklet)) => { Either::Second(Image::PaintWorklet(ref paint_worklet)) => self
self.get_webrender_image_for_paint_worklet(state, style, paint_worklet, size) .get_webrender_image_for_paint_worklet(state, style, paint_worklet, size)
.and_then(|image| { .and_then(|image| {
build_image_border_details(image, border_style_struct, outset_layout) build_image_border_details(image, border_style_struct, outset_layout)
}) }),
},
Either::Second(Image::Rect(..)) => { Either::Second(Image::Rect(..)) => {
// TODO: Handle border-image with `-moz-image-rect`. // TODO: Handle border-image with `-moz-image-rect`.
None None
@ -1385,11 +1413,14 @@ impl FragmentDisplayListBuilding for Fragment {
}), }),
}; };
if let Some(details) = details { if let Some(details) = details {
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
base, base,
border_widths: border_widths.to_layout(), webrender_api::BorderDisplayItem {
widths: border_widths.to_layout(),
details, details,
}))); },
stops,
)));
} }
} }
@ -1429,11 +1460,17 @@ impl FragmentDisplayListBuilding for Fragment {
style.get_cursor(CursorKind::Default), style.get_cursor(CursorKind::Default),
DisplayListSection::Outlines, DisplayListSection::Outlines,
); );
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
base: base, base,
border_widths: SideOffsets2D::new_all_same(width).to_layout(), webrender_api::BorderDisplayItem {
details: BorderDetails::Normal(simple_normal_border(color, outline_style.to_layout())), widths: SideOffsets2D::new_all_same(width).to_layout(),
}))); details: BorderDetails::Normal(simple_normal_border(
color,
outline_style.to_layout(),
)),
},
Vec::new(),
)));
} }
fn build_debug_borders_around_text_fragments( fn build_debug_borders_around_text_fragments(
@ -1456,14 +1493,17 @@ impl FragmentDisplayListBuilding for Fragment {
style.get_cursor(CursorKind::Default), style.get_cursor(CursorKind::Default),
DisplayListSection::Content, DisplayListSection::Content,
); );
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
base: base, base,
border_widths: SideOffsets2D::new_all_same(Au::from_px(1)).to_layout(), webrender_api::BorderDisplayItem {
widths: SideOffsets2D::new_all_same(Au::from_px(1)).to_layout(),
details: BorderDetails::Normal(simple_normal_border( details: BorderDetails::Normal(simple_normal_border(
ColorF::rgb(0, 0, 200), ColorF::rgb(0, 0, 200),
webrender_api::BorderStyle::Solid, webrender_api::BorderStyle::Solid,
)), )),
}))); },
Vec::new(),
)));
// Draw a rectangle representing the baselines. // Draw a rectangle representing the baselines.
let mut baseline = LogicalRect::from_physical( let mut baseline = LogicalRect::from_physical(
@ -1503,14 +1543,17 @@ impl FragmentDisplayListBuilding for Fragment {
self.style.get_cursor(CursorKind::Default), self.style.get_cursor(CursorKind::Default),
DisplayListSection::Content, DisplayListSection::Content,
); );
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
base: base, base,
border_widths: SideOffsets2D::new_all_same(Au::from_px(1)).to_layout(), webrender_api::BorderDisplayItem {
widths: SideOffsets2D::new_all_same(Au::from_px(1)).to_layout(),
details: BorderDetails::Normal(simple_normal_border( details: BorderDetails::Normal(simple_normal_border(
ColorF::rgb(0, 0, 200), ColorF::rgb(0, 0, 200),
webrender_api::BorderStyle::Solid, webrender_api::BorderStyle::Solid,
)), )),
}))); },
Vec::new(),
)));
} }
fn build_display_items_for_selection_if_necessary( fn build_display_items_for_selection_if_necessary(
@ -1540,10 +1583,12 @@ impl FragmentDisplayListBuilding for Fragment {
self.style.get_cursor(CursorKind::Default), self.style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
); );
state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { state.add_display_item(DisplayItem::Rectangle(CommonDisplayItem::new(
base: base, base,
webrender_api::RectangleDisplayItem {
color: background_color.to_layout(), color: background_color.to_layout(),
}))); },
)));
} }
// Draw a caret at the insertion point. // Draw a caret at the insertion point.
@ -1584,10 +1629,12 @@ impl FragmentDisplayListBuilding for Fragment {
self.style.get_cursor(cursor), self.style.get_cursor(cursor),
display_list_section, display_list_section,
); );
state.add_display_item(DisplayItem::SolidColor(Box::new(SolidColorDisplayItem { state.add_display_item(DisplayItem::Rectangle(CommonDisplayItem::new(
base: base, base,
webrender_api::RectangleDisplayItem {
color: self.style().get_color().color.to_layout(), color: self.style().get_color().color.to_layout(),
}))); },
)));
} }
fn build_display_list( fn build_display_list(
@ -1658,9 +1705,11 @@ impl FragmentDisplayListBuilding for Fragment {
state, state,
&*node.style, &*node.style,
Some(InlineNodeBorderInfo { Some(InlineNodeBorderInfo {
is_first_fragment_of_element: node.flags is_first_fragment_of_element: node
.flags
.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT), .contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT),
is_last_fragment_of_element: node.flags is_last_fragment_of_element: node
.flags
.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT), .contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT),
}), }),
border_painting_mode, border_painting_mode,
@ -1873,16 +1922,20 @@ impl FragmentDisplayListBuilding for Fragment {
if let Some(ref image) = image_fragment.image { if let Some(ref image) = image_fragment.image {
if let Some(id) = image.id { if let Some(id) = image.id {
let base = create_base_display_item(state); let base = create_base_display_item(state);
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem { state.add_display_item(DisplayItem::Image(CommonDisplayItem::new(
base, base,
id, webrender_api::ImageDisplayItem {
image_key: id,
stretch_size: stacking_relative_content_box.size.to_layout(), stretch_size: stacking_relative_content_box.size.to_layout(),
tile_spacing: LayoutSize::zero(), tile_spacing: LayoutSize::zero(),
image_rendering: self.style image_rendering: self
.style
.get_inherited_box() .get_inherited_box()
.image_rendering .image_rendering
.to_layout(), .to_layout(),
}))); alpha_type: webrender_api::AlphaType::PremultipliedAlpha,
},
)));
} }
} }
}, },
@ -1906,13 +1959,16 @@ impl FragmentDisplayListBuilding for Fragment {
}; };
let base = create_base_display_item(state); let base = create_base_display_item(state);
let display_item = DisplayItem::Image(Box::new(ImageDisplayItem { let display_item = DisplayItem::Image(CommonDisplayItem::new(
base, base,
id: image_key, webrender_api::ImageDisplayItem {
image_key,
stretch_size: stacking_relative_content_box.size.to_layout(), stretch_size: stacking_relative_content_box.size.to_layout(),
tile_spacing: LayoutSize::zero(), tile_spacing: LayoutSize::zero(),
image_rendering: ImageRendering::Auto, image_rendering: ImageRendering::Auto,
})); alpha_type: webrender_api::AlphaType::PremultipliedAlpha,
},
));
state.add_display_item(display_item); state.add_display_item(display_item);
}, },
@ -2092,12 +2148,15 @@ impl FragmentDisplayListBuilding for Fragment {
}; };
state.indexable_text.insert(self.node, indexable_text); state.indexable_text.insert(self.node, indexable_text);
state.add_display_item(DisplayItem::Text(Box::new(TextDisplayItem { state.add_display_item(DisplayItem::Text(CommonDisplayItem::with_data(
base: base.clone(), base.clone(),
glyphs: glyphs, webrender_api::TextDisplayItem {
font_key: text_fragment.run.font_key, font_key: text_fragment.run.font_key,
text_color: text_color.to_layout(), color: text_color.to_layout(),
}))); glyph_options: None,
},
glyphs,
)));
} }
// TODO(#17715): emit text-emphasis marks here. // TODO(#17715): emit text-emphasis marks here.
@ -2342,7 +2401,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
None => return, None => return,
}; };
let perspective = self.fragment let perspective = self
.fragment
.perspective_matrix(&border_box) .perspective_matrix(&border_box)
.unwrap_or(LayoutTransform::identity()); .unwrap_or(LayoutTransform::identity());
let transform = transform.pre_mul(&perspective).inverse(); let transform = transform.pre_mul(&perspective).inverse();
@ -2420,7 +2480,6 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
if stacking_context_type == Some(StackingContextType::Real) { if stacking_context_type == Some(StackingContextType::Real) {
state.current_real_stacking_context_id = self.base.stacking_context_id; state.current_real_stacking_context_id = self.base.stacking_context_id;
} }
let established_reference_frame = if self.is_reference_frame(stacking_context_type) { let established_reference_frame = if self.is_reference_frame(stacking_context_type) {
@ -2446,7 +2505,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
if establishes_containing_block_for_absolute( if establishes_containing_block_for_absolute(
flags, flags,
self.positioning(), self.positioning(),
established_reference_frame.is_some() established_reference_frame.is_some(),
) { ) {
state.containing_block_clipping_and_scrolling = state.current_clipping_and_scrolling; state.containing_block_clipping_and_scrolling = state.current_clipping_and_scrolling;
} }
@ -2536,7 +2595,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
// We keep track of our position so that any stickily positioned elements can // We keep track of our position so that any stickily positioned elements can
// properly determine the extent of their movement relative to scrolling containers. // properly determine the extent of their movement relative to scrolling containers.
if !flags.contains(StackingContextCollectionFlags::POSITION_NEVER_CREATES_CONTAINING_BLOCK) { if !flags.contains(StackingContextCollectionFlags::POSITION_NEVER_CREATES_CONTAINING_BLOCK)
{
let border_box = if self.fragment.establishes_stacking_context() { let border_box = if self.fragment.establishes_stacking_context() {
stacking_relative_border_box stacking_relative_border_box
} else { } else {
@ -2566,7 +2626,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
} }
let sticky_position = self.sticky_position(); let sticky_position = self.sticky_position();
if sticky_position.left == MaybeAuto::Auto && sticky_position.right == MaybeAuto::Auto && if sticky_position.left == MaybeAuto::Auto &&
sticky_position.right == MaybeAuto::Auto &&
sticky_position.top == MaybeAuto::Auto && sticky_position.top == MaybeAuto::Auto &&
sticky_position.bottom == MaybeAuto::Auto sticky_position.bottom == MaybeAuto::Auto
{ {
@ -2663,7 +2724,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
ScrollSensitivity::ScriptAndInputEvents ScrollSensitivity::ScriptAndInputEvents
}; };
let border_widths = self.fragment let border_widths = self
.fragment
.style .style
.logical_border_width() .logical_border_width()
.to_physical(self.fragment.style.writing_mode); .to_physical(self.fragment.style.writing_mode);
@ -2804,7 +2866,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
let background_border_section = self.background_border_section(); let background_border_section = self.background_border_section();
state.processing_scrolling_overflow_element = self.has_scrolling_overflow(); state.processing_scrolling_overflow_element = self.has_scrolling_overflow();
let stacking_relative_border_box = self.base let stacking_relative_border_box = self
.base
.stacking_relative_border_box_for_display_list(&self.fragment); .stacking_relative_border_box_for_display_list(&self.fragment);
// Add the box that starts the block context. // Add the box that starts the block context.
self.fragment.build_display_list_no_damage( self.fragment.build_display_list_no_damage(
@ -2838,7 +2901,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
background: &style_structs::Background, background: &style_structs::Background,
background_color: RGBA, background_color: RGBA,
) { ) {
let stacking_relative_border_box = self.base let stacking_relative_border_box = self
.base
.stacking_relative_border_box_for_display_list(&self.fragment); .stacking_relative_border_box_for_display_list(&self.fragment);
let background_border_section = self.background_border_section(); let background_border_section = self.background_border_section();
@ -2866,7 +2930,8 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
return Some(StackingContextType::Real); return Some(StackingContextType::Real);
} }
if self.base if self
.base
.flags .flags
.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) .contains(FlowFlags::IS_ABSOLUTELY_POSITIONED)
{ {
@ -2943,7 +3008,8 @@ impl InlineFlowDisplayListBuilding for InlineFlow {
index: usize, index: usize,
) { ) {
let fragment = self.fragments.fragments.get_mut(index).unwrap(); let fragment = self.fragments.fragments.get_mut(index).unwrap();
let stacking_relative_border_box = self.base let stacking_relative_border_box = self
.base
.stacking_relative_border_box_for_display_list(fragment); .stacking_relative_border_box_for_display_list(fragment);
fragment.build_display_list( fragment.build_display_list(
state, state,
@ -2999,7 +3065,8 @@ impl ListItemFlowDisplayListBuilding for ListItemFlow {
fn build_display_list_for_list_item(&mut self, state: &mut DisplayListBuildState) { fn build_display_list_for_list_item(&mut self, state: &mut DisplayListBuildState) {
// Draw the marker, if applicable. // Draw the marker, if applicable.
for marker in &mut self.marker_fragments { for marker in &mut self.marker_fragments {
let stacking_relative_border_box = self.block_flow let stacking_relative_border_box = self
.block_flow
.base .base
.stacking_relative_border_box_for_display_list(marker); .stacking_relative_border_box_for_display_list(marker);
marker.build_display_list( marker.build_display_list(
@ -3062,14 +3129,17 @@ impl BaseFlowDisplayListBuilding for BaseFlow {
None, None,
DisplayListSection::Content, DisplayListSection::Content,
); );
state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem { state.add_display_item(DisplayItem::Border(CommonDisplayItem::with_data(
base: base, base,
border_widths: SideOffsets2D::new_all_same(Au::from_px(2)).to_layout(), webrender_api::BorderDisplayItem {
widths: SideOffsets2D::new_all_same(Au::from_px(2)).to_layout(),
details: BorderDetails::Normal(simple_normal_border( details: BorderDetails::Normal(simple_normal_border(
color, color,
webrender_api::BorderStyle::Solid, webrender_api::BorderStyle::Solid,
)), )),
}))); },
Vec::new(),
)));
} }
} }

View file

@ -22,11 +22,12 @@ use std::cmp::Ordering;
use std::collections::HashMap; use std::collections::HashMap;
use std::f32; use std::f32;
use std::fmt; use std::fmt;
use webrender_api::{BorderRadius, BorderWidths, BoxShadowClipMode, ClipMode, ColorF}; use webrender_api as wr;
use webrender_api::{ComplexClipRegion, ExtendMode, ExternalScrollId, FilterOp, FontInstanceKey}; use webrender_api::{BorderRadius, ClipMode, ColorF};
use webrender_api::{GlyphInstance, GradientStop, ImageKey, ImageRendering, LayoutPoint}; use webrender_api::{ComplexClipRegion, ExternalScrollId, FilterOp};
use webrender_api::{GlyphInstance, GradientStop, ImageKey, LayoutPoint};
use webrender_api::{LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D, LineStyle}; use webrender_api::{LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D, LineStyle};
use webrender_api::{MixBlendMode, NinePatchBorder, NormalBorder, ScrollSensitivity, Shadow}; use webrender_api::{MixBlendMode, ScrollSensitivity, Shadow};
use webrender_api::{StickyOffsetBounds, TransformStyle}; use webrender_api::{StickyOffsetBounds, TransformStyle};
pub use style::dom::OpaqueNode; pub use style::dom::OpaqueNode;
@ -373,14 +374,14 @@ impl ClipScrollNode {
/// One drawing command in the list. /// One drawing command in the list.
#[derive(Clone, Serialize)] #[derive(Clone, Serialize)]
pub enum DisplayItem { pub enum DisplayItem {
SolidColor(Box<SolidColorDisplayItem>), Rectangle(Box<CommonDisplayItem<wr::RectangleDisplayItem>>),
Text(Box<TextDisplayItem>), Text(Box<CommonDisplayItem<wr::TextDisplayItem, Vec<GlyphInstance>>>),
Image(Box<ImageDisplayItem>), Image(Box<CommonDisplayItem<wr::ImageDisplayItem>>),
Border(Box<BorderDisplayItem>), Border(Box<CommonDisplayItem<wr::BorderDisplayItem, Vec<GradientStop>>>),
Gradient(Box<GradientDisplayItem>), Gradient(Box<CommonDisplayItem<wr::GradientDisplayItem, Vec<GradientStop>>>),
RadialGradient(Box<RadialGradientDisplayItem>), RadialGradient(Box<CommonDisplayItem<wr::RadialGradientDisplayItem, Vec<GradientStop>>>),
Line(Box<LineDisplayItem>), Line(Box<LineDisplayItem>),
BoxShadow(Box<BoxShadowDisplayItem>), BoxShadow(Box<CommonDisplayItem<wr::BoxShadowDisplayItem>>),
PushTextShadow(Box<PushTextShadowDisplayItem>), PushTextShadow(Box<PushTextShadowDisplayItem>),
PopAllTextShadows(Box<PopAllTextShadowsDisplayItem>), PopAllTextShadows(Box<PopAllTextShadowsDisplayItem>),
Iframe(Box<IframeDisplayItem>), Iframe(Box<IframeDisplayItem>),
@ -443,8 +444,9 @@ impl BaseDisplayItem {
clip_rect: LayoutRect::max_rect(), clip_rect: LayoutRect::max_rect(),
section: DisplayListSection::Content, section: DisplayListSection::Content,
stacking_context_id: StackingContextId::root(), stacking_context_id: StackingContextId::root(),
clipping_and_scrolling: clipping_and_scrolling: ClippingAndScrolling::simple(
ClippingAndScrolling::simple(ClipScrollNodeIndex::root_scroll_node()), ClipScrollNodeIndex::root_scroll_node(),
),
} }
} }
} }
@ -579,7 +581,8 @@ impl ClippingRegion {
pub fn translate(&self, delta: &LayoutVector2D) -> ClippingRegion { pub fn translate(&self, delta: &LayoutVector2D) -> ClippingRegion {
ClippingRegion { ClippingRegion {
main: self.main.translate(delta), main: self.main.translate(delta),
complex: self.complex complex: self
.complex
.iter() .iter()
.map(|complex| ComplexClipRegion { .map(|complex| ComplexClipRegion {
rect: complex.rect.translate(delta), rect: complex.rect.translate(delta),
@ -624,11 +627,13 @@ impl CompletelyEncloses for ComplexClipRegion {
fn completely_encloses(&self, other: &Self) -> bool { fn completely_encloses(&self, other: &Self) -> bool {
let left = self.radii.top_left.width.max(self.radii.bottom_left.width); let left = self.radii.top_left.width.max(self.radii.bottom_left.width);
let top = self.radii.top_left.height.max(self.radii.top_right.height); let top = self.radii.top_left.height.max(self.radii.top_right.height);
let right = self.radii let right = self
.radii
.top_right .top_right
.width .width
.max(self.radii.bottom_right.width); .max(self.radii.bottom_right.width);
let bottom = self.radii let bottom = self
.radii
.bottom_left .bottom_left
.height .height
.max(self.radii.bottom_right.height); .max(self.radii.bottom_right.height);
@ -639,8 +644,10 @@ impl CompletelyEncloses for ComplexClipRegion {
self.rect.size.height - top - bottom, self.rect.size.height - top - bottom,
), ),
); );
interior.origin.x <= other.rect.origin.x && interior.origin.y <= other.rect.origin.y && interior.origin.x <= other.rect.origin.x &&
interior.max_x() >= other.rect.max_x() && interior.max_y() >= other.rect.max_y() interior.origin.y <= other.rect.origin.y &&
interior.max_x() >= other.rect.max_x() &&
interior.max_y() >= other.rect.max_y()
} }
} }
@ -656,29 +663,6 @@ pub struct DisplayItemMetadata {
pub pointing: Option<u16>, pub pointing: Option<u16>,
} }
/// Paints a solid color.
#[derive(Clone, Serialize)]
pub struct SolidColorDisplayItem {
/// Fields common to all display items.
pub base: BaseDisplayItem,
/// The color.
pub color: ColorF,
}
/// Paints text.
#[derive(Clone, Serialize)]
pub struct TextDisplayItem {
/// Fields common to all display items.
pub base: BaseDisplayItem,
/// A collection of (non-whitespace) glyphs to be displayed.
pub glyphs: Vec<GlyphInstance>,
/// Reference to the font to be used.
pub font_key: FontInstanceKey,
/// The color of the text.
pub text_color: ColorF,
}
#[derive(Clone, Eq, PartialEq, Serialize)] #[derive(Clone, Eq, PartialEq, Serialize)]
pub enum TextOrientation { pub enum TextOrientation {
Upright, Upright,
@ -686,26 +670,6 @@ pub enum TextOrientation {
SidewaysRight, SidewaysRight,
} }
/// Paints an image.
#[derive(Clone, Serialize)]
pub struct ImageDisplayItem {
pub base: BaseDisplayItem,
pub id: ImageKey,
/// The dimensions to which the image display item should be stretched. If this is smaller than
/// the bounds of this display item, then the image will be repeated in the appropriate
/// direction to tile the entire bounds.
pub stretch_size: LayoutSize,
/// The amount of space to add to the right and bottom part of each tile, when the image
/// is tiled.
pub tile_spacing: LayoutSize,
/// The algorithm we should use to stretch the image. See `image_rendering` in CSS-IMAGES-3 §
/// 5.3.
pub image_rendering: ImageRendering,
}
/// Paints an iframe. /// Paints an iframe.
#[derive(Clone, Serialize)] #[derive(Clone, Serialize)]
pub struct IframeDisplayItem { pub struct IframeDisplayItem {
@ -713,118 +677,6 @@ pub struct IframeDisplayItem {
pub iframe: PipelineId, pub iframe: PipelineId,
} }
/// Paints a gradient.
#[derive(Clone, Serialize)]
pub struct Gradient {
/// The start point of the gradient (computed during display list construction).
pub start_point: LayoutPoint,
/// The end point of the gradient (computed during display list construction).
pub end_point: LayoutPoint,
/// A list of color stops.
pub stops: Vec<GradientStop>,
/// Whether the gradient is repeated or clamped.
pub extend_mode: ExtendMode,
}
#[derive(Clone, Serialize)]
pub struct GradientDisplayItem {
/// Fields common to all display item.
pub base: BaseDisplayItem,
/// Contains all gradient data. Included start, end point and color stops.
pub gradient: Gradient,
/// The size of a single gradient tile.
///
/// The gradient may fill an entire element background
/// but it can be composed from many smaller copys of
/// the same gradient.
///
/// Without tiles, the tile will be the same size as the background.
pub tile: LayoutSize,
pub tile_spacing: LayoutSize,
}
/// Paints a radial gradient.
#[derive(Clone, Serialize)]
pub struct RadialGradient {
/// The center point of the gradient.
pub center: LayoutPoint,
/// The radius of the gradient with an x and an y component.
pub radius: LayoutSize,
/// A list of color stops.
pub stops: Vec<GradientStop>,
/// Whether the gradient is repeated or clamped.
pub extend_mode: ExtendMode,
}
#[derive(Clone, Serialize)]
pub struct RadialGradientDisplayItem {
/// Fields common to all display item.
pub base: BaseDisplayItem,
/// Contains all gradient data.
pub gradient: RadialGradient,
/// The size of a single gradient tile.
///
/// The gradient may fill an entire element background
/// but it can be composed from many smaller copys of
/// the same gradient.
///
/// Without tiles, the tile will be the same size as the background.
pub tile: LayoutSize,
pub tile_spacing: LayoutSize,
}
/// A border that is made of linear gradient
#[derive(Clone, Serialize)]
pub struct GradientBorder {
/// The gradient info that this border uses, border-image-source.
pub gradient: Gradient,
/// Outsets for the border, as per border-image-outset.
pub outset: SideOffsets2D<f32>,
}
/// A border that is made of radial gradient
#[derive(Clone, Serialize)]
pub struct RadialGradientBorder {
/// The gradient info that this border uses, border-image-source.
pub gradient: RadialGradient,
/// Outsets for the border, as per border-image-outset.
pub outset: SideOffsets2D<f32>,
}
/// Specifies the type of border
#[derive(Clone, Serialize)]
pub enum BorderDetails {
Normal(NormalBorder),
Image(NinePatchBorder),
Gradient(GradientBorder),
RadialGradient(RadialGradientBorder),
}
/// Paints a border.
#[derive(Clone, Serialize)]
pub struct BorderDisplayItem {
/// Fields common to all display items.
pub base: BaseDisplayItem,
/// Border widths.
pub border_widths: BorderWidths,
/// Details for specific border type
pub details: BorderDetails,
}
/// Paints a line segment. /// Paints a line segment.
#[derive(Clone, Serialize)] #[derive(Clone, Serialize)]
pub struct LineDisplayItem { pub struct LineDisplayItem {
@ -837,32 +689,27 @@ pub struct LineDisplayItem {
pub style: LineStyle, pub style: LineStyle,
} }
/// Paints a box shadow per CSS-BACKGROUNDS.
#[derive(Clone, Serialize)] #[derive(Clone, Serialize)]
pub struct BoxShadowDisplayItem { pub struct CommonDisplayItem<T, U = ()> {
/// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
pub item: T,
pub data: U,
}
/// The dimensions of the box that we're placing a shadow around. impl<T> CommonDisplayItem<T> {
pub box_bounds: LayoutRect, pub fn new(base: BaseDisplayItem, item: T) -> Box<CommonDisplayItem<T>> {
Box::new(CommonDisplayItem {
base,
item,
data: (),
})
}
}
/// The offset of this shadow from the box. impl<T, U> CommonDisplayItem<T, U> {
pub offset: LayoutVector2D, pub fn with_data(base: BaseDisplayItem, item: T, data: U) -> Box<CommonDisplayItem<T, U>> {
Box::new(CommonDisplayItem { base, item, data })
/// The color of this shadow. }
pub color: ColorF,
/// The blur radius for this shadow.
pub blur_radius: f32,
/// The spread radius of this shadow.
pub spread_radius: f32,
/// The border radius of this shadow.
pub border_radius: BorderRadius,
/// How we should clip the result.
pub clip_mode: BoxShadowClipMode,
} }
/// Defines a text shadow that affects all items until the paired PopTextShadow. /// Defines a text shadow that affects all items until the paired PopTextShadow.
@ -912,7 +759,7 @@ pub struct DefineClipScrollNodeItem {
impl DisplayItem { impl DisplayItem {
pub fn base(&self) -> &BaseDisplayItem { pub fn base(&self) -> &BaseDisplayItem {
match *self { match *self {
DisplayItem::SolidColor(ref solid_color) => &solid_color.base, DisplayItem::Rectangle(ref rect) => &rect.base,
DisplayItem::Text(ref text) => &text.base, DisplayItem::Text(ref text) => &text.base,
DisplayItem::Image(ref image_item) => &image_item.base, DisplayItem::Image(ref image_item) => &image_item.base,
DisplayItem::Border(ref border) => &border.base, DisplayItem::Border(ref border) => &border.base,
@ -976,13 +823,7 @@ impl fmt::Debug for DisplayItem {
f, f,
"{} @ {:?} {:?}", "{} @ {:?} {:?}",
match *self { match *self {
DisplayItem::SolidColor(ref solid_color) => format!( DisplayItem::Rectangle(_) => "Rectangle".to_owned(),
"SolidColor rgba({}, {}, {}, {})",
solid_color.color.r,
solid_color.color.g,
solid_color.color.b,
solid_color.color.a
),
DisplayItem::Text(_) => "Text".to_owned(), DisplayItem::Text(_) => "Text".to_owned(),
DisplayItem::Image(_) => "Image".to_owned(), DisplayItem::Image(_) => "Image".to_owned(),
DisplayItem::Border(_) => "Border".to_owned(), DisplayItem::Border(_) => "Border".to_owned(),
@ -1032,8 +873,18 @@ impl SimpleMatrixDetection for LayoutTransform {
#[inline] #[inline]
fn is_identity_or_simple_translation(&self) -> bool { fn is_identity_or_simple_translation(&self) -> bool {
let (_0, _1) = (0.0, 1.0); let (_0, _1) = (0.0, 1.0);
self.m11 == _1 && self.m12 == _0 && self.m13 == _0 && self.m14 == _0 && self.m21 == _0 && self.m11 == _1 &&
self.m22 == _1 && self.m23 == _0 && self.m24 == _0 && self.m31 == _0 && self.m12 == _0 &&
self.m32 == _0 && self.m33 == _1 && self.m34 == _0 && self.m44 == _1 self.m13 == _0 &&
self.m14 == _0 &&
self.m21 == _0 &&
self.m22 == _1 &&
self.m23 == _0 &&
self.m24 == _0 &&
self.m31 == _0 &&
self.m32 == _0 &&
self.m33 == _1 &&
self.m34 == _0 &&
self.m44 == _1
} }
} }

View file

@ -7,9 +7,8 @@
// This might be achieved by sharing types between WR and Servo display lists, or // This might be achieved by sharing types between WR and Servo display lists, or
// completely converting layout to directly generate WebRender display lists, for example. // completely converting layout to directly generate WebRender display lists, for example.
use display_list::items::{BorderDetails, ClipScrollNode, ClipScrollNodeIndex, ClipScrollNodeType}; use display_list::items::{ClipScrollNode, ClipScrollNodeIndex, ClipScrollNodeType};
use display_list::items::{DisplayItem, DisplayList, StackingContextType}; use display_list::items::{DisplayItem, DisplayList, StackingContextType};
use euclid::SideOffsets2D;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder, GlyphRasterSpace}; use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder, GlyphRasterSpace};
use webrender_api::LayoutPoint; use webrender_api::LayoutPoint;
@ -104,105 +103,93 @@ impl WebRenderDisplayItemConverter for DisplayItem {
} }
match *self { match *self {
DisplayItem::SolidColor(ref item) => { DisplayItem::Rectangle(ref item) => {
builder.push_rect(&self.prim_info(), item.color); builder.push_rect(&self.prim_info(), item.item.color);
}, },
DisplayItem::Text(ref item) => { DisplayItem::Text(ref item) => {
builder.push_text( builder.push_text(
&self.prim_info(), &self.prim_info(),
&item.glyphs, &item.data,
item.font_key, item.item.font_key,
item.text_color, item.item.color,
None, item.item.glyph_options,
); );
}, },
DisplayItem::Image(ref item) => { DisplayItem::Image(ref item) => {
if item.stretch_size.width > 0.0 && item.stretch_size.height > 0.0 {
builder.push_image( builder.push_image(
&self.prim_info(), &self.prim_info(),
item.stretch_size, item.item.stretch_size,
item.tile_spacing, item.item.tile_spacing,
item.image_rendering, item.item.image_rendering,
webrender_api::AlphaType::PremultipliedAlpha, item.item.alpha_type,
item.id, item.item.image_key,
); );
}
}, },
DisplayItem::Border(ref item) => { DisplayItem::Border(ref item) => {
let details = match item.details { if item.data.is_empty() {
BorderDetails::Normal(ref border) => { builder.push_border(&self.prim_info(), item.item.widths, item.item.details);
webrender_api::BorderDetails::Normal(*border) } else {
let mut details = item.item.details.clone();
match &mut details {
webrender_api::BorderDetails::NinePatch(
webrender_api::NinePatchBorder {
source:
webrender_api::NinePatchBorderSource::Gradient(ref mut gradient),
..
}, },
BorderDetails::Image(ref image) => { ) => {
webrender_api::BorderDetails::NinePatch(*image) *gradient = builder.create_gradient(
gradient.start_point,
gradient.end_point,
item.data.clone(),
gradient.extend_mode,
);
},
webrender_api::BorderDetails::NinePatch(
webrender_api::NinePatchBorder {
source:
webrender_api::NinePatchBorderSource::RadialGradient(gradient),
..
},
) => {
*gradient = builder.create_radial_gradient(
gradient.center,
gradient.radius,
item.data.clone(),
gradient.extend_mode,
)
},
_ => unreachable!(),
}
builder.push_border(&self.prim_info(), item.item.widths, details);
} }
BorderDetails::Gradient(ref gradient) => {
let wr_gradient = builder.create_gradient(
gradient.gradient.start_point,
gradient.gradient.end_point,
gradient.gradient.stops.clone(),
gradient.gradient.extend_mode,
);
let details = webrender_api::NinePatchBorder {
source: webrender_api::NinePatchBorderSource::Gradient(wr_gradient),
width: 0,
height: 0,
slice: SideOffsets2D::zero(),
fill: false,
repeat_horizontal: webrender_api::RepeatMode::Stretch,
repeat_vertical: webrender_api::RepeatMode::Stretch,
outset: gradient.outset,
};
webrender_api::BorderDetails::NinePatch(details)
},
BorderDetails::RadialGradient(ref gradient) => {
let wr_gradient = builder.create_radial_gradient(
gradient.gradient.center,
gradient.gradient.radius,
gradient.gradient.stops.clone(),
gradient.gradient.extend_mode,
);
let details = webrender_api::NinePatchBorder {
source: webrender_api::NinePatchBorderSource::RadialGradient(wr_gradient),
width: 0,
height: 0,
slice: SideOffsets2D::zero(),
fill: false,
repeat_horizontal: webrender_api::RepeatMode::Stretch,
repeat_vertical: webrender_api::RepeatMode::Stretch,
outset: gradient.outset,
};
webrender_api::BorderDetails::NinePatch(details)
},
};
builder.push_border(&self.prim_info(), item.border_widths, details);
}, },
DisplayItem::Gradient(ref item) => { DisplayItem::Gradient(ref item) => {
let gradient = builder.create_gradient( let gradient = builder.create_gradient(
item.gradient.start_point, item.item.gradient.start_point,
item.gradient.end_point, item.item.gradient.end_point,
item.gradient.stops.clone(), item.data.clone(),
item.gradient.extend_mode, item.item.gradient.extend_mode,
);
builder.push_gradient(
&self.prim_info(),
gradient,
item.item.tile_size,
item.item.tile_spacing,
); );
builder.push_gradient(&self.prim_info(), gradient, item.tile, item.tile_spacing);
}, },
DisplayItem::RadialGradient(ref item) => { DisplayItem::RadialGradient(ref item) => {
let gradient = builder.create_radial_gradient( let gradient = builder.create_radial_gradient(
item.gradient.center, item.item.gradient.center,
item.gradient.radius, item.item.gradient.radius,
item.gradient.stops.clone(), item.data.clone(),
item.gradient.extend_mode, item.item.gradient.extend_mode,
); );
builder.push_radial_gradient( builder.push_radial_gradient(
&self.prim_info(), &self.prim_info(),
gradient, gradient,
item.tile, item.item.tile_size,
item.tile_spacing, item.item.tile_spacing,
); );
}, },
DisplayItem::Line(ref item) => { DisplayItem::Line(ref item) => {
@ -218,13 +205,13 @@ impl WebRenderDisplayItemConverter for DisplayItem {
DisplayItem::BoxShadow(ref item) => { DisplayItem::BoxShadow(ref item) => {
builder.push_box_shadow( builder.push_box_shadow(
&self.prim_info(), &self.prim_info(),
item.box_bounds, item.item.box_bounds,
item.offset, item.item.offset,
item.color, item.item.color,
item.blur_radius, item.item.blur_radius,
item.spread_radius, item.item.spread_radius,
item.border_radius, item.item.border_radius,
item.clip_mode, item.item.clip_mode,
); );
}, },
DisplayItem::PushTextShadow(ref item) => { DisplayItem::PushTextShadow(ref item) => {
@ -310,7 +297,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
}, },
ClipScrollNodeType::Placeholder => { ClipScrollNodeType::Placeholder => {
unreachable!("Found DefineClipScrollNode for Placeholder type node."); unreachable!("Found DefineClipScrollNode for Placeholder type node.");
} },
}; };
clip_ids[item.node_index.to_index()] = Some(webrender_id); clip_ids[item.node_index.to_index()] = Some(webrender_id);