Move DL items from gfx to layout

Implement corner clipping.
Remove PixelFormat from WebrenderImageInfo.
Use WebRender text shadow.
Remove MallocSizeOf and Deserialize for DL items.

Closes #19649, #19680, #19802
This commit is contained in:
Pyfisch 2018-03-24 21:50:15 +01:00
parent 782d4d4af6
commit c0be925bed
26 changed files with 417 additions and 287 deletions

6
Cargo.lock generated
View file

@ -1022,8 +1022,6 @@ dependencies = [
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1", "malloc_size_of 0.0.1",
"malloc_size_of_derive 0.0.1",
"msg 0.0.1",
"net_traits 0.0.1", "net_traits 0.0.1",
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"range 0.0.1", "range 0.0.1",
@ -1032,7 +1030,6 @@ dependencies = [
"servo_allocator 0.0.1", "servo_allocator 0.0.1",
"servo_arc 0.1.1", "servo_arc 0.1.1",
"servo_atoms 0.0.1", "servo_atoms 0.0.1",
"servo_geometry 0.0.1",
"servo_url 0.0.1", "servo_url 0.0.1",
"simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1723,12 +1720,11 @@ dependencies = [
name = "metrics_tests" name = "metrics_tests"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"gfx 0.0.1",
"gfx_traits 0.0.1", "gfx_traits 0.0.1",
"ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", "ipc-channel 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"layout 0.0.1",
"metrics 0.0.1", "metrics 0.0.1",
"msg 0.0.1", "msg 0.0.1",
"net_traits 0.0.1",
"profile_traits 0.0.1", "profile_traits 0.0.1",
"servo_url 0.0.1", "servo_url 0.0.1",
"time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -28,15 +28,12 @@ lazy_static = "1"
libc = "0.2" libc = "0.2"
log = "0.3.5" log = "0.3.5"
malloc_size_of = { path = "../malloc_size_of" } malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
msg = {path = "../msg"}
net_traits = {path = "../net_traits"} net_traits = {path = "../net_traits"}
ordered-float = "0.4" ordered-float = "0.4"
range = {path = "../range"} range = {path = "../range"}
serde = "1.0" serde = "1.0"
servo_arc = {path = "../servo_arc"} servo_arc = {path = "../servo_arc"}
servo_atoms = {path = "../atoms"} servo_atoms = {path = "../atoms"}
servo_geometry = {path = "../geometry"}
servo_url = {path = "../url"} servo_url = {path = "../url"}
smallvec = "0.6" smallvec = "0.6"
style = {path = "../style"} style = {path = "../style"}

View file

@ -43,14 +43,11 @@ extern crate libc;
extern crate log; extern crate log;
#[cfg_attr(target_os = "windows", macro_use)] #[cfg_attr(target_os = "windows", macro_use)]
extern crate malloc_size_of; extern crate malloc_size_of;
#[macro_use] extern crate malloc_size_of_derive;
extern crate msg;
extern crate net_traits; extern crate net_traits;
extern crate ordered_float; extern crate ordered_float;
extern crate range; extern crate range;
#[macro_use] extern crate serde; #[macro_use] extern crate serde;
extern crate servo_arc; extern crate servo_arc;
extern crate servo_geometry;
extern crate servo_url; extern crate servo_url;
#[macro_use] extern crate servo_atoms; #[macro_use] extern crate servo_atoms;
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
@ -66,9 +63,6 @@ extern crate xi_unicode;
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
extern crate xml5ever; extern crate xml5ever;
#[deny(unsafe_code)]
pub mod display_list;
// Fonts // Fonts
#[macro_use] pub mod font; #[macro_use] pub mod font;
pub mod font_cache_thread; pub mod font_cache_thread;

View file

@ -2,7 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#[derive(Clone, Debug, MallocSizeOf)] use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
#[derive(Clone, Debug)]
pub struct FontContextHandle { pub struct FontContextHandle {
ctx: () ctx: ()
} }
@ -13,3 +15,9 @@ impl FontContextHandle {
FontContextHandle { ctx: () } FontContextHandle { ctx: () }
} }
} }
impl MallocSizeOf for FontContextHandle {
fn size_of(&self, _: &mut MallocSizeOfOps) -> usize {
0
}
}

View file

@ -5,9 +5,9 @@
//! CSS transitions and animations. //! CSS transitions and animations.
use context::LayoutContext; use context::LayoutContext;
use display_list::items::OpaqueNode;
use flow::{Flow, GetBaseFlow}; use flow::{Flow, GetBaseFlow};
use fnv::FnvHashMap; use fnv::FnvHashMap;
use gfx::display_list::OpaqueNode;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use opaque_node::OpaqueNodeMethods; use opaque_node::OpaqueNodeMethods;

View file

@ -32,13 +32,13 @@ use context::LayoutContext;
use display_list::{BlockFlowDisplayListBuilding, BorderPaintingMode}; use display_list::{BlockFlowDisplayListBuilding, BorderPaintingMode};
use display_list::{DisplayListBuildState, StackingContextCollectionFlags}; use display_list::{DisplayListBuildState, StackingContextCollectionFlags};
use display_list::StackingContextCollectionState; use display_list::StackingContextCollectionState;
use display_list::items::DisplayListSection;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use floats::{ClearType, FloatKind, Floats, PlacementInfo}; use floats::{ClearType, FloatKind, Floats, PlacementInfo};
use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag, GetBaseFlow}; use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag, GetBaseFlow};
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow, FragmentationContext, FlowFlags}; use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow, FragmentationContext, FlowFlags};
use flow_list::FlowList; use flow_list::FlowList;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow, FragmentFlags}; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow, FragmentFlags};
use gfx::display_list::DisplayListSection;
use gfx_traits::print_tree::PrintTree; use gfx_traits::print_tree::PrintTree;
use incremental::RelayoutMode; use incremental::RelayoutMode;
use layout_debug; use layout_debug;

View file

@ -17,6 +17,7 @@ use ServoArc;
use block::BlockFlow; use block::BlockFlow;
use context::{LayoutContext, with_thread_local_font_context}; use context::{LayoutContext, with_thread_local_font_context};
use data::{LayoutDataFlags, LayoutData}; use data::{LayoutDataFlags, LayoutData};
use display_list::items::OpaqueNode;
use flex::FlexFlow; use flex::FlexFlow;
use floats::FloatKind; use floats::FloatKind;
use flow::{AbsoluteDescendants, Flow, FlowClass, GetBaseFlow, ImmutableFlowUtils}; use flow::{AbsoluteDescendants, Flow, FlowClass, GetBaseFlow, ImmutableFlowUtils};
@ -27,7 +28,6 @@ use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo, FragmentFlags
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo}; use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo}; use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use fragment::WhitespaceStrippingResult; use fragment::WhitespaceStrippingResult;
use gfx::display_list::OpaqueNode;
use inline::{InlineFlow, InlineFragmentNodeInfo, InlineFragmentNodeFlags}; use inline::{InlineFlow, InlineFragmentNodeInfo, InlineFragmentNodeFlags};
use linked_list::prepend_from; use linked_list::prepend_from;
use list_item::{ListItemFlow, ListStyleTypeContent}; use list_item::{ListItemFlow, ListStyleTypeContent};

View file

@ -4,8 +4,8 @@
//! Data needed by the layout thread. //! Data needed by the layout thread.
use display_list::items::{WebRenderImageInfo, OpaqueNode};
use fnv::FnvHasher; use fnv::FnvHasher;
use gfx::display_list::{WebRenderImageInfo, OpaqueNode};
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context::FontContext; use gfx::font_context::FontContext;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};

View file

@ -13,8 +13,8 @@
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 euclid::{Point2D, Rect, SideOffsets2D, Size2D, Vector2D}; use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Vector2D};
use gfx::display_list::{self, BorderDetails, WebRenderImageInfo};
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;
use style::computed_values::background_clip::single_value::T as BackgroundClip; use style::computed_values::background_clip::single_value::T as BackgroundClip;
@ -56,7 +56,9 @@ pub struct BackgroundPlacement {
pub tile_spacing: Size2D<Au>, pub tile_spacing: Size2D<Au>,
/// A clip area. While the background is rendered according to all the /// A clip area. While the background is rendered according to all the
/// measures above it is only shown within these bounds. /// measures above it is only shown within these bounds.
pub css_clip: Rect<Au>, pub clip_rect: Rect<Au>,
/// Rounded corners for the clip_rect.
pub clip_radii: BorderRadius,
/// Whether or not the background is fixed to the viewport. /// Whether or not the background is fixed to the viewport.
pub fixed: bool, pub fixed: bool,
} }
@ -149,6 +151,26 @@ fn compute_background_image_size(
} }
} }
pub fn compute_background_clip(
bg_clip: BackgroundClip,
absolute_bounds: Rect<Au>,
border: SideOffsets2D<Au>,
border_padding: SideOffsets2D<Au>,
border_radii: BorderRadius,
) -> (Rect<Au>, BorderRadius) {
match bg_clip {
BackgroundClip::BorderBox => (absolute_bounds, border_radii),
BackgroundClip::PaddingBox => (
absolute_bounds.inner_rect(border),
calculate_inner_border_radii(border_radii, border),
),
BackgroundClip::ContentBox => (
absolute_bounds.inner_rect(border_padding),
calculate_inner_border_radii(border_radii, border_padding),
),
}
}
/// Determines where to place an element background image or gradient. /// Determines where to place an element background image or gradient.
/// ///
/// Photos have their resolution as intrinsic size while gradients have /// Photos have their resolution as intrinsic size while gradients have
@ -160,6 +182,7 @@ pub fn compute_background_placement(
intrinsic_size: Option<Size2D<Au>>, intrinsic_size: Option<Size2D<Au>>,
border: SideOffsets2D<Au>, border: SideOffsets2D<Au>,
border_padding: SideOffsets2D<Au>, border_padding: SideOffsets2D<Au>,
border_radii: BorderRadius,
index: usize, index: usize,
) -> BackgroundPlacement { ) -> BackgroundPlacement {
let bg_attachment = *get_cyclic(&bg.background_attachment.0, index); let bg_attachment = *get_cyclic(&bg.background_attachment.0, index);
@ -170,11 +193,13 @@ pub fn compute_background_placement(
let bg_repeat = get_cyclic(&bg.background_repeat.0, index); let bg_repeat = get_cyclic(&bg.background_repeat.0, index);
let bg_size = *get_cyclic(&bg.background_size.0, index); let bg_size = *get_cyclic(&bg.background_size.0, index);
let css_clip = match bg_clip { let (clip_rect, clip_radii) = compute_background_clip(
BackgroundClip::BorderBox => absolute_bounds, bg_clip,
BackgroundClip::PaddingBox => absolute_bounds.inner_rect(border), absolute_bounds,
BackgroundClip::ContentBox => absolute_bounds.inner_rect(border_padding), border,
}; border_padding,
border_radii,
);
let mut fixed = false; let mut fixed = false;
let mut bounds = match bg_attachment { let mut bounds = match bg_attachment {
@ -202,8 +227,8 @@ pub fn compute_background_placement(
&mut tile_size.width, &mut tile_size.width,
&mut tile_spacing.width, &mut tile_spacing.width,
pos_x, pos_x,
css_clip.origin.x, clip_rect.origin.x,
css_clip.size.width, clip_rect.size.width,
); );
tile_image_axis( tile_image_axis(
bg_repeat.1, bg_repeat.1,
@ -212,15 +237,16 @@ pub fn compute_background_placement(
&mut tile_size.height, &mut tile_size.height,
&mut tile_spacing.height, &mut tile_spacing.height,
pos_y, pos_y,
css_clip.origin.y, clip_rect.origin.y,
css_clip.size.height, clip_rect.size.height,
); );
BackgroundPlacement { BackgroundPlacement {
bounds, bounds,
tile_size, tile_size,
tile_spacing, tile_spacing,
css_clip, clip_rect,
clip_radii,
fixed, fixed,
} }
} }
@ -508,7 +534,7 @@ pub fn convert_linear_gradient(
stops: &[GradientItem], stops: &[GradientItem],
direction: LineDirection, direction: LineDirection,
repeating: bool, repeating: bool,
) -> display_list::Gradient { ) -> Gradient {
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 {
@ -556,7 +582,7 @@ 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);
display_list::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: stops, stops: stops,
@ -570,7 +596,7 @@ pub fn convert_radial_gradient(
shape: EndingShape, shape: EndingShape,
center: Position, center: Position,
repeating: bool, repeating: bool,
) -> display_list::RadialGradient { ) -> RadialGradient {
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),
@ -593,7 +619,7 @@ pub fn convert_radial_gradient(
let stops = convert_gradient_stops(stops, radius.width); let stops = convert_gradient_stops(stops, radius.width);
display_list::RadialGradient { RadialGradient {
center: center.to_layout(), center: center.to_layout(),
radius: radius.to_layout(), radius: radius.to_layout(),
stops: stops, stops: stops,

View file

@ -17,8 +17,18 @@ use context::LayoutContext;
use display_list::ToLayout; use display_list::ToLayout;
use display_list::background::{build_border_radius, build_image_border_details}; use display_list::background::{build_border_radius, build_image_border_details};
use display_list::background::{calculate_inner_border_radii, compute_background_placement}; use display_list::background::{calculate_inner_border_radii, compute_background_placement};
use display_list::background::{convert_linear_gradient, convert_radial_gradient}; use display_list::background::{convert_radial_gradient, convert_linear_gradient};
use display_list::background::{get_cyclic, simple_normal_border}; use display_list::background::{get_cyclic, simple_normal_border};
use display_list::items::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR};
use display_list::items::{BoxShadowDisplayItem, ClipScrollNode};
use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
use display_list::items::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList};
use display_list::items::{DisplayListSection, GradientBorder, GradientDisplayItem};
use display_list::items::{IframeDisplayItem, ImageDisplayItem, LineDisplayItem, OpaqueNode};
use display_list::items::{PopAllTextShadowsDisplayItem, PushTextShadowDisplayItem};
use display_list::items::{RadialGradientBorder, RadialGradientDisplayItem, SolidColorDisplayItem};
use display_list::items::{StackingContext, StackingContextType, StickyFrameData, TextDisplayItem};
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;
use flow::{BaseFlow, Flow, FlowFlags}; use flow::{BaseFlow, Flow, FlowFlags};
@ -26,17 +36,6 @@ use flow_ref::FlowRef;
use fnv::FnvHashMap; use fnv::FnvHashMap;
use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ScannedTextFragmentInfo}; use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ScannedTextFragmentInfo};
use fragment::SpecificFragmentInfo; use fragment::SpecificFragmentInfo;
use gfx::display_list;
use gfx::display_list::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR};
use gfx::display_list::{BoxShadowDisplayItem, ClipScrollNode};
use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
use gfx::display_list::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList};
use gfx::display_list::{DisplayListSection, GradientDisplayItem, IframeDisplayItem};
use gfx::display_list::{ImageDisplayItem, LineDisplayItem, OpaqueNode};
use gfx::display_list::{PopAllTextShadowsDisplayItem, PushTextShadowDisplayItem};
use gfx::display_list::{RadialGradientDisplayItem, SolidColorDisplayItem, StackingContext};
use gfx::display_list::{StackingContextType, StickyFrameData, TextDisplayItem, TextOrientation};
use gfx::display_list::WebRenderImageInfo;
use gfx::text::TextRun; use gfx::text::TextRun;
use gfx::text::glyph::ByteIndex; use gfx::text::glyph::ByteIndex;
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId}; use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
@ -45,7 +44,6 @@ use ipc_channel::ipc;
use list_item::ListItemFlow; use list_item::ListItemFlow;
use model::MaybeAuto; use model::MaybeAuto;
use msg::constellation_msg::{BrowsingContextId, PipelineId}; use msg::constellation_msg::{BrowsingContextId, PipelineId};
use net_traits::image::base::PixelFormat;
use net_traits::image_cache::UsePlaceholder; use net_traits::image_cache::UsePlaceholder;
use range::Range; use range::Range;
use servo_config::opts; use servo_config::opts;
@ -61,7 +59,7 @@ use style::computed_values::pointer_events::T as PointerEvents;
use style::computed_values::position::T as StylePosition; use style::computed_values::position::T as StylePosition;
use style::computed_values::visibility::T as Visibility; use style::computed_values::visibility::T as Visibility;
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect}; use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect};
use style::properties::{ComputedValues, style_structs}; use style::properties::{style_structs, ComputedValues};
use style::servo::restyle_damage::ServoRestyleDamage; use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::{Either, RGBA}; use style::values::{Either, RGBA};
use style::values::computed::Gradient; use style::values::computed::Gradient;
@ -240,7 +238,7 @@ impl StackingContextCollectionState {
let mut stacking_context_info = FnvHashMap::default(); let mut stacking_context_info = FnvHashMap::default();
stacking_context_info.insert( stacking_context_info.insert(
StackingContextId::root(), StackingContextId::root(),
StackingContextInfo::new(StackingContextId::root()) StackingContextInfo::new(StackingContextId::root()),
); );
StackingContextCollectionState { StackingContextCollectionState {
@ -261,7 +259,7 @@ impl StackingContextCollectionState {
fn allocate_stacking_context_info( fn allocate_stacking_context_info(
&mut self, &mut self,
stacking_context_type: StackingContextType stacking_context_type: StackingContextType,
) -> StackingContextId { ) -> StackingContextId {
let next_stacking_context_id = self.next_stacking_context_id.next(); let next_stacking_context_id = self.next_stacking_context_id.next();
let allocated_id = let allocated_id =
@ -274,7 +272,7 @@ impl StackingContextCollectionState {
self.stacking_context_info.insert( self.stacking_context_info.insert(
allocated_id, allocated_id,
StackingContextInfo::new(real_stacking_context_id) StackingContextInfo::new(real_stacking_context_id),
); );
allocated_id allocated_id
@ -285,7 +283,11 @@ impl StackingContextCollectionState {
parent_id: StackingContextId, parent_id: StackingContextId,
stacking_context: StackingContext, stacking_context: StackingContext,
) { ) {
self.stacking_context_info.get_mut(&parent_id).unwrap().children.push(stacking_context); self.stacking_context_info
.get_mut(&parent_id)
.unwrap()
.children
.push(stacking_context);
} }
fn add_clip_scroll_node(&mut self, clip_scroll_node: ClipScrollNode) -> ClipScrollNodeIndex { fn add_clip_scroll_node(&mut self, clip_scroll_node: ClipScrollNode) -> ClipScrollNodeIndex {
@ -462,7 +464,9 @@ impl<'a> DisplayListBuildState<'a> {
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.remove(&stacking_context.id).unwrap(); let mut info = self.stacking_context_info
.remove(&stacking_context.id)
.unwrap();
info.children.sort(); info.children.sort();
@ -806,7 +810,13 @@ impl FragmentDisplayListBuilding for Fragment {
// XXXManishearth the below method should ideally use an iterator over // XXXManishearth the below method should ideally use an iterator over
// backgrounds // backgrounds
self.build_display_list_for_background_if_applicable_with_background( self.build_display_list_for_background_if_applicable_with_background(
state, style, background, background_color, display_list_section, absolute_bounds) state,
style,
background,
background_color,
display_list_section,
absolute_bounds,
)
} }
fn build_display_list_for_background_if_applicable_with_background( fn build_display_list_for_background_if_applicable_with_background(
@ -955,6 +965,9 @@ impl FragmentDisplayListBuilding for Fragment {
index: usize, index: usize,
) { ) {
debug!("(building display list) building background image"); debug!("(building display list) building background image");
if webrender_image.key.is_none() {
return;
}
let image = Size2D::new( let image = Size2D::new(
Au::from_px(webrender_image.width as i32), Au::from_px(webrender_image.width as i32),
@ -967,13 +980,21 @@ impl FragmentDisplayListBuilding for Fragment {
Some(image), Some(image),
style.logical_border_width().to_physical(style.writing_mode), style.logical_border_width().to_physical(style.writing_mode),
self.border_padding.to_physical(style.writing_mode), self.border_padding.to_physical(style.writing_mode),
build_border_radius(&absolute_bounds, style.get_border()),
index, index,
); );
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
if !placement.clip_radii.is_zero() {
let clip_id =
state.add_late_clip_node(placement.clip_rect.to_layout(), placement.clip_radii);
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
}
// Create the image display item. // Create the image display item.
let base = state.create_base_display_item( let base = state.create_base_display_item(
&placement.bounds, &placement.bounds,
&placement.css_clip, &placement.clip_rect,
self.node, self.node,
style.get_cursor(CursorKind::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
@ -982,11 +1003,13 @@ 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(Box::new(ImageDisplayItem {
base: base, base: base,
webrender_image: webrender_image, id: 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_inheritedbox().image_rendering.to_layout(), image_rendering: style.get_inheritedbox().image_rendering.to_layout(),
}))); })));
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
} }
fn get_webrender_image_for_paint_worklet( fn get_webrender_image_for_paint_worklet(
@ -1032,7 +1055,6 @@ impl FragmentDisplayListBuilding for Fragment {
let webrender_image = WebRenderImageInfo { let webrender_image = WebRenderImageInfo {
width: draw_result.width, width: draw_result.width,
height: draw_result.height, height: draw_result.height,
format: draw_result.format,
key: draw_result.image_key, key: draw_result.image_key,
}; };
@ -1066,12 +1088,20 @@ impl FragmentDisplayListBuilding for Fragment {
None, None,
style.logical_border_width().to_physical(style.writing_mode), style.logical_border_width().to_physical(style.writing_mode),
self.border_padding.to_physical(style.writing_mode), self.border_padding.to_physical(style.writing_mode),
build_border_radius(&absolute_bounds, style.get_border()),
index, index,
); );
let previous_clipping_and_scrolling = state.current_clipping_and_scrolling;
if !placement.clip_radii.is_zero() {
let clip_id =
state.add_late_clip_node(placement.clip_rect.to_layout(), placement.clip_radii);
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
}
let base = state.create_base_display_item( let base = state.create_base_display_item(
&placement.bounds, &placement.bounds,
&placement.css_clip, &placement.clip_rect,
self.node, self.node,
style.get_cursor(CursorKind::Default), style.get_cursor(CursorKind::Default),
display_list_section, display_list_section,
@ -1109,6 +1139,7 @@ impl FragmentDisplayListBuilding for Fragment {
}, },
}; };
state.add_display_item(display_item); state.add_display_item(display_item);
state.current_clipping_and_scrolling = previous_clipping_and_scrolling;
} }
fn build_display_list_for_box_shadow_if_applicable( fn build_display_list_for_box_shadow_if_applicable(
@ -1252,7 +1283,7 @@ impl FragmentDisplayListBuilding for Fragment {
Either::Second(Image::Gradient(ref gradient)) => { Either::Second(Image::Gradient(ref gradient)) => {
Some(match gradient.kind { Some(match gradient.kind {
GradientKind::Linear(angle_or_corner) => { GradientKind::Linear(angle_or_corner) => {
BorderDetails::Gradient(display_list::GradientBorder { BorderDetails::Gradient(GradientBorder {
gradient: convert_linear_gradient( gradient: convert_linear_gradient(
bounds.size, bounds.size,
&gradient.items[..], &gradient.items[..],
@ -1264,7 +1295,7 @@ impl FragmentDisplayListBuilding for Fragment {
}) })
}, },
GradientKind::Radial(shape, center, _angle) => { GradientKind::Radial(shape, center, _angle) => {
BorderDetails::RadialGradient(display_list::RadialGradientBorder { BorderDetails::RadialGradient(RadialGradientBorder {
gradient: convert_radial_gradient( gradient: convert_radial_gradient(
bounds.size, bounds.size,
&gradient.items[..], &gradient.items[..],
@ -1519,8 +1550,13 @@ impl FragmentDisplayListBuilding for Fragment {
clip: &Rect<Au>, clip: &Rect<Au>,
) { ) {
self.restyle_damage.remove(ServoRestyleDamage::REPAINT); self.restyle_damage.remove(ServoRestyleDamage::REPAINT);
self.build_display_list_no_damage(state, stacking_relative_border_box, self.build_display_list_no_damage(
border_painting_mode, display_list_section, clip) state,
stacking_relative_border_box,
border_painting_mode,
display_list_section,
clip,
)
} }
fn build_display_list_no_damage( fn build_display_list_no_damage(
@ -1662,16 +1698,12 @@ impl FragmentDisplayListBuilding for Fragment {
let create_base_display_item = |state: &mut DisplayListBuildState| { let create_base_display_item = |state: &mut DisplayListBuildState| {
// Adjust the clipping region as necessary to account for `border-radius`. // Adjust the clipping region as necessary to account for `border-radius`.
let radii = build_border_radius_for_inner_rect( let radii =
&stacking_relative_border_box, build_border_radius_for_inner_rect(&stacking_relative_border_box, &self.style);
&self.style
);
if !radii.is_zero() { if !radii.is_zero() {
let clip_id = state.add_late_clip_node( let clip_id =
stacking_relative_border_box.to_layout(), state.add_late_clip_node(stacking_relative_border_box.to_layout(), radii);
radii
);
state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id); state.current_clipping_and_scrolling = ClippingAndScrolling::simple(clip_id);
} }
@ -1779,22 +1811,24 @@ impl FragmentDisplayListBuilding for Fragment {
SpecificFragmentInfo::Image(ref image_fragment) => { SpecificFragmentInfo::Image(ref image_fragment) => {
// Place the image into the display list. // Place the image into the display list.
if let Some(ref image) = image_fragment.image { if let Some(ref image) = image_fragment.image {
let base = create_base_display_item(state); if let Some(id) = image.id {
state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem { let base = create_base_display_item(state);
base, state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
webrender_image: WebRenderImageInfo::from_image(image), base,
stretch_size: stacking_relative_content_box.size.to_layout(), id,
tile_spacing: LayoutSize::zero(), stretch_size: stacking_relative_content_box.size.to_layout(),
image_rendering: self.style.get_inheritedbox().image_rendering.to_layout(), tile_spacing: LayoutSize::zero(),
}))); image_rendering: self.style
.get_inheritedbox()
.image_rendering
.to_layout(),
})));
}
} }
}, },
SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => { SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
let computed_width = canvas_fragment_info.dom_width.to_px(); let image_key = match canvas_fragment_info.source {
let computed_height = canvas_fragment_info.dom_height.to_px(); CanvasFragmentSource::WebGL(image_key) => image_key,
let (image_key, format) = match canvas_fragment_info.source {
CanvasFragmentSource::WebGL(image_key) => (image_key, PixelFormat::BGRA8),
CanvasFragmentSource::Image(ref ipc_renderer) => match *ipc_renderer { CanvasFragmentSource::Image(ref ipc_renderer) => match *ipc_renderer {
Some(ref ipc_renderer) => { Some(ref ipc_renderer) => {
let ipc_renderer = ipc_renderer.lock().unwrap(); let ipc_renderer = ipc_renderer.lock().unwrap();
@ -1802,7 +1836,7 @@ impl FragmentDisplayListBuilding for Fragment {
ipc_renderer ipc_renderer
.send(CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender))) .send(CanvasMsg::FromLayout(FromLayoutMsg::SendData(sender)))
.unwrap(); .unwrap();
(receiver.recv().unwrap().image_key, PixelFormat::BGRA8) receiver.recv().unwrap().image_key
}, },
None => return, None => return,
}, },
@ -1811,12 +1845,7 @@ 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(Box::new(ImageDisplayItem {
base, base,
webrender_image: WebRenderImageInfo { id: image_key,
width: computed_width as u32,
height: computed_height as u32,
format: format,
key: Some(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,
@ -1942,12 +1971,14 @@ impl FragmentDisplayListBuilding for Fragment {
state.add_display_item(DisplayItem::PushTextShadow(Box::new( state.add_display_item(DisplayItem::PushTextShadow(Box::new(
PushTextShadowDisplayItem { PushTextShadowDisplayItem {
base: base.clone(), base: base.clone(),
blur_radius: shadow.blur.px(), shadow: webrender_api::Shadow {
offset: LayoutVector2D::new(shadow.horizontal.px(), shadow.vertical.px()), offset: LayoutVector2D::new(shadow.horizontal.px(), shadow.vertical.px()),
color: shadow color: shadow
.color .color
.unwrap_or(self.style().get_color().color) .unwrap_or(self.style().get_color().color)
.to_layout(), .to_layout(),
blur_radius: shadow.blur.px(),
},
}, },
))); )));
} }
@ -2146,7 +2177,8 @@ pub trait BlockFlowDisplayListBuilding {
&self, &self,
state: &mut DisplayListBuildState, state: &mut DisplayListBuildState,
background: &style_structs::Background, background: &style_structs::Background,
background_color: RGBA); background_color: RGBA,
);
fn stacking_context_type( fn stacking_context_type(
&self, &self,
@ -2679,8 +2711,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 = let stacking_relative_border_box = self.base
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(
state, state,
@ -2701,7 +2733,9 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
state: &mut DisplayListBuildState, state: &mut DisplayListBuildState,
border_painting_mode: BorderPaintingMode, border_painting_mode: BorderPaintingMode,
) { ) {
self.fragment.restyle_damage.remove(ServoRestyleDamage::REPAINT); self.fragment
.restyle_damage
.remove(ServoRestyleDamage::REPAINT);
self.build_display_list_for_block_no_damage(state, border_painting_mode); self.build_display_list_for_block_no_damage(state, border_painting_mode);
} }
@ -2709,23 +2743,28 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
&self, &self,
state: &mut DisplayListBuildState, state: &mut DisplayListBuildState,
background: &style_structs::Background, background: &style_structs::Background,
background_color: RGBA) { background_color: RGBA,
let stacking_relative_border_box = ) {
self.base.stacking_relative_border_box_for_display_list(&self.fragment); let stacking_relative_border_box = self.base
.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();
self.fragment.build_display_list_for_background_if_applicable_with_background( self.fragment
state, self.fragment.style(), background, background_color, .build_display_list_for_background_if_applicable_with_background(
background_border_section, &stacking_relative_border_box state,
) self.fragment.style(),
background,
background_color,
background_border_section,
&stacking_relative_border_box,
)
} }
#[inline] #[inline]
fn stacking_context_type( fn stacking_context_type(
&self, &self,
flags: StackingContextCollectionFlags, flags: StackingContextCollectionFlags,
) -> Option<StackingContextType>{ ) -> Option<StackingContextType> {
if flags.contains(StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT) { if flags.contains(StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT) {
return None; return None;
} }
@ -2734,7 +2773,10 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
return Some(StackingContextType::Real); return Some(StackingContextType::Real);
} }
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) { if self.base
.flags
.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED)
{
return Some(StackingContextType::PseudoPositioned); return Some(StackingContextType::PseudoPositioned);
} }
@ -2810,8 +2852,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 = let stacking_relative_border_box = self.base
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,
stacking_relative_border_box, stacking_relative_border_box,
@ -2866,8 +2908,9 @@ 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 = let stacking_relative_border_box = self.block_flow
self.block_flow.base.stacking_relative_border_box_for_display_list(marker); .base
.stacking_relative_border_box_for_display_list(marker);
marker.build_display_list( marker.build_display_list(
state, state,
stacking_relative_border_box, stacking_relative_border_box,
@ -3057,6 +3100,10 @@ impl IndexableText {
// TODO(#20020): access all elements // TODO(#20020): access all elements
let point = point_in_item + item[0].origin.to_vector(); let point = point_in_item + item[0].origin.to_vector();
let offset = point - item[0].baseline_origin; let offset = point - item[0].baseline_origin;
Some(item[0].text_run.range_index_of_advance(&item[0].range, offset.x)) Some(
item[0]
.text_run
.range_index_of_advance(&item[0].range, offset.x),
)
} }
} }

View file

@ -6,20 +6,17 @@
//! perform. Using a list instead of painting elements in immediate mode allows transforms, hit //! perform. Using a list instead of painting elements in immediate mode allows transforms, hit
//! testing, and invalidation to be performed using the same primitives as painting. It also allows //! testing, and invalidation to be performed using the same primitives as painting. It also allows
//! Servo to aggressively cull invisible and out-of-bounds painting elements, to reduce overdraw. //! Servo to aggressively cull invisible and out-of-bounds painting elements, to reduce overdraw.
//! Finally, display lists allow tiles to be farmed out onto multiple CPUs and painted in parallel
//! (although this benefit does not apply to GPU-based painting).
//! //!
//! Display items describe relatively high-level drawing operations (for example, entire borders //! Display items describe relatively high-level drawing operations (for example, entire borders
//! and shadows instead of lines and blur operations), to reduce the amount of allocation required. //! and shadows instead of lines and blur operations), to reduce the amount of allocation required.
//! They are therefore not exactly analogous to constructs like Skia pictures, which consist of //! They are therefore not exactly analogous to constructs like Skia pictures, which consist of
//! low-level drawing primitives. //! low-level drawing primitives.
use euclid::{Vector2D, TypedRect, SideOffsets2D}; use euclid::{SideOffsets2D, TypedRect, Vector2D};
use euclid::num::{One, Zero};
use gfx_traits::{self, StackingContextId}; use gfx_traits::{self, StackingContextId};
use gfx_traits::print_tree::PrintTree; use gfx_traits::print_tree::PrintTree;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use net_traits::image::base::{Image, PixelFormat}; use net_traits::image::base::Image;
use servo_geometry::MaxRect; use servo_geometry::MaxRect;
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::HashMap; use std::collections::HashMap;
@ -29,7 +26,7 @@ use webrender_api::{BorderRadius, BorderWidths, BoxShadowClipMode, ClipMode, Col
use webrender_api::{ComplexClipRegion, ExtendMode, ExternalScrollId, FilterOp, FontInstanceKey}; use webrender_api::{ComplexClipRegion, ExtendMode, ExternalScrollId, FilterOp, FontInstanceKey};
use webrender_api::{GlyphInstance, GradientStop, ImageBorder, ImageKey, ImageRendering}; use webrender_api::{GlyphInstance, GradientStop, ImageBorder, ImageKey, ImageRendering};
use webrender_api::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D}; use webrender_api::{LayoutPoint, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
use webrender_api::{LineStyle, MixBlendMode, NormalBorder, ScrollPolicy, ScrollSensitivity}; use webrender_api::{LineStyle, MixBlendMode, NormalBorder, ScrollPolicy, ScrollSensitivity, Shadow};
use webrender_api::{StickyOffsetBounds, TransformStyle}; use webrender_api::{StickyOffsetBounds, TransformStyle};
pub use style::dom::OpaqueNode; pub use style::dom::OpaqueNode;
@ -40,7 +37,7 @@ pub static BLUR_INFLATION_FACTOR: i32 = 3;
/// An index into the vector of ClipScrollNodes. During WebRender conversion these nodes /// An index into the vector of ClipScrollNodes. During WebRender conversion these nodes
/// are given ClipIds. /// are given ClipIds.
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] #[derive(Clone, Copy, Debug, PartialEq, Serialize)]
pub struct ClipScrollNodeIndex(pub usize); pub struct ClipScrollNodeIndex(pub usize);
impl ClipScrollNodeIndex { impl ClipScrollNodeIndex {
@ -60,7 +57,7 @@ impl ClipScrollNodeIndex {
} }
/// A set of indices into the clip scroll node vector for a given item. /// A set of indices into the clip scroll node vector for a given item.
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize)] #[derive(Clone, Copy, Debug, PartialEq, Serialize)]
pub struct ClippingAndScrolling { pub struct ClippingAndScrolling {
pub scrolling: ClipScrollNodeIndex, pub scrolling: ClipScrollNodeIndex,
pub clipping: Option<ClipScrollNodeIndex>, pub clipping: Option<ClipScrollNodeIndex>,
@ -74,7 +71,10 @@ impl ClippingAndScrolling {
} }
} }
pub fn new(scrolling: ClipScrollNodeIndex, clipping: ClipScrollNodeIndex) -> ClippingAndScrolling { pub fn new(
scrolling: ClipScrollNodeIndex,
clipping: ClipScrollNodeIndex,
) -> ClippingAndScrolling {
ClippingAndScrolling { ClippingAndScrolling {
scrolling, scrolling,
clipping: Some(clipping), clipping: Some(clipping),
@ -82,7 +82,7 @@ impl ClippingAndScrolling {
} }
} }
#[derive(Deserialize, MallocSizeOf, Serialize)] #[derive(Serialize)]
pub struct DisplayList { pub struct DisplayList {
pub list: Vec<DisplayItem>, pub list: Vec<DisplayItem>,
pub clip_scroll_nodes: Vec<ClipScrollNode>, pub clip_scroll_nodes: Vec<ClipScrollNode>,
@ -113,11 +113,12 @@ impl DisplayList {
print_tree.new_level("Items".to_owned()); print_tree.new_level("Items".to_owned());
for item in &self.list { for item in &self.list {
print_tree.add_item(format!("{:?} StackingContext: {:?} {:?}", print_tree.add_item(format!(
"{:?} StackingContext: {:?} {:?}",
item, item,
item.base().stacking_context_id, item.base().stacking_context_id,
item.clipping_and_scrolling()) item.clipping_and_scrolling()
); ));
} }
print_tree.end_level(); print_tree.end_level();
} }
@ -130,10 +131,7 @@ impl gfx_traits::DisplayList for DisplayList {
fn is_contentful(&self) -> bool { fn is_contentful(&self) -> bool {
for item in &self.list { for item in &self.list {
match item { match item {
&DisplayItem::Text(_) | &DisplayItem::Text(_) | &DisplayItem::Image(_) => return true,
&DisplayItem::Image(_) => {
return true
}
_ => (), _ => (),
} }
} }
@ -145,7 +143,7 @@ impl gfx_traits::DisplayList for DisplayList {
/// Display list sections that make up a stacking context. Each section here refers /// Display list sections that make up a stacking context. Each section here refers
/// to the steps in CSS 2.1 Appendix E. /// to the steps in CSS 2.1 Appendix E.
/// ///
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub enum DisplayListSection { pub enum DisplayListSection {
BackgroundAndBorders, BackgroundAndBorders,
BlockBackgroundsAndBorders, BlockBackgroundsAndBorders,
@ -153,14 +151,14 @@ pub enum DisplayListSection {
Outlines, Outlines,
} }
#[derive(Clone, Copy, Debug, Deserialize, Eq, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize)] #[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd, Serialize)]
pub enum StackingContextType { pub enum StackingContextType {
Real, Real,
PseudoPositioned, PseudoPositioned,
PseudoFloat, PseudoFloat,
} }
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
/// Represents one CSS stacking context, which may or may not have a hardware layer. /// Represents one CSS stacking context, which may or may not have a hardware layer.
pub struct StackingContext { pub struct StackingContext {
/// The ID of this StackingContext for uniquely identifying it. /// The ID of this StackingContext for uniquely identifying it.
@ -203,19 +201,20 @@ pub struct StackingContext {
impl StackingContext { impl StackingContext {
/// Creates a new stacking context. /// Creates a new stacking context.
#[inline] #[inline]
pub fn new(id: StackingContextId, pub fn new(
context_type: StackingContextType, id: StackingContextId,
bounds: LayoutRect, context_type: StackingContextType,
overflow: LayoutRect, bounds: LayoutRect,
z_index: i32, overflow: LayoutRect,
filters: Vec<FilterOp>, z_index: i32,
mix_blend_mode: MixBlendMode, filters: Vec<FilterOp>,
transform: Option<LayoutTransform>, mix_blend_mode: MixBlendMode,
transform_style: TransformStyle, transform: Option<LayoutTransform>,
perspective: Option<LayoutTransform>, transform_style: TransformStyle,
scroll_policy: ScrollPolicy, perspective: Option<LayoutTransform>,
parent_clipping_and_scrolling: ClippingAndScrolling) scroll_policy: ScrollPolicy,
-> StackingContext { parent_clipping_and_scrolling: ClippingAndScrolling,
) -> StackingContext {
StackingContext { StackingContext {
id, id,
context_type, context_type,
@ -246,7 +245,7 @@ impl StackingContext {
TransformStyle::Flat, TransformStyle::Flat,
None, None,
ScrollPolicy::Scrollable, ScrollPolicy::Scrollable,
ClippingAndScrolling::simple(ClipScrollNodeIndex(0)) ClippingAndScrolling::simple(ClipScrollNodeIndex(0)),
) )
} }
@ -255,19 +254,15 @@ impl StackingContext {
base_item.stacking_context_id = self.id; base_item.stacking_context_id = self.id;
base_item.clipping_and_scrolling = self.parent_clipping_and_scrolling; base_item.clipping_and_scrolling = self.parent_clipping_and_scrolling;
let pop_item = DisplayItem::PopStackingContext(Box::new( let pop_item = DisplayItem::PopStackingContext(Box::new(PopStackingContextItem {
PopStackingContextItem { base: base_item.clone(),
base: base_item.clone(), stacking_context_id: self.id,
stacking_context_id: self.id, }));
}
));
let push_item = DisplayItem::PushStackingContext(Box::new( let push_item = DisplayItem::PushStackingContext(Box::new(PushStackingContextItem {
PushStackingContextItem { base: base_item,
base: base_item, stacking_context: self,
stacking_context: self, }));
}
));
(push_item, pop_item) (push_item, pop_item)
} }
@ -303,28 +298,28 @@ impl PartialEq for StackingContext {
impl fmt::Debug for StackingContext { impl fmt::Debug for StackingContext {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let type_string = if self.context_type == StackingContextType::Real { let type_string = if self.context_type == StackingContextType::Real {
"StackingContext" "StackingContext"
} else { } else {
"Pseudo-StackingContext" "Pseudo-StackingContext"
}; };
write!(f, "{} at {:?} with overflow {:?}: {:?}", write!(
type_string, f,
self.bounds, "{} at {:?} with overflow {:?}: {:?}",
self.overflow, type_string, self.bounds, self.overflow, self.id
self.id) )
} }
} }
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Debug, Serialize)]
pub struct StickyFrameData { pub struct StickyFrameData {
pub margins: SideOffsets2D<Option<f32>>, pub margins: SideOffsets2D<Option<f32>>,
pub vertical_offset_bounds: StickyOffsetBounds, pub vertical_offset_bounds: StickyOffsetBounds,
pub horizontal_offset_bounds: StickyOffsetBounds, pub horizontal_offset_bounds: StickyOffsetBounds,
} }
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Debug, Serialize)]
pub enum ClipScrollNodeType { pub enum ClipScrollNodeType {
ScrollFrame(ScrollSensitivity, ExternalScrollId), ScrollFrame(ScrollSensitivity, ExternalScrollId),
StickyFrame(StickyFrameData), StickyFrame(StickyFrameData),
@ -332,7 +327,7 @@ pub enum ClipScrollNodeType {
} }
/// Defines a clip scroll node. /// Defines a clip scroll node.
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Debug, Serialize)]
pub struct ClipScrollNode { pub struct ClipScrollNode {
/// The index of the parent of this ClipScrollNode. /// The index of the parent of this ClipScrollNode.
pub parent_index: ClipScrollNodeIndex, pub parent_index: ClipScrollNodeIndex,
@ -348,7 +343,7 @@ pub struct ClipScrollNode {
} }
/// One drawing command in the list. /// One drawing command in the list.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub enum DisplayItem { pub enum DisplayItem {
SolidColor(Box<SolidColorDisplayItem>), SolidColor(Box<SolidColorDisplayItem>),
Text(Box<TextDisplayItem>), Text(Box<TextDisplayItem>),
@ -367,7 +362,7 @@ pub enum DisplayItem {
} }
/// Information common to all display items. /// Information common to all display items.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct BaseDisplayItem { pub struct BaseDisplayItem {
/// The boundaries of the display item, in layer coordinates. /// The boundaries of the display item, in layer coordinates.
pub bounds: LayoutRect, pub bounds: LayoutRect,
@ -390,13 +385,14 @@ pub struct BaseDisplayItem {
impl BaseDisplayItem { impl BaseDisplayItem {
#[inline(always)] #[inline(always)]
pub fn new(bounds: LayoutRect, pub fn new(
metadata: DisplayItemMetadata, bounds: LayoutRect,
clip_rect: LayoutRect, metadata: DisplayItemMetadata,
section: DisplayListSection, clip_rect: LayoutRect,
stacking_context_id: StackingContextId, section: DisplayListSection,
clipping_and_scrolling: ClippingAndScrolling) stacking_context_id: StackingContextId,
-> BaseDisplayItem { clipping_and_scrolling: ClippingAndScrolling,
) -> BaseDisplayItem {
BaseDisplayItem { BaseDisplayItem {
bounds, bounds,
metadata, metadata,
@ -427,7 +423,7 @@ impl BaseDisplayItem {
/// A clipping region for a display item. Currently, this can describe rectangles, rounded /// A clipping region for a display item. Currently, this can describe rectangles, rounded
/// rectangles (for `border-radius`), or arbitrary intersections of the two. Arbitrary transforms /// rectangles (for `border-radius`), or arbitrary intersections of the two. Arbitrary transforms
/// are not supported because those are handled by the higher-level `StackingContext` abstraction. /// are not supported because those are handled by the higher-level `StackingContext` abstraction.
#[derive(Clone, Deserialize, MallocSizeOf, PartialEq, Serialize)] #[derive(Clone, PartialEq, Serialize)]
pub struct ClippingRegion { pub struct ClippingRegion {
/// The main rectangular region. This does not include any corners. /// The main rectangular region. This does not include any corners.
pub main: LayoutRect, pub main: LayoutRect,
@ -487,7 +483,9 @@ impl ClippingRegion {
#[inline] #[inline]
pub fn might_intersect_point(&self, point: &LayoutPoint) -> bool { pub fn might_intersect_point(&self, point: &LayoutPoint) -> bool {
self.main.contains(point) && self.main.contains(point) &&
self.complex.iter().all(|complex| complex.rect.contains(point)) self.complex
.iter()
.all(|complex| complex.rect.contains(point))
} }
/// Returns true if this clipping region might intersect the given rectangle and false /// Returns true if this clipping region might intersect the given rectangle and false
@ -495,7 +493,9 @@ impl ClippingRegion {
#[inline] #[inline]
pub fn might_intersect_rect(&self, rect: &LayoutRect) -> bool { pub fn might_intersect_rect(&self, rect: &LayoutRect) -> bool {
self.main.intersects(rect) && self.main.intersects(rect) &&
self.complex.iter().all(|complex| complex.rect.intersects(rect)) self.complex
.iter()
.all(|complex| complex.rect.intersects(rect))
} }
/// Returns true if this clipping region completely surrounds the given rect. /// Returns true if this clipping region completely surrounds the given rect.
@ -535,10 +535,10 @@ impl ClippingRegion {
for existing_complex_region in &mut self.complex { for existing_complex_region in &mut self.complex {
if existing_complex_region.completely_encloses(&new_complex_region) { if existing_complex_region.completely_encloses(&new_complex_region) {
*existing_complex_region = new_complex_region; *existing_complex_region = new_complex_region;
return return;
} }
if new_complex_region.completely_encloses(existing_complex_region) { if new_complex_region.completely_encloses(existing_complex_region) {
return return;
} }
} }
@ -550,13 +550,14 @@ 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.iter().map(|complex| { complex: self.complex
ComplexClipRegion { .iter()
.map(|complex| ComplexClipRegion {
rect: complex.rect.translate(delta), rect: complex.rect.translate(delta),
radii: complex.radii, radii: complex.radii,
mode: complex.mode, mode: complex.mode,
} })
}).collect(), .collect(),
} }
} }
@ -575,7 +576,11 @@ impl fmt::Debug for ClippingRegion {
} else if self.main == LayoutRect::max_rect() { } else if self.main == LayoutRect::max_rect() {
write!(f, "ClippingRegion(Complex={:?})", self.complex) write!(f, "ClippingRegion(Complex={:?})", self.complex)
} else { } else {
write!(f, "ClippingRegion(Rect={:?}, Complex={:?})", self.main, self.complex) write!(
f,
"ClippingRegion(Rect={:?}, Complex={:?})",
self.main, self.complex
)
} }
} }
} }
@ -590,11 +595,21 @@ 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.top_right.width.max(self.radii.bottom_right.width); let right = self.radii
let bottom = self.radii.bottom_left.height.max(self.radii.bottom_right.height); .top_right
let interior = LayoutRect::new(LayoutPoint::new(self.rect.origin.x + left, self.rect.origin.y + top), .width
LayoutSize::new(self.rect.size.width - left - right, .max(self.radii.bottom_right.width);
self.rect.size.height - top - bottom)); let bottom = self.radii
.bottom_left
.height
.max(self.radii.bottom_right.height);
let interior = LayoutRect::new(
LayoutPoint::new(self.rect.origin.x + left, self.rect.origin.y + top),
LayoutSize::new(
self.rect.size.width - left - right,
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.origin.y <= other.rect.origin.y &&
interior.max_x() >= other.rect.max_x() && interior.max_y() >= other.rect.max_y() interior.max_x() >= other.rect.max_x() && interior.max_y() >= other.rect.max_y()
} }
@ -603,7 +618,7 @@ impl CompletelyEncloses for ComplexClipRegion {
/// Metadata attached to each display item. This is useful for performing auxiliary threads with /// Metadata attached to each display item. This is useful for performing auxiliary threads with
/// the display list involving hit testing: finding the originating DOM node and determining the /// the display list involving hit testing: finding the originating DOM node and determining the
/// cursor to use when the element is hovered over. /// cursor to use when the element is hovered over.
#[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Copy, Serialize)]
pub struct DisplayItemMetadata { pub struct DisplayItemMetadata {
/// The DOM node from which this display item originated. /// The DOM node from which this display item originated.
pub node: OpaqueNode, pub node: OpaqueNode,
@ -613,7 +628,7 @@ pub struct DisplayItemMetadata {
} }
/// Paints a solid color. /// Paints a solid color.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct SolidColorDisplayItem { pub struct SolidColorDisplayItem {
/// Fields common to all display items. /// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -623,7 +638,7 @@ pub struct SolidColorDisplayItem {
} }
/// Paints text. /// Paints text.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct TextDisplayItem { pub struct TextDisplayItem {
/// Fields common to all display items. /// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -635,7 +650,7 @@ pub struct TextDisplayItem {
pub text_color: ColorF, pub text_color: ColorF,
} }
#[derive(Clone, Deserialize, Eq, MallocSizeOf, PartialEq, Serialize)] #[derive(Clone, Eq, PartialEq, Serialize)]
pub enum TextOrientation { pub enum TextOrientation {
Upright, Upright,
SidewaysLeft, SidewaysLeft,
@ -643,11 +658,11 @@ pub enum TextOrientation {
} }
/// Paints an image. /// Paints an image.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct ImageDisplayItem { pub struct ImageDisplayItem {
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
pub webrender_image: WebRenderImageInfo, pub id: ImageKey,
/// The dimensions to which the image display item should be stretched. If this is smaller than /// 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 /// the bounds of this display item, then the image will be repeated in the appropriate
@ -663,14 +678,14 @@ pub struct ImageDisplayItem {
pub image_rendering: ImageRendering, pub image_rendering: ImageRendering,
} }
/// Paints an iframe. /// Paints an iframe.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct IframeDisplayItem { pub struct IframeDisplayItem {
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
pub iframe: PipelineId, pub iframe: PipelineId,
} }
/// Paints a gradient. /// Paints a gradient.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct Gradient { pub struct Gradient {
/// The start point of the gradient (computed during display list construction). /// The start point of the gradient (computed during display list construction).
pub start_point: LayoutPoint, pub start_point: LayoutPoint,
@ -685,7 +700,7 @@ pub struct Gradient {
pub extend_mode: ExtendMode, pub extend_mode: ExtendMode,
} }
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct GradientDisplayItem { pub struct GradientDisplayItem {
/// Fields common to all display item. /// Fields common to all display item.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -705,7 +720,7 @@ pub struct GradientDisplayItem {
} }
/// Paints a radial gradient. /// Paints a radial gradient.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct RadialGradient { pub struct RadialGradient {
/// The center point of the gradient. /// The center point of the gradient.
pub center: LayoutPoint, pub center: LayoutPoint,
@ -720,7 +735,7 @@ pub struct RadialGradient {
pub extend_mode: ExtendMode, pub extend_mode: ExtendMode,
} }
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct RadialGradientDisplayItem { pub struct RadialGradientDisplayItem {
/// Fields common to all display item. /// Fields common to all display item.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -740,7 +755,7 @@ pub struct RadialGradientDisplayItem {
} }
/// A border that is made of linear gradient /// A border that is made of linear gradient
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct GradientBorder { pub struct GradientBorder {
/// The gradient info that this border uses, border-image-source. /// The gradient info that this border uses, border-image-source.
pub gradient: Gradient, pub gradient: Gradient,
@ -750,7 +765,7 @@ pub struct GradientBorder {
} }
/// A border that is made of radial gradient /// A border that is made of radial gradient
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct RadialGradientBorder { pub struct RadialGradientBorder {
/// The gradient info that this border uses, border-image-source. /// The gradient info that this border uses, border-image-source.
pub gradient: RadialGradient, pub gradient: RadialGradient,
@ -760,7 +775,7 @@ pub struct RadialGradientBorder {
} }
/// Specifies the type of border /// Specifies the type of border
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub enum BorderDetails { pub enum BorderDetails {
Normal(NormalBorder), Normal(NormalBorder),
Image(ImageBorder), Image(ImageBorder),
@ -769,7 +784,7 @@ pub enum BorderDetails {
} }
/// Paints a border. /// Paints a border.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct BorderDisplayItem { pub struct BorderDisplayItem {
/// Fields common to all display items. /// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -782,7 +797,7 @@ pub struct BorderDisplayItem {
} }
/// Paints a line segment. /// Paints a line segment.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct LineDisplayItem { pub struct LineDisplayItem {
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -794,7 +809,7 @@ pub struct LineDisplayItem {
} }
/// Paints a box shadow per CSS-BACKGROUNDS. /// Paints a box shadow per CSS-BACKGROUNDS.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct BoxShadowDisplayItem { pub struct BoxShadowDisplayItem {
/// Fields common to all display items. /// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -822,30 +837,23 @@ pub struct BoxShadowDisplayItem {
} }
/// Defines a text shadow that affects all items until the paired PopTextShadow. /// Defines a text shadow that affects all items until the paired PopTextShadow.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct PushTextShadowDisplayItem { pub struct PushTextShadowDisplayItem {
/// Fields common to all display items. /// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
/// The offset of this shadow from the text. pub shadow: Shadow,
pub offset: LayoutVector2D,
/// The color of this shadow.
pub color: ColorF,
/// The blur radius for this shadow.
pub blur_radius: f32,
} }
/// Defines a text shadow that affects all items until the next PopTextShadow. /// Defines a text shadow that affects all items until the next PopTextShadow.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct PopAllTextShadowsDisplayItem { pub struct PopAllTextShadowsDisplayItem {
/// Fields common to all display items. /// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
} }
/// Defines a stacking context. /// Defines a stacking context.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct PushStackingContextItem { pub struct PushStackingContextItem {
/// Fields common to all display items. /// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -854,7 +862,7 @@ pub struct PushStackingContextItem {
} }
/// Defines a stacking context. /// Defines a stacking context.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct PopStackingContextItem { pub struct PopStackingContextItem {
/// Fields common to all display items. /// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -863,7 +871,7 @@ pub struct PopStackingContextItem {
} }
/// Starts a group of items inside a particular scroll root. /// Starts a group of items inside a particular scroll root.
#[derive(Clone, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Serialize)]
pub struct DefineClipScrollNodeItem { pub struct DefineClipScrollNodeItem {
/// Fields common to all display items. /// Fields common to all display items.
pub base: BaseDisplayItem, pub base: BaseDisplayItem,
@ -935,14 +943,17 @@ impl fmt::Debug for DisplayItem {
return write!(f, "DefineClipScrollNode({:?}", item.node_index); return write!(f, "DefineClipScrollNode({:?}", item.node_index);
} }
write!(f, "{} @ {:?} {:?}", write!(
f,
"{} @ {:?} {:?}",
match *self { match *self {
DisplayItem::SolidColor(ref solid_color) => DisplayItem::SolidColor(ref solid_color) => format!(
format!("SolidColor rgba({}, {}, {}, {})", "SolidColor rgba({}, {}, {}, {})",
solid_color.color.r, solid_color.color.r,
solid_color.color.g, solid_color.color.g,
solid_color.color.b, solid_color.color.b,
solid_color.color.a), 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(),
@ -963,11 +974,10 @@ impl fmt::Debug for DisplayItem {
} }
} }
#[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)] #[derive(Clone, Copy, Serialize)]
pub struct WebRenderImageInfo { pub struct WebRenderImageInfo {
pub width: u32, pub width: u32,
pub height: u32, pub height: u32,
pub format: PixelFormat,
pub key: Option<ImageKey>, pub key: Option<ImageKey>,
} }
@ -977,7 +987,6 @@ impl WebRenderImageInfo {
WebRenderImageInfo { WebRenderImageInfo {
width: image.width, width: image.width,
height: image.height, height: image.height,
format: image.format,
key: image.id, key: image.id,
} }
} }
@ -986,7 +995,6 @@ impl WebRenderImageInfo {
/// The type of the scroll offset list. This is only populated if WebRender is in use. /// The type of the scroll offset list. This is only populated if WebRender is in use.
pub type ScrollOffsetMap = HashMap<ExternalScrollId, Vector2D<f32>>; pub type ScrollOffsetMap = HashMap<ExternalScrollId, Vector2D<f32>>;
pub trait SimpleMatrixDetection { pub trait SimpleMatrixDetection {
fn is_identity_or_simple_translation(&self) -> bool; fn is_identity_or_simple_translation(&self) -> bool;
} }
@ -994,11 +1002,9 @@ pub trait SimpleMatrixDetection {
impl SimpleMatrixDetection for LayoutTransform { 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) = (Zero::zero(), One::one()); let (_0, _1) = (0.0, 1.0);
self.m11 == _1 && self.m12 == _0 && self.m13 == _0 && self.m14 == _0 && self.m11 == _1 && self.m12 == _0 && self.m13 == _0 && self.m14 == _0 && self.m21 == _0 &&
self.m21 == _0 && self.m22 == _1 && self.m23 == _0 && self.m24 == _0 && self.m22 == _1 && self.m23 == _0 && self.m24 == _0 && self.m31 == _0 &&
self.m31 == _0 && self.m32 == _0 && self.m33 == _1 && self.m34 == _0 && self.m32 == _0 && self.m33 == _1 && self.m34 == _0 && self.m44 == _1
self.m44 == _1
} }
} }

View file

@ -17,4 +17,5 @@ pub use self::webrender_helpers::WebRenderDisplayListConverter;
mod background; mod background;
mod builder; mod builder;
mod conversions; mod conversions;
pub mod items;
mod webrender_helpers; mod webrender_helpers;

View file

@ -7,9 +7,9 @@
// 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 gfx::display_list::{BorderDetails, ClipScrollNode}; use display_list::items::{BorderDetails, ClipScrollNode};
use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem}; use display_list::items::{ClipScrollNodeIndex, ClipScrollNodeType, DisplayItem};
use gfx::display_list::{DisplayList, StackingContextType}; use display_list::items::{DisplayList, StackingContextType};
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;
use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder}; use webrender_api::{self, ClipAndScrollInfo, ClipId, DisplayListBuilder};
@ -111,17 +111,15 @@ impl WebRenderDisplayItemConverter for DisplayItem {
); );
}, },
DisplayItem::Image(ref item) => { DisplayItem::Image(ref item) => {
if let Some(id) = item.webrender_image.key { if item.stretch_size.width > 0.0 && item.stretch_size.height > 0.0 {
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.stretch_size, item.tile_spacing,
item.tile_spacing, item.image_rendering,
item.image_rendering, webrender_api::AlphaType::PremultipliedAlpha,
webrender_api::AlphaType::PremultipliedAlpha, item.id,
id, );
);
}
} }
}, },
DisplayItem::Border(ref item) => { DisplayItem::Border(ref item) => {
@ -204,14 +202,7 @@ impl WebRenderDisplayItemConverter for DisplayItem {
); );
}, },
DisplayItem::PushTextShadow(ref item) => { DisplayItem::PushTextShadow(ref item) => {
builder.push_shadow( builder.push_shadow(&self.prim_info(), item.shadow);
&self.prim_info(),
webrender_api::Shadow {
blur_radius: item.blur_radius,
offset: item.offset,
color: item.color,
},
);
}, },
DisplayItem::PopAllTextShadows(_) => { DisplayItem::PopAllTextShadows(_) => {
builder.pop_all_shadows(); builder.pop_all_shadows();

View file

@ -29,13 +29,13 @@ use app_units::Au;
use block::{BlockFlow, FormattingContextType}; use block::{BlockFlow, FormattingContextType};
use context::LayoutContext; use context::LayoutContext;
use display_list::{DisplayListBuildState, StackingContextCollectionState}; use display_list::{DisplayListBuildState, StackingContextCollectionState};
use display_list::items::ClippingAndScrolling;
use euclid::{Point2D, Vector2D, Rect, Size2D}; use euclid::{Point2D, Vector2D, Rect, Size2D};
use flex::FlexFlow; use flex::FlexFlow;
use floats::{Floats, SpeculatedFloatPlacement}; use floats::{Floats, SpeculatedFloatPlacement};
use flow_list::{FlowList, FlowListIterator, MutFlowListIterator}; use flow_list::{FlowList, FlowListIterator, MutFlowListIterator};
use flow_ref::{FlowRef, WeakFlowRef}; use flow_ref::{FlowRef, WeakFlowRef};
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::ClippingAndScrolling;
use gfx_traits::StackingContextId; use gfx_traits::StackingContextId;
use gfx_traits::print_tree::PrintTree; use gfx_traits::print_tree::PrintTree;
use inline::InlineFlow; use inline::InlineFlow;

View file

@ -11,12 +11,12 @@ use app_units::Au;
use canvas_traits::canvas::CanvasMsg; use canvas_traits::canvas::CanvasMsg;
use context::{LayoutContext, with_thread_local_font_context}; use context::{LayoutContext, with_thread_local_font_context};
use display_list::ToLayout; use display_list::ToLayout;
use display_list::items::{BLUR_INFLATION_FACTOR, OpaqueNode};
use euclid::{Point2D, Vector2D, Rect, Size2D}; use euclid::{Point2D, Vector2D, Rect, Size2D};
use floats::ClearType; use floats::ClearType;
use flow::{GetBaseFlow, ImmutableFlowUtils}; use flow::{GetBaseFlow, ImmutableFlowUtils};
use flow_ref::FlowRef; use flow_ref::FlowRef;
use gfx; use gfx;
use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
use gfx::text::glyph::ByteIndex; use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::{TextRun, TextRunSlice}; use gfx::text::text_run::{TextRun, TextRunSlice};
use gfx_traits::StackingContextId; use gfx_traits::StackingContextId;

View file

@ -9,9 +9,9 @@
//! as possible. //! as possible.
use context::{LayoutContext, with_thread_local_font_context}; use context::{LayoutContext, with_thread_local_font_context};
use display_list::items::OpaqueNode;
use flow::{Flow, FlowFlags, GetBaseFlow, ImmutableFlowUtils}; use flow::{Flow, FlowFlags, GetBaseFlow, ImmutableFlowUtils};
use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo}; use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use gfx::display_list::OpaqueNode;
use script_layout_interface::wrapper_traits::PseudoElementType; use script_layout_interface::wrapper_traits::PseudoElementType;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::collections::{HashMap, LinkedList}; use std::collections::{HashMap, LinkedList};

View file

@ -10,6 +10,7 @@ use block::AbsoluteAssignBSizesTraversal;
use context::{LayoutContext, LayoutFontContext}; use context::{LayoutContext, LayoutFontContext};
use display_list::{DisplayListBuildState, InlineFlowDisplayListBuilding}; use display_list::{DisplayListBuildState, InlineFlowDisplayListBuilding};
use display_list::StackingContextCollectionState; use display_list::StackingContextCollectionState;
use display_list::items::OpaqueNode;
use euclid::{Point2D, Size2D}; use euclid::{Point2D, Size2D};
use floats::{FloatKind, Floats, PlacementInfo}; use floats::{FloatKind, Floats, PlacementInfo};
use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag}; use flow::{BaseFlow, Flow, FlowClass, ForceNonfloatedFlag};
@ -18,7 +19,6 @@ use flow_ref::FlowRef;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow}; use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use fragment::FragmentFlags; use fragment::FragmentFlags;
use fragment::SpecificFragmentInfo; use fragment::SpecificFragmentInfo;
use gfx::display_list::OpaqueNode;
use gfx::font::FontMetrics; use gfx::font::FontMetrics;
use gfx_traits::print_tree::PrintTree; use gfx_traits::print_tree::PrintTree;
use layout_debug; use layout_debug;

View file

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use gfx::display_list::OpaqueNode; use display_list::items::OpaqueNode;
use libc::c_void; use libc::c_void;
use script_traits::UntrustedNodeAddress; use script_traits::UntrustedNodeAddress;

View file

@ -8,10 +8,10 @@ use app_units::Au;
use construct::ConstructionResult; use construct::ConstructionResult;
use context::LayoutContext; use context::LayoutContext;
use display_list::IndexableText; use display_list::IndexableText;
use display_list::items::{DisplayList, OpaqueNode, ScrollOffsetMap};
use euclid::{Point2D, Vector2D, Rect, Size2D}; use euclid::{Point2D, Vector2D, Rect, Size2D};
use flow::{Flow, GetBaseFlow}; use flow::{Flow, GetBaseFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo}; use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
use gfx::display_list::{DisplayList, OpaqueNode, ScrollOffsetMap};
use inline::InlineFragmentNodeFlags; use inline::InlineFragmentNodeFlags;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId; use msg::constellation_msg::PipelineId;

View file

@ -55,7 +55,6 @@ use dom_wrapper::{ServoLayoutElement, ServoLayoutDocument, ServoLayoutNode};
use dom_wrapper::drop_style_and_layout_data; use dom_wrapper::drop_style_and_layout_data;
use euclid::{Point2D, Rect, Size2D, TypedScale, TypedSize2D}; use euclid::{Point2D, Rect, Size2D, TypedScale, TypedSize2D};
use fnv::FnvHashMap; use fnv::FnvHashMap;
use gfx::display_list::{OpaqueNode, WebRenderImageInfo};
use gfx::font; use gfx::font;
use gfx::font_cache_thread::FontCacheThread; use gfx::font_cache_thread::FontCacheThread;
use gfx::font_context; use gfx::font_context;
@ -68,8 +67,8 @@ use layout::context::LayoutContext;
use layout::context::RegisteredPainter; use layout::context::RegisteredPainter;
use layout::context::RegisteredPainters; use layout::context::RegisteredPainters;
use layout::context::malloc_size_of_persistent_local_context; use layout::context::malloc_size_of_persistent_local_context;
use layout::display_list::{IndexableText, ToLayout}; use layout::display_list::{IndexableText, ToLayout, WebRenderDisplayListConverter};
use layout::display_list::WebRenderDisplayListConverter; use layout::display_list::items::{OpaqueNode, WebRenderImageInfo};
use layout::flow::{Flow, GetBaseFlow, ImmutableFlowUtils, MutableOwnedFlowUtils}; use layout::flow::{Flow, GetBaseFlow, ImmutableFlowUtils, MutableOwnedFlowUtils};
use layout::flow_ref::FlowRef; use layout::flow_ref::FlowRef;
use layout::incremental::{LayoutDamageComputation, RelayoutMode, SpecialRestyleDamage}; use layout::incremental::{LayoutDamageComputation, RelayoutMode, SpecialRestyleDamage};

View file

@ -10,12 +10,11 @@ path = "lib.rs"
doctest = false doctest = false
[dependencies] [dependencies]
gfx = {path = "../../../components/gfx"}
gfx_traits = {path = "../../../components/gfx_traits"} gfx_traits = {path = "../../../components/gfx_traits"}
ipc-channel = "0.10" ipc-channel = "0.10"
layout = {path = "../../../components/layout"}
metrics = {path = "../../../components/metrics"} metrics = {path = "../../../components/metrics"}
msg = {path = "../../../components/msg"} msg = {path = "../../../components/msg"}
net_traits = {path = "../../../components/net_traits"}
profile_traits = {path = "../../../components/profile_traits"} profile_traits = {path = "../../../components/profile_traits"}
servo_url = {path = "../../../components/url"} servo_url = {path = "../../../components/url"}
time = "0.1.12" time = "0.1.12"

View file

@ -4,12 +4,11 @@
#![cfg(test)] #![cfg(test)]
extern crate gfx;
extern crate gfx_traits; extern crate gfx_traits;
extern crate ipc_channel; extern crate ipc_channel;
extern crate layout;
extern crate metrics; extern crate metrics;
extern crate msg; extern crate msg;
extern crate net_traits;
extern crate profile_traits; extern crate profile_traits;
extern crate servo_url; extern crate servo_url;
extern crate time; extern crate time;

View file

@ -2,17 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use gfx::display_list::{BaseDisplayItem, WebRenderImageInfo};
use gfx::display_list::{DisplayItem, DisplayList, ImageDisplayItem};
use gfx_traits::Epoch; use gfx_traits::Epoch;
use ipc_channel::ipc; use ipc_channel::ipc;
use layout::display_list::items::{BaseDisplayItem, DisplayItem, DisplayList, ImageDisplayItem};
use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric}; use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric};
use msg::constellation_msg::TEST_PIPELINE_ID; use msg::constellation_msg::TEST_PIPELINE_ID;
use net_traits::image::base::PixelFormat;
use profile_traits::time::{ProfilerChan, TimerMetadata}; use profile_traits::time::{ProfilerChan, TimerMetadata};
use servo_url::ServoUrl; use servo_url::ServoUrl;
use time; use time;
use webrender_api::{ImageRendering, LayoutSize}; use webrender_api::{ImageKey, ImageRendering, LayoutSize};
struct DummyProfilerMetadataFactory {} struct DummyProfilerMetadataFactory {}
impl ProfilerMetadataFactory for DummyProfilerMetadataFactory { impl ProfilerMetadataFactory for DummyProfilerMetadataFactory {
@ -120,12 +118,7 @@ fn test_first_paint_setter() {
fn test_first_contentful_paint_setter() { fn test_first_contentful_paint_setter() {
let image = DisplayItem::Image(Box::new(ImageDisplayItem { let image = DisplayItem::Image(Box::new(ImageDisplayItem {
base: BaseDisplayItem::empty(), base: BaseDisplayItem::empty(),
webrender_image: WebRenderImageInfo { id: ImageKey::DUMMY,
width: 1,
height: 1,
format: PixelFormat::RGB8,
key: None,
},
stretch_size: LayoutSize::zero(), stretch_size: LayoutSize::zero(),
tile_spacing: LayoutSize::zero(), tile_spacing: LayoutSize::zero(),
image_rendering: ImageRendering::Auto, image_rendering: ImageRendering::Auto,

View file

@ -100521,6 +100521,18 @@
{} {}
] ]
], ],
"css/css-backgrounds/background-rounded-image-clip.html": [
[
"/css/css-backgrounds/background-rounded-image-clip.html",
[
[
"/css/css-backgrounds/reference/background-rounded-image-clip.html",
"=="
]
],
{}
]
],
"css/css-backgrounds/background-size-002.html": [ "css/css-backgrounds/background-size-002.html": [
[ [
"/css/css-backgrounds/background-size-002.html", "/css/css-backgrounds/background-size-002.html",
@ -236779,6 +236791,11 @@
{} {}
] ]
], ],
"css/css-backgrounds/reference/background-rounded-image-clip.html": [
[
{}
]
],
"css/css-backgrounds/reference/background-size-002-ref.html": [ "css/css-backgrounds/reference/background-size-002-ref.html": [
[ [
{} {}
@ -483700,6 +483717,10 @@
"36050bffda9382cfd978dc82a2f0244a535a6a46", "36050bffda9382cfd978dc82a2f0244a535a6a46",
"support" "support"
], ],
"css/css-backgrounds/background-rounded-image-clip.html": [
"c22edf865829fea1d69a54e34396b4462250585f",
"reftest"
],
"css/css-backgrounds/background-size-001.html": [ "css/css-backgrounds/background-size-001.html": [
"7cf677bf25a1fcac569bd0accd28dd66e6060a1b", "7cf677bf25a1fcac569bd0accd28dd66e6060a1b",
"testharness" "testharness"
@ -485904,6 +485925,10 @@
"1141a4c270ace715755b9b8352dab9baffca27c4", "1141a4c270ace715755b9b8352dab9baffca27c4",
"support" "support"
], ],
"css/css-backgrounds/reference/background-rounded-image-clip.html": [
"f5c1af4d9e5b415e762c921c6d93355b2861946c",
"support"
],
"css/css-backgrounds/reference/background-size-002-ref.html": [ "css/css-backgrounds/reference/background-size-002-ref.html": [
"33d8850f315bedabb7024031b091a14177034c1d", "33d8850f315bedabb7024031b091a14177034c1d",
"support" "support"

View file

@ -0,0 +1,34 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Background Clip Follows Rounded Corner</title>
<link rel="match" href="reference/background-rounded-image-clip.html">
<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#corner-clipping">
<style>
html {
background-color: green;
}
#a {
top: 20px;
left: 20px;
position: absolute;
width: 20px;
height: 20px;
background-color: black;
}
#b {
position: absolute;
width: 300px;
height: 200px;
background-image: linear-gradient(green, green);
background-clip: content-box;
border-top-left-radius: 90px;
border-width: 10px;
border-style: solid;
border-color: transparent;
}
</style>
<body>
<div id="a"></div>
<div id="b"></div>
</body>

View file

@ -0,0 +1,15 @@
<!doctype html>
<style>
html {
background-color: green;
}
#a {
top: 20px;
left: 20px;
position: absolute;
width: 20px;
height: 20px;
background-color: black;
}
</style>
<div id="a"></div>