servo: Merge #19782 - Use more WebRender types in gfx/display_list (from pyfisch:dl-simple); r=mrobinson
authorPyfisch <pyfisch@gmail.com>
Thu, 18 Jan 2018 05:42:52 -0600
changeset 399817 d19de7121ca1ee2ade1b5aa3883ddb88c153803a
parent 399816 e1903f1d75e0146b451c8da9d237a83ede2e0fa9
child 399818 891afc6d66f11311146589cb4db1605ddbd8f380
push id58290
push userservo-vcs-sync@mozilla.com
push dateThu, 18 Jan 2018 12:44:54 +0000
treeherderautoland@d19de7121ca1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrobinson
milestone59.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #19782 - Use more WebRender types in gfx/display_list (from pyfisch:dl-simple); r=mrobinson Use more WebRender types in gfx/display_list. This uses floating-point (Layout) coordinates in where possible. Replace NormalBorder struct with WebRender equivalent. Remove ToPointF and ToRectF traits. Convert border RepeatKeyword with ToLayout. Add some definitions to malloc_size_of for WebRender types. Source-Repo: https://github.com/servo/servo Source-Revision: aee0d694cc077d4694fc3114af3a2ad83e326cbf
servo/Cargo.lock
servo/components/geometry/Cargo.toml
servo/components/geometry/lib.rs
servo/components/gfx/display_list/mod.rs
servo/components/layout/block.rs
servo/components/layout/display_list/background.rs
servo/components/layout/display_list/builder.rs
servo/components/layout/display_list/conversions.rs
servo/components/layout/display_list/webrender_helpers.rs
servo/components/layout/flow.rs
servo/components/layout_thread/lib.rs
servo/components/malloc_size_of/lib.rs
servo/components/script/dom/window.rs
servo/tests/unit/metrics/Cargo.toml
servo/tests/unit/metrics/lib.rs
servo/tests/unit/metrics/paint_time.rs
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -1774,27 +1774,26 @@ dependencies = [
  "servo_url 0.0.1",
  "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "metrics_tests"
 version = "0.0.1"
 dependencies = [
- "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gfx 0.0.1",
  "gfx_traits 0.0.1",
  "ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "metrics 0.0.1",
  "msg 0.0.1",
  "net_traits 0.0.1",
  "profile_traits 0.0.1",
  "servo_url 0.0.1",
- "style 0.0.1",
  "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "webrender_api 0.56.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "mime"
 version = "0.2.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2955,16 +2954,17 @@ dependencies = [
 [[package]]
 name = "servo_geometry"
 version = "0.0.1"
 dependencies = [
  "app_units 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "malloc_size_of 0.0.1",
  "malloc_size_of_derive 0.0.1",
+ "webrender_api 0.56.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "servo_rand"
 version = "0.0.1"
 dependencies = [
  "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
--- a/servo/components/geometry/Cargo.toml
+++ b/servo/components/geometry/Cargo.toml
@@ -9,8 +9,9 @@ publish = false
 name = "servo_geometry"
 path = "lib.rs"
 
 [dependencies]
 app_units = "0.6"
 euclid = "0.16"
 malloc_size_of = { path = "../malloc_size_of" }
 malloc_size_of_derive = { path = "../malloc_size_of_derive" }
+webrender_api = { git = "https://github.com/servo/webrender" }
--- a/servo/components/geometry/lib.rs
+++ b/servo/components/geometry/lib.rs
@@ -1,19 +1,22 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 extern crate app_units;
 extern crate euclid;
 extern crate malloc_size_of;
 #[macro_use] extern crate malloc_size_of_derive;
+extern crate webrender_api;
 
 use app_units::{Au, MAX_AU, MIN_AU};
 use euclid::{Point2D, Rect, Size2D};
+use std::f32;
+use webrender_api::{LayoutPoint, LayoutRect, LayoutSize};
 
 // Units for use with euclid::length and euclid::scale_factor.
 
 /// A normalized "pixel" at the default resolution for the display.
 ///
 /// Like the CSS "px" unit, the exact physical size of this unit may vary between devices, but it
 /// should approximate a device-independent reference length.  This unit corresponds to Android's
 /// "density-independent pixel" (dip), Mac OS X's "point", and Windows "device-independent pixel."
@@ -27,19 +30,37 @@ use euclid::{Point2D, Rect, Size2D};
 /// `servo::windowing::WindowMethods::hidpi_factor`.
 #[derive(Clone, Copy, Debug, MallocSizeOf)]
 pub enum DeviceIndependentPixel {}
 
 // An Au is an "App Unit" and represents 1/60th of a CSS pixel.  It was
 // originally proposed in 2002 as a standard unit of measure in Gecko.
 // See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info.
 
-#[inline(always)]
-pub fn max_rect() -> Rect<Au> {
-    Rect::new(Point2D::new(MIN_AU / 2, MIN_AU / 2), Size2D::new(MAX_AU, MAX_AU))
+pub trait MaxRect {
+    #[inline(always)]
+    fn max_rect() -> Self;
+}
+
+impl MaxRect for Rect<Au> {
+    fn max_rect() -> Rect<Au> {
+        Rect::new(
+            Point2D::new(MIN_AU / 2, MIN_AU / 2),
+            Size2D::new(MAX_AU, MAX_AU)
+        )
+    }
+}
+
+impl MaxRect for LayoutRect {
+    fn max_rect() -> LayoutRect {
+        LayoutRect::new(
+            LayoutPoint::new(f32::MIN / 2.0, f32::MIN / 2.0),
+            LayoutSize::new(f32::MAX, f32::MAX),
+        )
+    }
 }
 
 /// A helper function to convert a rect of `f32` pixels to a rect of app units.
 pub fn f32_rect_to_au_rect(rect: Rect<f32>) -> Rect<Au> {
     Rect::new(Point2D::new(Au::from_f32_px(rect.origin.x), Au::from_f32_px(rect.origin.y)),
               Size2D::new(Au::from_f32_px(rect.size.width), Au::from_f32_px(rect.size.height)))
 }
 
--- a/servo/components/gfx/display_list/mod.rs
+++ b/servo/components/gfx/display_list/mod.rs
@@ -18,28 +18,30 @@ use app_units::Au;
 use euclid::{Transform3D, Point2D, Vector2D, Rect, Size2D, TypedRect, SideOffsets2D};
 use euclid::num::{One, Zero};
 use gfx_traits::{self, StackingContextId};
 use gfx_traits::print_tree::PrintTree;
 use ipc_channel::ipc::IpcSharedMemory;
 use msg::constellation_msg::PipelineId;
 use net_traits::image::base::{Image, PixelFormat};
 use range::Range;
-use servo_geometry::max_rect;
+use servo_geometry::MaxRect;
 use std::cmp::{self, Ordering};
 use std::collections::HashMap;
+use std::f32;
 use std::fmt;
 use std::sync::Arc;
-use style::computed_values::{border_style, image_rendering};
 use style::values::computed::Filter;
 use style_traits::cursor::Cursor;
 use text::TextRun;
 use text::glyph::ByteIndex;
-use webrender_api::{self, BoxShadowClipMode, ClipId, ColorF, GradientStop, LocalClip, MixBlendMode};
-use webrender_api::{ScrollPolicy, ScrollSensitivity, StickyOffsetBounds, TransformStyle};
+use webrender_api::{BoxShadowClipMode, ClipId, ColorF, ExtendMode, GradientStop, ImageKey};
+use webrender_api::{ImageRendering, LayoutPoint, LayoutRect, LayoutSize, LayoutVector2D};
+use webrender_api::{LineStyle, LocalClip, MixBlendMode, NormalBorder, RepeatMode, ScrollPolicy};
+use webrender_api::{ScrollSensitivity, StickyOffsetBounds, TransformStyle};
 
 pub use style::dom::OpaqueNode;
 
 /// The factor that we multiply the blur radius by in order to inflate the boundaries of display
 /// items that involve a blur. This ensures that the display item boundaries include all the ink.
 pub static BLUR_INFLATION_FACTOR: i32 = 3;
 
 /// An index into the vector of ClipScrollNodes. During WebRender conversion these nodes
@@ -437,17 +439,18 @@ impl BaseDisplayItem {
     #[inline(always)]
     pub fn empty() -> BaseDisplayItem {
         BaseDisplayItem {
             bounds: TypedRect::zero(),
             metadata: DisplayItemMetadata {
                 node: OpaqueNode(0),
                 pointing: None,
             },
-            local_clip: LocalClip::from(max_rect().to_rectf()),
+            // Create a rectangle of maximal size.
+            local_clip: LocalClip::from(LayoutRect::max_rect()),
             section: DisplayListSection::Content,
             stacking_context_id: StackingContextId::root(),
             clipping_and_scrolling: ClippingAndScrolling::simple(ClipScrollNodeIndex(0)),
         }
     }
 }
 
 /// A clipping region for a display item. Currently, this can describe rectangles, rounded
@@ -484,17 +487,17 @@ impl ClippingRegion {
             complex: Vec::new(),
         }
     }
 
     /// Returns an all-encompassing clipping region that clips no pixels out.
     #[inline]
     pub fn max() -> ClippingRegion {
         ClippingRegion {
-            main: max_rect(),
+            main: Rect::max_rect(),
             complex: Vec::new(),
         }
     }
 
     /// Returns a clipping region that represents the given rectangle.
     #[inline]
     pub fn from_rect(rect: &Rect<Au>) -> ClippingRegion {
         ClippingRegion {
@@ -595,27 +598,27 @@ impl ClippingRegion {
                     radii: complex.radii,
                 }
             }).collect(),
         }
     }
 
     #[inline]
     pub fn is_max(&self) -> bool {
-        self.main == max_rect() && self.complex.is_empty()
+        self.main == Rect::max_rect() && self.complex.is_empty()
     }
 }
 
 impl fmt::Debug for ClippingRegion {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         if *self == ClippingRegion::max() {
             write!(f, "ClippingRegion::Max")
         } else if *self == ClippingRegion::empty() {
             write!(f, "ClippingRegion::Empty")
-        } else if self.main == max_rect() {
+        } else if self.main == Rect::max_rect() {
             write!(f, "ClippingRegion(Complex={:?})", self.complex)
         } else {
             write!(f, "ClippingRegion(Rect={:?}, Complex={:?})", self.main, self.complex)
         }
     }
 }
 
 impl ComplexClippingRegion {
@@ -694,47 +697,47 @@ pub struct ImageDisplayItem {
     pub webrender_image: WebRenderImageInfo,
 
     #[ignore_malloc_size_of = "Because it is non-owning"]
     pub image_data: Option<Arc<IpcSharedMemory>>,
 
     /// 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: Size2D<Au>,
+    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: Size2D<Au>,
+    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: image_rendering::T,
+    pub image_rendering: ImageRendering,
 }
 /// Paints an iframe.
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct IframeDisplayItem {
     pub base: BaseDisplayItem,
     pub iframe: PipelineId,
 }
 
 /// Paints a gradient.
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct Gradient {
     /// The start point of the gradient (computed during display list construction).
-    pub start_point: Point2D<Au>,
+    pub start_point: LayoutPoint,
 
     /// The end point of the gradient (computed during display list construction).
-    pub end_point: Point2D<Au>,
+    pub end_point: LayoutPoint,
 
     /// A list of color stops.
     pub stops: Vec<GradientStop>,
 
-    /// True if gradient repeats infinitly.
-    pub repeating: bool,
+    /// Whether the gradient is repeated or clamped.
+    pub extend_mode: ExtendMode,
 }
 
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct GradientDisplayItem {
     /// Fields common to all display item.
     pub base: BaseDisplayItem,
 
     /// Contains all gradient data. Included start, end point and color stops.
@@ -742,34 +745,34 @@ pub struct GradientDisplayItem {
 
     /// 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: Size2D<Au>,
-    pub tile_spacing: Size2D<Au>,
+    pub tile: LayoutSize,
+    pub tile_spacing: LayoutSize,
 }
 
 /// Paints a radial gradient.
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct RadialGradient {
     /// The center point of the gradient.
-    pub center: Point2D<Au>,
+    pub center: LayoutPoint,
 
     /// The radius of the gradient with an x and an y component.
-    pub radius: Size2D<Au>,
+    pub radius: LayoutSize,
 
     /// A list of color stops.
     pub stops: Vec<GradientStop>,
 
-    /// True if gradient repeats infinitly.
-    pub repeating: bool,
+    /// Whether the gradient is repeated or clamped.
+    pub extend_mode: ExtendMode,
 }
 
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct RadialGradientDisplayItem {
     /// Fields common to all display item.
     pub base: BaseDisplayItem,
 
     /// Contains all gradient data.
@@ -777,31 +780,18 @@ pub struct RadialGradientDisplayItem {
 
     /// 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: Size2D<Au>,
-    pub tile_spacing: Size2D<Au>,
-}
-
-/// A normal border, supporting CSS border styles.
-#[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
-pub struct NormalBorder {
-    /// Border colors.
-    pub color: SideOffsets2D<ColorF>,
-
-    /// Border styles.
-    pub style: SideOffsets2D<border_style::T>,
-
-    /// Border radii.
-    pub radius: BorderRadii<Au>,
+    pub tile: LayoutSize,
+    pub tile_spacing: LayoutSize,
 }
 
 /// A border that is made of image segments.
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct ImageBorder {
     /// The image this border uses, border-image-source.
     pub image: WebRenderImageInfo,
 
@@ -810,20 +800,20 @@ pub struct ImageBorder {
 
     /// Outsets for the border, as per border-image-outset.
     pub outset: SideOffsets2D<f32>,
 
     /// If fill is true, draw the center patch of the image.
     pub fill: bool,
 
     /// How to repeat or stretch horizontal edges (border-image-repeat).
-    pub repeat_horizontal: webrender_api::RepeatMode,
+    pub repeat_horizontal: RepeatMode,
 
     /// How to repeat or stretch vertical edges (border-image-repeat).
-    pub repeat_vertical: webrender_api::RepeatMode,
+    pub repeat_vertical: RepeatMode,
 }
 
 /// A border that is made of linear gradient
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct GradientBorder {
     /// The gradient info that this border uses, border-image-source.
     pub gradient: Gradient,
 
@@ -929,63 +919,61 @@ impl<T> BorderRadii<T> where T: PartialE
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct LineDisplayItem {
     pub base: BaseDisplayItem,
 
     /// The line segment color.
     pub color: ColorF,
 
     /// The line segment style.
-    #[ignore_malloc_size_of = "enum type in webrender"]
-    pub style: webrender_api::LineStyle,
+    pub style: LineStyle,
 }
 
 /// Paints a box shadow per CSS-BACKGROUNDS.
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct BoxShadowDisplayItem {
     /// Fields common to all display items.
     pub base: BaseDisplayItem,
 
     /// The dimensions of the box that we're placing a shadow around.
-    pub box_bounds: Rect<Au>,
+    pub box_bounds: LayoutRect,
 
     /// The offset of this shadow from the box.
-    pub offset: Vector2D<Au>,
+    pub offset: LayoutVector2D,
 
     /// The color of this shadow.
     pub color: ColorF,
 
     /// The blur radius for this shadow.
-    pub blur_radius: Au,
+    pub blur_radius: f32,
 
     /// The spread radius of this shadow.
-    pub spread_radius: Au,
+    pub spread_radius: f32,
 
     /// The border radius of this shadow.
     pub border_radius: BorderRadii<Au>,
 
     /// How we should clip the result.
-    #[ignore_malloc_size_of = "enum type in webrender"]
     pub clip_mode: BoxShadowClipMode,
 }
 
 /// Defines a text shadow that affects all items until the paired PopTextShadow.
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct PushTextShadowDisplayItem {
     /// Fields common to all display items.
     pub base: BaseDisplayItem,
 
     /// The offset of this shadow from the text.
-    pub offset: Vector2D<Au>,
+    pub offset: LayoutVector2D,
 
     /// The color of this shadow.
     pub color: ColorF,
 
     /// The blur radius for this shadow.
-    pub blur_radius: Au,
+    pub blur_radius: f32,
 }
 
 /// Defines a text shadow that affects all items until the next PopTextShadow.
 #[derive(Clone, Deserialize, MallocSizeOf, Serialize)]
 pub struct PopAllTextShadowsDisplayItem {
     /// Fields common to all display items.
     pub base: BaseDisplayItem,
 }
@@ -1113,17 +1101,17 @@ impl fmt::Debug for DisplayItem {
     }
 }
 
 #[derive(Clone, Copy, Deserialize, MallocSizeOf, Serialize)]
 pub struct WebRenderImageInfo {
     pub width: u32,
     pub height: u32,
     pub format: PixelFormat,
-    pub key: Option<webrender_api::ImageKey>,
+    pub key: Option<ImageKey>,
 }
 
 impl WebRenderImageInfo {
     #[inline]
     pub fn from_image(image: &Image) -> WebRenderImageInfo {
         WebRenderImageInfo {
             width: image.width,
             height: image.height,
@@ -1147,33 +1135,8 @@ impl SimpleMatrixDetection for Transform
         let (_0, _1) = (Zero::zero(), One::one());
         self.m11 == _1 && self.m12 == _0 && 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
     }
 }
 
-trait ToPointF {
-    fn to_pointf(&self) -> webrender_api::LayoutPoint;
-}
-
-impl ToPointF for Point2D<Au> {
-    fn to_pointf(&self) -> webrender_api::LayoutPoint {
-        webrender_api::LayoutPoint::new(self.x.to_f32_px(), self.y.to_f32_px())
-    }
-}
-
-trait ToRectF {
-    fn to_rectf(&self) -> webrender_api::LayoutRect;
-}
-
-impl ToRectF for Rect<Au> {
-    fn to_rectf(&self) -> webrender_api::LayoutRect {
-        let x = self.origin.x.to_f32_px();
-        let y = self.origin.y.to_f32_px();
-        let w = self.size.width.to_f32_px();
-        let h = self.size.height.to_f32_px();
-        let point = webrender_api::LayoutPoint::new(x, y);
-        let size = webrender_api::LayoutSize::new(w, h);
-        webrender_api::LayoutRect::new(point, size)
-    }
-}
--- a/servo/components/layout/block.rs
+++ b/servo/components/layout/block.rs
@@ -39,17 +39,17 @@ use flow::{ImmutableFlowUtils, LateAbsol
 use flow_list::FlowList;
 use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow, FragmentFlags};
 use gfx_traits::print_tree::PrintTree;
 use incremental::RelayoutMode;
 use layout_debug;
 use model::{AdjoiningMargins, CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo, MaybeAuto};
 use sequential;
 use serde::{Serialize, Serializer};
-use servo_geometry::max_rect;
+use servo_geometry::MaxRect;
 use std::cmp::{max, min};
 use std::fmt;
 use std::sync::Arc;
 use style::computed_values::box_sizing::T as BoxSizing;
 use style::computed_values::display::T as Display;
 use style::computed_values::float::T as Float;
 use style::computed_values::overflow_x::T as StyleOverflow;
 use style::computed_values::position::T as Position;
@@ -1950,17 +1950,17 @@ impl Flow for BlockFlow {
     }
 
     fn compute_stacking_relative_position(&mut self, _layout_context: &LayoutContext) {
         // FIXME (mbrubeck): Get the real container size, taking the container writing mode into
         // account.  Must handle vertical writing modes.
         let container_size = Size2D::new(self.base.block_container_inline_size, Au(0));
 
         if self.is_root() {
-            self.base.clip = max_rect();
+            self.base.clip = Rect::max_rect();
         }
 
         if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
             let position_start = self.base.position.start.to_physical(self.base.writing_mode,
                                                                       container_size);
 
             // Compute our position relative to the nearest ancestor stacking context. This will be
             // passed down later as part of containing block details for absolute descendants.
--- a/servo/components/layout/display_list/background.rs
+++ b/servo/components/layout/display_list/background.rs
@@ -18,17 +18,17 @@ use style::values::computed::{LengthOrPe
 use style::values::computed::Position;
 use style::values::computed::image::{EndingShape, LineDirection};
 use style::values::generics::background::BackgroundSize;
 use style::values::generics::image::{Circle, Ellipse, ShapeExtent};
 use style::values::generics::image::EndingShape as GenericEndingShape;
 use style::values::generics::image::GradientItem as GenericGradientItem;
 use style::values::specified::background::RepeatKeyword;
 use style::values::specified::position::{X, Y};
-use webrender_api::GradientStop;
+use webrender_api::{ExtendMode, GradientStop};
 
 /// A helper data structure for gradients.
 #[derive(Clone, Copy)]
 struct StopRun {
     start_offset: f32,
     end_offset: f32,
     start_index: usize,
     stop_count: usize,
@@ -365,16 +365,24 @@ fn convert_gradient_stops(gradient_items
         stops.push(GradientStop {
             offset: offset,
             color: stop.color.to_layout(),
         })
     }
     stops
 }
 
+fn as_gradient_extend_mode(repeating: bool) -> ExtendMode {
+    if repeating {
+        ExtendMode::Repeat
+    } else {
+        ExtendMode::Clamp
+    }
+}
+
 pub fn convert_linear_gradient(
     size: Size2D<Au>,
     stops: &[GradientItem],
     direction: LineDirection,
     repeating: bool,
 ) -> display_list::Gradient {
     let angle = match direction {
         LineDirection::Angle(angle) => angle.radians(),
@@ -426,20 +434,20 @@ pub fn convert_linear_gradient(
     // both directions, so the rendering is always correct.
     if !repeating {
         fix_gradient_stops(&mut stops);
     }
 
     let center = Point2D::new(size.width / 2, size.height / 2);
 
     display_list::Gradient {
-        start_point: center - delta,
-        end_point: center + delta,
+        start_point: (center - delta).to_layout(),
+        end_point: (center + delta).to_layout(),
         stops: stops,
-        repeating: repeating,
+        extend_mode: as_gradient_extend_mode(repeating),
     }
 }
 
 pub fn convert_radial_gradient(
     size: Size2D<Au>,
     stops: &[GradientItem],
     shape: EndingShape,
     center: Position,
@@ -468,20 +476,20 @@ pub fn convert_radial_gradient(
     let mut stops = convert_gradient_stops(stops, radius.width);
     // Repeating gradients have no last stops that can be ignored. So
     // fixup is not necessary but may actually break the gradient.
     if !repeating {
         fix_gradient_stops(&mut stops);
     }
 
     display_list::RadialGradient {
-        center: center,
-        radius: radius,
+        center: center.to_layout(),
+        radius: radius.to_layout(),
         stops: stops,
-        repeating: repeating,
+        extend_mode: as_gradient_extend_mode(repeating),
     }
 }
 
 #[inline]
 /// Duplicate the first and last stops if necessary.
 ///
 /// Explanation by pyfisch:
 /// If the last stop is at the same position as the previous stop the
--- a/servo/components/layout/display_list/builder.rs
+++ b/servo/components/layout/display_list/builder.rs
@@ -26,86 +26,76 @@ use fnv::FnvHashMap;
 use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ScannedTextFragmentInfo};
 use fragment::SpecificFragmentInfo;
 use gfx::display_list;
 use gfx::display_list::{BaseDisplayItem, BorderDetails, BorderDisplayItem, BLUR_INFLATION_FACTOR};
 use gfx::display_list::{BorderRadii, BoxShadowDisplayItem, ClipScrollNode};
 use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
 use gfx::display_list::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList};
 use gfx::display_list::{DisplayListSection, GradientDisplayItem, IframeDisplayItem, ImageBorder};
-use gfx::display_list::{ImageDisplayItem, LineDisplayItem, NormalBorder, OpaqueNode};
+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_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
 use inline::{InlineFlow, InlineFragmentNodeFlags};
 use ipc_channel::ipc;
 use list_item::ListItemFlow;
 use model::{self, MaybeAuto};
 use msg::constellation_msg::{BrowsingContextId, PipelineId};
 use net_traits::image::base::PixelFormat;
 use net_traits::image_cache::UsePlaceholder;
 use range::Range;
 use servo_config::opts;
-use servo_geometry::max_rect;
+use servo_geometry::MaxRect;
 use std::{cmp, f32};
 use std::default::Default;
 use std::mem;
 use std::sync::Arc;
 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_origin::single_value::T as BackgroundOrigin;
 use style::computed_values::border_style::T as BorderStyle;
 use style::computed_values::cursor;
-use style::computed_values::image_rendering::T as ImageRendering;
 use style::computed_values::overflow_x::T as StyleOverflow;
 use style::computed_values::pointer_events::T as PointerEvents;
 use style::computed_values::position::T as StylePosition;
 use style::computed_values::visibility::T as Visibility;
 use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode};
 use style::properties::ComputedValues;
-use style::properties::longhands::border_image_repeat::computed_value::RepeatKeyword;
 use style::properties::style_structs;
 use style::servo::restyle_damage::ServoRestyleDamage;
 use style::values::{Either, RGBA};
 use style::values::computed::{Gradient, NumberOrPercentage};
 use style::values::computed::effects::SimpleShadow;
 use style::values::generics::background::BackgroundSize;
 use style::values::generics::effects::Filter;
 use style::values::generics::image::{GradientKind, Image, PaintWorklet};
 use style_traits::CSSPixel;
 use style_traits::ToCss;
 use style_traits::cursor::Cursor;
 use table_cell::CollapsedBordersForCell;
-use webrender_api::{BoxShadowClipMode, ClipId, ClipMode, ColorF, ComplexClipRegion, LineStyle};
-use webrender_api::{LocalClip, RepeatMode, ScrollPolicy, ScrollSensitivity, StickyOffsetBounds};
+use webrender_api::{self, BoxShadowClipMode, ClipId, ClipMode, ColorF, ComplexClipRegion};
+use webrender_api::{ImageRendering, LayoutSize, LayoutVector2D, LineStyle};
+use webrender_api::{LocalClip, NormalBorder, ScrollPolicy, ScrollSensitivity, StickyOffsetBounds};
 
 trait ResolvePercentage {
     fn resolve(&self, length: u32) -> u32;
 }
 
 impl ResolvePercentage for NumberOrPercentage {
     fn resolve(&self, length: u32) -> u32 {
         match *self {
             NumberOrPercentage::Percentage(p) => (p.0 * length as f32).round() as u32,
             NumberOrPercentage::Number(n) => n.round() as u32,
         }
     }
 }
 
-fn convert_repeat_mode(from: RepeatKeyword) -> RepeatMode {
-    match from {
-        RepeatKeyword::Stretch => RepeatMode::Stretch,
-        RepeatKeyword::Repeat => RepeatMode::Repeat,
-        RepeatKeyword::Round => RepeatMode::Round,
-        RepeatKeyword::Space => RepeatMode::Space,
-    }
-}
-
 fn establishes_containing_block_for_absolute(
     flags: StackingContextCollectionFlags,
     positioning: StylePosition,
 ) -> bool {
     !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK) &&
         StylePosition::Static != positioning
 }
 
@@ -820,16 +810,27 @@ fn build_inner_border_box_for_border_rec
 fn calculate_inner_bounds(mut bounds: Rect<Au>, offsets: SideOffsets2D<Au>) -> Rect<Au> {
     bounds.origin.x += offsets.left;
     bounds.origin.y += offsets.top;
     bounds.size.width -= offsets.horizontal();
     bounds.size.height -= offsets.vertical();
     bounds
 }
 
+fn simple_normal_border(color: ColorF, style: webrender_api::BorderStyle) -> NormalBorder {
+    let side = webrender_api::BorderSide { color, style };
+    NormalBorder {
+        left: side,
+        right: side,
+        top: side,
+        bottom: side,
+        radius: webrender_api::BorderRadius::zero(),
+    }
+}
+
 fn calculate_inner_border_radii(
     mut radii: BorderRadii<Au>,
     offsets: SideOffsets2D<Au>,
 ) -> BorderRadii<Au> {
     radii.top_left.width = cmp::max(Au(0), radii.top_left.width - offsets.left);
     radii.bottom_left.width = cmp::max(Au(0), radii.bottom_left.width - offsets.left);
 
     radii.top_right.width = cmp::max(Au(0), radii.top_right.width - offsets.right);
@@ -1124,19 +1125,19 @@ impl FragmentDisplayListBuilding for Fra
             display_list_section,
         );
 
         debug!("(building display list) adding background image.");
         state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
             base: base,
             webrender_image: webrender_image,
             image_data: None,
-            stretch_size: placement.tile_size,
-            tile_spacing: placement.tile_spacing,
-            image_rendering: style.get_inheritedbox().image_rendering.clone(),
+            stretch_size: placement.tile_size.to_layout(),
+            tile_spacing: placement.tile_spacing.to_layout(),
+            image_rendering: style.get_inheritedbox().image_rendering.to_layout(),
         })));
     }
 
     fn get_webrender_image_for_paint_worklet(
         &self,
         state: &mut DisplayListBuildState,
         style: &ComputedValues,
         paint_worklet: &PaintWorklet,
@@ -1222,33 +1223,33 @@ impl FragmentDisplayListBuilding for Fra
                     placement.tile_size,
                     &gradient.items[..],
                     angle_or_corner,
                     gradient.repeating,
                 );
                 DisplayItem::Gradient(Box::new(GradientDisplayItem {
                     base: base,
                     gradient: gradient,
-                    tile: placement.tile_size,
-                    tile_spacing: placement.tile_spacing,
+                    tile: placement.tile_size.to_layout(),
+                    tile_spacing: placement.tile_spacing.to_layout(),
                 }))
             },
             GradientKind::Radial(shape, center, _angle) => {
                 let gradient = convert_radial_gradient(
                     placement.tile_size,
                     &gradient.items[..],
                     shape,
                     center,
                     gradient.repeating,
                 );
                 DisplayItem::RadialGradient(Box::new(RadialGradientDisplayItem {
                     base: base,
                     gradient: gradient,
-                    tile: placement.tile_size,
-                    tile_spacing: placement.tile_spacing,
+                    tile: placement.tile_size.to_layout(),
+                    tile_spacing: placement.tile_spacing.to_layout(),
                 }))
             },
         };
         state.add_display_item(display_item);
     }
 
     fn build_display_list_for_box_shadow_if_applicable(
         &self,
@@ -1274,28 +1275,28 @@ impl FragmentDisplayListBuilding for Fra
                 LocalClip::from(clip.to_layout()),
                 self.node,
                 style.get_cursor(Cursor::Default),
                 display_list_section,
             );
             let border_radius = build_border_radius(absolute_bounds, style.get_border());
             state.add_display_item(DisplayItem::BoxShadow(Box::new(BoxShadowDisplayItem {
                 base: base,
-                box_bounds: *absolute_bounds,
+                box_bounds: absolute_bounds.to_layout(),
                 color: box_shadow
                     .base
                     .color
                     .unwrap_or(style.get_color().color)
                     .to_layout(),
-                offset: Vector2D::new(
-                    Au::from(box_shadow.base.horizontal),
-                    Au::from(box_shadow.base.vertical),
+                offset: LayoutVector2D::new(
+                    box_shadow.base.horizontal.px(),
+                    box_shadow.base.vertical.px(),
                 ),
-                blur_radius: Au::from(box_shadow.base.blur),
-                spread_radius: Au::from(box_shadow.spread),
+                blur_radius: box_shadow.base.blur.px(),
+                spread_radius: box_shadow.spread.px(),
                 border_radius,
                 clip_mode: if box_shadow.inset {
                     BoxShadowClipMode::Inset
                 } else {
                     BoxShadowClipMode::Outset
                 },
             })));
         }
@@ -1368,30 +1369,41 @@ impl FragmentDisplayListBuilding for Fra
         let base = state.create_base_display_item(
             &bounds,
             LocalClip::from(clip.to_layout()),
             self.node,
             style.get_cursor(Cursor::Default),
             display_list_section,
         );
 
+        let border_radius = build_border_radius(&bounds, border_style_struct);
+
         match border_style_struct.border_image_source {
             Either::First(_) => {
                 state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
                     base: base,
                     border_widths: border.to_physical(style.writing_mode),
                     details: BorderDetails::Normal(NormalBorder {
-                        color: SideOffsets2D::new(
-                            colors.top.to_layout(),
-                            colors.right.to_layout(),
-                            colors.bottom.to_layout(),
-                            colors.left.to_layout(),
-                        ),
-                        style: border_style,
-                        radius: build_border_radius(&bounds, border_style_struct),
+                        left: webrender_api::BorderSide {
+                            color: colors.left.to_layout(),
+                            style: border_style.left.to_layout(),
+                        },
+                        right: webrender_api::BorderSide {
+                            color: colors.right.to_layout(),
+                            style: border_style.right.to_layout(),
+                        },
+                        top: webrender_api::BorderSide {
+                            color: colors.top.to_layout(),
+                            style: border_style.top.to_layout(),
+                        },
+                        bottom: webrender_api::BorderSide {
+                            color: colors.bottom.to_layout(),
+                            style: border_style.bottom.to_layout(),
+                        },
+                        radius: border_radius.to_border_radius(),
                     }),
                 })));
             },
             Either::Second(Image::Gradient(ref gradient)) => {
                 let border_widths = border.to_physical(style.writing_mode);
                 let details = match gradient.kind {
                     GradientKind::Linear(angle_or_corner) => {
                         BorderDetails::Gradient(display_list::GradientBorder {
@@ -1427,37 +1439,34 @@ impl FragmentDisplayListBuilding for Fra
             },
             Either::Second(Image::PaintWorklet(ref paint_worklet)) => {
                 // TODO: this size should be increased by border-image-outset
                 let size = self.border_box.size.to_physical(style.writing_mode);
                 let webrender_image =
                     self.get_webrender_image_for_paint_worklet(state, style, paint_worklet, size);
                 if let Some(webrender_image) = webrender_image {
                     let corners = &border_style_struct.border_image_slice.offsets;
+                    let border_image_repeat = &border_style_struct.border_image_repeat;
 
                     state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
                         base: base,
                         border_widths: border.to_physical(style.writing_mode),
                         details: BorderDetails::Image(ImageBorder {
                             image: webrender_image,
                             fill: border_style_struct.border_image_slice.fill,
                             slice: SideOffsets2D::new(
                                 corners.0.resolve(webrender_image.height),
                                 corners.1.resolve(webrender_image.width),
                                 corners.2.resolve(webrender_image.height),
                                 corners.3.resolve(webrender_image.width),
                             ),
                             // TODO(gw): Support border-image-outset
                             outset: SideOffsets2D::zero(),
-                            repeat_horizontal: convert_repeat_mode(
-                                border_style_struct.border_image_repeat.0,
-                            ),
-                            repeat_vertical: convert_repeat_mode(
-                                border_style_struct.border_image_repeat.1,
-                            ),
+                            repeat_horizontal: border_image_repeat.0.to_layout(),
+                            repeat_vertical: border_image_repeat.1.to_layout(),
                         }),
                     })));
                 }
             },
             Either::Second(Image::Rect(..)) => {
                 // TODO: Handle border-image with `-moz-image-rect`.
             },
             Either::Second(Image::Element(..)) => {
@@ -1467,37 +1476,34 @@ impl FragmentDisplayListBuilding for Fra
                 if let Some(url) = image_url.url() {
                     let webrender_image = state.layout_context.get_webrender_image_for_url(
                         self.node,
                         url.clone(),
                         UsePlaceholder::No,
                     );
                     if let Some(webrender_image) = webrender_image {
                         let corners = &border_style_struct.border_image_slice.offsets;
+                        let border_image_repeat = &border_style_struct.border_image_repeat;
 
                         state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
                             base: base,
                             border_widths: border.to_physical(style.writing_mode),
                             details: BorderDetails::Image(ImageBorder {
                                 image: webrender_image,
                                 fill: border_style_struct.border_image_slice.fill,
                                 slice: SideOffsets2D::new(
                                     corners.0.resolve(webrender_image.height),
                                     corners.1.resolve(webrender_image.width),
                                     corners.2.resolve(webrender_image.height),
                                     corners.3.resolve(webrender_image.width),
                                 ),
                                 // TODO(gw): Support border-image-outset
                                 outset: SideOffsets2D::zero(),
-                                repeat_horizontal: convert_repeat_mode(
-                                    border_style_struct.border_image_repeat.0,
-                                ),
-                                repeat_vertical: convert_repeat_mode(
-                                    border_style_struct.border_image_repeat.1,
-                                ),
+                                repeat_horizontal: border_image_repeat.0.to_layout(),
+                                repeat_vertical: border_image_repeat.1.to_layout(),
                             }),
                         })));
                     }
                 }
             },
         }
     }
 
@@ -1539,21 +1545,17 @@ impl FragmentDisplayListBuilding for Fra
             LocalClip::from(clip.to_layout()),
             self.node,
             style.get_cursor(Cursor::Default),
             DisplayListSection::Outlines,
         );
         state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
             base: base,
             border_widths: SideOffsets2D::new_all_same(width),
-            details: BorderDetails::Normal(NormalBorder {
-                color: SideOffsets2D::new_all_same(color),
-                style: SideOffsets2D::new_all_same(outline_style),
-                radius: Default::default(),
-            }),
+            details: BorderDetails::Normal(simple_normal_border(color, outline_style.to_layout())),
         })));
     }
 
     fn build_debug_borders_around_text_fragments(
         &self,
         state: &mut DisplayListBuildState,
         style: &ComputedValues,
         stacking_relative_border_box: &Rect<Au>,
@@ -1570,21 +1572,20 @@ impl FragmentDisplayListBuilding for Fra
             LocalClip::from(clip.to_layout()),
             self.node,
             style.get_cursor(Cursor::Default),
             DisplayListSection::Content,
         );
         state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
             base: base,
             border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
-            details: BorderDetails::Normal(NormalBorder {
-                color: SideOffsets2D::new_all_same(ColorF::rgb(0, 0, 200)),
-                style: SideOffsets2D::new_all_same(BorderStyle::Solid),
-                radius: Default::default(),
-            }),
+            details: BorderDetails::Normal(simple_normal_border(
+                ColorF::rgb(0, 0, 200),
+                webrender_api::BorderStyle::Solid,
+            )),
         })));
 
         // Draw a rectangle representing the baselines.
         let mut baseline = LogicalRect::from_physical(
             self.style.writing_mode,
             *stacking_relative_content_box,
             container_size,
         );
@@ -1618,21 +1619,20 @@ impl FragmentDisplayListBuilding for Fra
             LocalClip::from(clip.to_layout()),
             self.node,
             self.style.get_cursor(Cursor::Default),
             DisplayListSection::Content,
         );
         state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
             base: base,
             border_widths: SideOffsets2D::new_all_same(Au::from_px(1)),
-            details: BorderDetails::Normal(NormalBorder {
-                color: SideOffsets2D::new_all_same(ColorF::rgb(0, 0, 200)),
-                style: SideOffsets2D::new_all_same(BorderStyle::Solid),
-                radius: Default::default(),
-            }),
+            details: BorderDetails::Normal(simple_normal_border(
+                ColorF::rgb(0, 0, 200),
+                webrender_api::BorderStyle::Solid,
+            )),
         })));
     }
 
     fn build_display_items_for_selection_if_necessary(
         &self,
         state: &mut DisplayListBuildState,
         stacking_relative_border_box: &Rect<Au>,
         display_list_section: DisplayListSection,
@@ -1991,19 +1991,19 @@ impl FragmentDisplayListBuilding for Fra
                         self.node,
                         self.style.get_cursor(Cursor::Default),
                         DisplayListSection::Content,
                     );
                     state.add_display_item(DisplayItem::Image(Box::new(ImageDisplayItem {
                         base: base,
                         webrender_image: WebRenderImageInfo::from_image(image),
                         image_data: Some(Arc::new(image.bytes.clone())),
-                        stretch_size: stacking_relative_content_box.size,
-                        tile_spacing: Size2D::zero(),
-                        image_rendering: self.style.get_inheritedbox().image_rendering.clone(),
+                        stretch_size: stacking_relative_content_box.size.to_layout(),
+                        tile_spacing: LayoutSize::zero(),
+                        image_rendering: self.style.get_inheritedbox().image_rendering.to_layout(),
                     })));
                 }
             },
             SpecificFragmentInfo::Canvas(ref canvas_fragment_info) => {
                 let computed_width = canvas_fragment_info.dom_width.to_px();
                 let computed_height = canvas_fragment_info.dom_height.to_px();
 
                 let (image_key, format) = match canvas_fragment_info.source {
@@ -2032,18 +2032,18 @@ impl FragmentDisplayListBuilding for Fra
                     base: base,
                     webrender_image: WebRenderImageInfo {
                         width: computed_width as u32,
                         height: computed_height as u32,
                         format: format,
                         key: Some(image_key),
                     },
                     image_data: None,
-                    stretch_size: stacking_relative_content_box.size,
-                    tile_spacing: Size2D::zero(),
+                    stretch_size: stacking_relative_content_box.size.to_layout(),
+                    tile_spacing: LayoutSize::zero(),
                     image_rendering: ImageRendering::Auto,
                 }));
 
                 state.add_display_item(display_item);
             },
             SpecificFragmentInfo::UnscannedText(_) => {
                 panic!("Shouldn't see unscanned fragments here.")
             },
@@ -2155,18 +2155,18 @@ impl FragmentDisplayListBuilding for Fra
         // NB: According to CSS-BACKGROUNDS, text shadows render in *reverse* order (front
         // to back).
 
         // Shadows
         for shadow in text_shadows.iter().rev() {
             state.add_display_item(DisplayItem::PushTextShadow(Box::new(
                 PushTextShadowDisplayItem {
                     base: base.clone(),
-                    blur_radius: Au::from(shadow.blur),
-                    offset: Vector2D::new(Au::from(shadow.horizontal), Au::from(shadow.vertical)),
+                    blur_radius: shadow.blur.px(),
+                    offset: LayoutVector2D::new(shadow.horizontal.px(), shadow.vertical.px()),
                     color: shadow
                         .color
                         .unwrap_or(self.style().get_color().color)
                         .to_layout(),
                 },
             )));
         }
 
@@ -2376,17 +2376,17 @@ impl SavedStackingContextCollectionState
         }
     }
 
     fn switch_to_containing_block_clip(&mut self, state: &mut StackingContextCollectionState) {
         let clip = state
             .containing_block_clip_stack
             .last()
             .cloned()
-            .unwrap_or_else(max_rect);
+            .unwrap_or_else(MaxRect::max_rect);
         state.clip_stack.push(clip);
         self.clips_pushed += 1;
     }
 
     fn restore(self, state: &mut StackingContextCollectionState) {
         state.current_stacking_context_id = self.stacking_context_id;
         state.current_real_stacking_context_id = self.real_stacking_context_id;
         state.current_clipping_and_scrolling = self.clipping_and_scrolling;
@@ -2442,28 +2442,28 @@ impl BlockFlowDisplayListBuilding for Bl
 
         let perspective = self.fragment
             .perspective_matrix(&border_box)
             .unwrap_or_else(Transform3D::identity);
         let transform = transform.pre_mul(&perspective).inverse();
 
         let origin = &border_box.origin;
         let transform_clip = |clip: &Rect<Au>| {
-            if *clip == max_rect() {
+            if *clip == Rect::max_rect() {
                 return *clip;
             }
 
             match transform {
                 Some(transform) if transform.m13 != 0.0 || transform.m23 != 0.0 => {
                     // We cannot properly handle perspective transforms, because there may be a
                     // situation where an element is transformed from outside the clip into the
                     // clip region. Here we don't have enough information to detect when that is
                     // happening. For the moment we just punt on trying to optimize the display
                     // list for those cases.
-                    max_rect()
+                    Rect::max_rect()
                 },
                 Some(transform) => {
                     let clip = Rect::new(
                         Point2D::new(
                             (clip.origin.x - origin.x).to_f32_px(),
                             (clip.origin.y - origin.y).to_f32_px(),
                         ),
                         Size2D::new(clip.size.width.to_f32_px(), clip.size.height.to_f32_px()),
@@ -2568,17 +2568,17 @@ impl BlockFlowDisplayListBuilding for Bl
         let containing_clipping_and_scrolling = match self.positioning() {
             StylePosition::Absolute => {
                 preserved_state.switch_to_containing_block_clip(state);
                 state.current_clipping_and_scrolling =
                     state.containing_block_clipping_and_scrolling;
                 state.containing_block_clipping_and_scrolling
             },
             StylePosition::Fixed => {
-                preserved_state.push_clip(state, &max_rect(), StylePosition::Fixed);
+                preserved_state.push_clip(state, &Rect::max_rect(), StylePosition::Fixed);
                 state.current_clipping_and_scrolling
             },
             _ => state.current_clipping_and_scrolling,
         };
         self.base.clipping_and_scrolling = Some(containing_clipping_and_scrolling);
 
         let stacking_relative_border_box = if self.fragment.establishes_stacking_context() {
             self.stacking_relative_border_box(CoordinateSystem::Own)
@@ -2594,17 +2594,21 @@ impl BlockFlowDisplayListBuilding for Bl
             self.setup_clip_scroll_node_for_position(state, &stacking_relative_border_box);
             self.setup_clip_scroll_node_for_overflow(state, &stacking_relative_border_box);
             self.setup_clip_scroll_node_for_css_clip(
                 state,
                 preserved_state,
                 &stacking_relative_border_box,
             );
         }
-        self.base.clip = state.clip_stack.last().cloned().unwrap_or_else(max_rect);
+        self.base.clip = state
+            .clip_stack
+            .last()
+            .cloned()
+            .unwrap_or_else(Rect::max_rect);
 
         // We keep track of our position so that any stickily positioned elements can
         // properly determine the extent of their movement relative to scrolling containers.
         if !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK) {
             let border_box = if self.fragment.establishes_stacking_context() {
                 stacking_relative_border_box
             } else {
                 self.stacking_relative_border_box(CoordinateSystem::Own)
@@ -2964,17 +2968,21 @@ pub trait InlineFlowDisplayListBuilding 
     );
     fn build_display_list_for_inline(&mut self, state: &mut DisplayListBuildState);
 }
 
 impl InlineFlowDisplayListBuilding for InlineFlow {
     fn collect_stacking_contexts_for_inline(&mut self, state: &mut StackingContextCollectionState) {
         self.base.stacking_context_id = state.current_stacking_context_id;
         self.base.clipping_and_scrolling = Some(state.current_clipping_and_scrolling);
-        self.base.clip = state.clip_stack.last().cloned().unwrap_or_else(max_rect);
+        self.base.clip = state
+            .clip_stack
+            .last()
+            .cloned()
+            .unwrap_or_else(Rect::max_rect);
 
         for fragment in self.fragments.fragments.iter_mut() {
             let previous_cb_clipping_and_scrolling = state.containing_block_clipping_and_scrolling;
             if establishes_containing_block_for_absolute(
                 StackingContextCollectionFlags::empty(),
                 fragment.style.get_box().position,
             ) {
                 state.containing_block_clipping_and_scrolling =
@@ -3136,21 +3144,20 @@ impl BaseFlowDisplayListBuilding for Bas
             LocalClip::from(self.clip.to_layout()),
             node,
             None,
             DisplayListSection::Content,
         );
         state.add_display_item(DisplayItem::Border(Box::new(BorderDisplayItem {
             base: base,
             border_widths: SideOffsets2D::new_all_same(Au::from_px(2)),
-            details: BorderDetails::Normal(NormalBorder {
-                color: SideOffsets2D::new_all_same(color),
-                style: SideOffsets2D::new_all_same(BorderStyle::Solid),
-                radius: BorderRadii::all_same(Au(0)),
-            }),
+            details: BorderDetails::Normal(simple_normal_border(
+                color,
+                webrender_api::BorderStyle::Solid,
+            )),
         })));
     }
 }
 
 trait ComputedValuesCursorUtility {
     fn get_cursor(&self, default_cursor: Cursor) -> Option<Cursor>;
 }
 
--- a/servo/components/layout/display_list/conversions.rs
+++ b/servo/components/layout/display_list/conversions.rs
@@ -2,16 +2,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 use app_units::Au;
 use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Vector2D};
 use style::computed_values::image_rendering::T as ImageRendering;
 use style::computed_values::mix_blend_mode::T as MixBlendMode;
 use style::computed_values::transform_style::T as TransformStyle;
+use style::properties::longhands::border_image_repeat::RepeatKeyword;
 use style::values::RGBA;
 use style::values::computed::{BorderStyle, Filter};
 use style::values::generics::effects::Filter as GenericFilter;
 use webrender_api as wr;
 
 pub trait ToLayout {
     type Type;
     fn to_layout(&self) -> Self::Type;
@@ -145,8 +146,20 @@ impl ToLayout for Size2D<Au> {
 }
 
 impl ToLayout for Vector2D<Au> {
     type Type = wr::LayoutVector2D;
     fn to_layout(&self) -> Self::Type {
         wr::LayoutVector2D::new(self.x.to_f32_px(), self.y.to_f32_px())
     }
 }
+
+impl ToLayout for RepeatKeyword {
+    type Type = wr::RepeatMode;
+    fn to_layout(&self) -> Self::Type {
+        match *self {
+            RepeatKeyword::Stretch => wr::RepeatMode::Stretch,
+            RepeatKeyword::Repeat => wr::RepeatMode::Repeat,
+            RepeatKeyword::Round => wr::RepeatMode::Round,
+            RepeatKeyword::Space => wr::RepeatMode::Space,
+        }
+    }
+}
--- a/servo/components/layout/display_list/webrender_helpers.rs
+++ b/servo/components/layout/display_list/webrender_helpers.rs
@@ -10,17 +10,17 @@
 use app_units::Au;
 use display_list::ToLayout;
 use euclid::Point2D;
 use gfx::display_list::{BorderDetails, BorderRadii, ClipScrollNode};
 use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingRegion, DisplayItem};
 use gfx::display_list::{DisplayList, StackingContextType};
 use msg::constellation_msg::PipelineId;
 use webrender_api::{self, ClipAndScrollInfo, ClipId, ClipMode, ComplexClipRegion};
-use webrender_api::{DisplayListBuilder, ExtendMode, LayoutTransform};
+use webrender_api::{DisplayListBuilder, LayoutTransform};
 
 pub trait WebRenderDisplayListConverter {
     fn convert_to_webrender(&self, pipeline_id: PipelineId) -> DisplayListBuilder;
 }
 
 trait WebRenderDisplayItemConverter {
     fn prim_info(&self) -> webrender_api::LayoutPrimitiveInfo;
     fn convert_to_webrender(
@@ -155,57 +155,34 @@ impl WebRenderDisplayItemConverter for D
                         item.text_run.font_key,
                         item.text_color,
                         None,
                     );
                 }
             },
             DisplayItem::Image(ref item) => {
                 if let Some(id) = item.webrender_image.key {
-                    if item.stretch_size.width > Au(0) && item.stretch_size.height > Au(0) {
+                    if item.stretch_size.width > 0.0 && item.stretch_size.height > 0.0 {
                         builder.push_image(
                             &self.prim_info(),
-                            item.stretch_size.to_layout(),
-                            item.tile_spacing.to_layout(),
-                            item.image_rendering.to_layout(),
+                            item.stretch_size,
+                            item.tile_spacing,
+                            item.image_rendering,
                             webrender_api::AlphaType::PremultipliedAlpha,
                             id,
                         );
                     }
                 }
             },
             DisplayItem::Border(ref item) => {
                 let widths = item.border_widths.to_layout();
 
                 let details = match item.details {
                     BorderDetails::Normal(ref border) => {
-                        let left = webrender_api::BorderSide {
-                            color: border.color.left,
-                            style: border.style.left.to_layout(),
-                        };
-                        let top = webrender_api::BorderSide {
-                            color: border.color.top,
-                            style: border.style.top.to_layout(),
-                        };
-                        let right = webrender_api::BorderSide {
-                            color: border.color.right,
-                            style: border.style.right.to_layout(),
-                        };
-                        let bottom = webrender_api::BorderSide {
-                            color: border.color.bottom,
-                            style: border.style.bottom.to_layout(),
-                        };
-                        let radius = border.radius.to_border_radius();
-                        webrender_api::BorderDetails::Normal(webrender_api::NormalBorder {
-                            left: left,
-                            top: top,
-                            right: right,
-                            bottom: bottom,
-                            radius: radius,
-                        })
+                        webrender_api::BorderDetails::Normal(*border)
                     },
                     BorderDetails::Image(ref image) => match image.image.key {
                         None => return,
                         Some(key) => {
                             webrender_api::BorderDetails::Image(webrender_api::ImageBorder {
                                 image_key: key,
                                 patch: webrender_api::NinePatchDescriptor {
                                     width: image.image.width,
@@ -215,124 +192,94 @@ impl WebRenderDisplayItemConverter for D
                                 fill: image.fill,
                                 outset: image.outset,
                                 repeat_horizontal: image.repeat_horizontal,
                                 repeat_vertical: image.repeat_vertical,
                             })
                         },
                     },
                     BorderDetails::Gradient(ref gradient) => {
-                        let extend_mode = if gradient.gradient.repeating {
-                            ExtendMode::Repeat
-                        } else {
-                            ExtendMode::Clamp
-                        };
                         webrender_api::BorderDetails::Gradient(webrender_api::GradientBorder {
                             gradient: builder.create_gradient(
-                                gradient.gradient.start_point.to_layout(),
-                                gradient.gradient.end_point.to_layout(),
+                                gradient.gradient.start_point,
+                                gradient.gradient.end_point,
                                 gradient.gradient.stops.clone(),
-                                extend_mode,
+                                gradient.gradient.extend_mode,
                             ),
                             outset: gradient.outset,
                         })
                     },
                     BorderDetails::RadialGradient(ref gradient) => {
-                        let extend_mode = if gradient.gradient.repeating {
-                            ExtendMode::Repeat
-                        } else {
-                            ExtendMode::Clamp
-                        };
                         webrender_api::BorderDetails::RadialGradient(
                             webrender_api::RadialGradientBorder {
                                 gradient: builder.create_radial_gradient(
-                                    gradient.gradient.center.to_layout(),
-                                    gradient.gradient.radius.to_layout(),
+                                    gradient.gradient.center,
+                                    gradient.gradient.radius,
                                     gradient.gradient.stops.clone(),
-                                    extend_mode,
+                                    gradient.gradient.extend_mode,
                                 ),
                                 outset: gradient.outset,
                             },
                         )
                     },
                 };
 
                 builder.push_border(&self.prim_info(), widths, details);
             },
             DisplayItem::Gradient(ref item) => {
-                let start_point = item.gradient.start_point.to_layout();
-                let end_point = item.gradient.end_point.to_layout();
-                let extend_mode = if item.gradient.repeating {
-                    ExtendMode::Repeat
-                } else {
-                    ExtendMode::Clamp
-                };
                 let gradient = builder.create_gradient(
-                    start_point,
-                    end_point,
+                    item.gradient.start_point,
+                    item.gradient.end_point,
                     item.gradient.stops.clone(),
-                    extend_mode,
+                    item.gradient.extend_mode,
                 );
-                builder.push_gradient(
-                    &self.prim_info(),
-                    gradient,
-                    item.tile.to_layout(),
-                    item.tile_spacing.to_layout(),
-                );
+                builder.push_gradient(&self.prim_info(), gradient, item.tile, item.tile_spacing);
             },
             DisplayItem::RadialGradient(ref item) => {
-                let center = item.gradient.center.to_layout();
-                let radius = item.gradient.radius.to_layout();
-                let extend_mode = if item.gradient.repeating {
-                    ExtendMode::Repeat
-                } else {
-                    ExtendMode::Clamp
-                };
                 let gradient = builder.create_radial_gradient(
-                    center,
-                    radius,
+                    item.gradient.center,
+                    item.gradient.radius,
                     item.gradient.stops.clone(),
-                    extend_mode,
+                    item.gradient.extend_mode,
                 );
                 builder.push_radial_gradient(
                     &self.prim_info(),
                     gradient,
-                    item.tile.to_layout(),
-                    item.tile_spacing.to_layout(),
+                    item.tile,
+                    item.tile_spacing,
                 );
             },
             DisplayItem::Line(ref item) => {
                 builder.push_line(
                     &self.prim_info(),
                     // TODO(gw): Use a better estimate for wavy line thickness.
                     (0.33 * item.base.bounds.size.height.to_f32_px()).ceil(),
                     webrender_api::LineOrientation::Horizontal,
                     &item.color,
                     item.style,
                 );
             },
             DisplayItem::BoxShadow(ref item) => {
-                let box_bounds = item.box_bounds.to_layout();
                 builder.push_box_shadow(
                     &self.prim_info(),
-                    box_bounds,
-                    item.offset.to_layout(),
+                    item.box_bounds,
+                    item.offset,
                     item.color,
-                    item.blur_radius.to_f32_px(),
-                    item.spread_radius.to_f32_px(),
+                    item.blur_radius,
+                    item.spread_radius,
                     item.border_radius.to_border_radius(),
                     item.clip_mode,
                 );
             },
             DisplayItem::PushTextShadow(ref item) => {
                 builder.push_shadow(
                     &self.prim_info(),
                     webrender_api::Shadow {
-                        blur_radius: item.blur_radius.to_f32_px(),
-                        offset: item.offset.to_layout(),
+                        blur_radius: item.blur_radius,
+                        offset: item.offset,
                         color: item.color,
                     },
                 );
             },
             DisplayItem::PopAllTextShadows(_) => {
                 builder.pop_all_shadows();
             },
             DisplayItem::Iframe(ref item) => {
--- a/servo/components/layout/flow.rs
+++ b/servo/components/layout/flow.rs
@@ -38,17 +38,17 @@ use fragment::{CoordinateSystem, Fragmen
 use gfx::display_list::ClippingAndScrolling;
 use gfx_traits::StackingContextId;
 use gfx_traits::print_tree::PrintTree;
 use inline::InlineFlow;
 use model::{CollapsibleMargins, IntrinsicISizes, MarginCollapseInfo};
 use multicol::MulticolFlow;
 use parallel::FlowParallelInfo;
 use serde::ser::{Serialize, SerializeStruct, Serializer};
-use servo_geometry::{au_rect_to_f32_rect, f32_rect_to_au_rect, max_rect};
+use servo_geometry::{au_rect_to_f32_rect, f32_rect_to_au_rect, MaxRect};
 use std::fmt;
 use std::iter::Zip;
 use std::slice::IterMut;
 use std::sync::Arc;
 use std::sync::atomic::Ordering;
 use style::computed_values::clear::T as Clear;
 use style::computed_values::float::T as Float;
 use style::computed_values::overflow_x::T as StyleOverflow;
@@ -1057,17 +1057,17 @@ impl BaseFlow {
             speculated_float_placement_in: SpeculatedFloatPlacement::zero(),
             speculated_float_placement_out: SpeculatedFloatPlacement::zero(),
             block_container_inline_size: Au(0),
             block_container_writing_mode: writing_mode,
             block_container_explicit_block_size: None,
             absolute_cb: ContainingBlockLink::new(),
             early_absolute_position_info: EarlyAbsolutePositionInfo::new(writing_mode),
             late_absolute_position_info: LateAbsolutePositionInfo::new(),
-            clip: max_rect(),
+            clip: MaxRect::max_rect(),
             flags: flags,
             writing_mode: writing_mode,
             thread_id: 0,
             stacking_context_id: StackingContextId::root(),
             clipping_and_scrolling: None,
         }
     }
 
--- a/servo/components/layout_thread/lib.rs
+++ b/servo/components/layout_thread/lib.rs
@@ -103,17 +103,17 @@ use script_traits::{DrawAPaintImageResul
 use script_traits::{ScrollState, UntrustedNodeAddress};
 use script_traits::Painter;
 use selectors::Element;
 use servo_arc::Arc as ServoArc;
 use servo_atoms::Atom;
 use servo_config::opts;
 use servo_config::prefs::PREFS;
 use servo_config::resource_files::read_resource_file;
-use servo_geometry::max_rect;
+use servo_geometry::MaxRect;
 use servo_url::ServoUrl;
 use std::borrow::ToOwned;
 use std::cell::{Cell, RefCell};
 use std::collections::HashMap;
 use std::mem as std_mem;
 use std::ops::{Deref, DerefMut};
 use std::process;
 use std::sync::{Arc, Mutex, MutexGuard};
@@ -1462,17 +1462,17 @@ impl LayoutThread {
 
     fn tick_animations(&mut self, rw_data: &mut LayoutThreadData) {
         if opts::get().relayout_event {
             println!("**** pipeline={}\tForDisplay\tSpecial\tAnimationTick", self.id);
         }
 
         if let Some(mut root_flow) = self.root_flow.borrow().clone() {
             let reflow_info = Reflow {
-                page_clip_rect: max_rect(),
+                page_clip_rect: Rect::max_rect(),
             };
 
             // Unwrap here should not panic since self.root_flow is only ever set to Some(_)
             // in handle_reflow() where self.document_shared_lock is as well.
             let author_shared_lock = self.document_shared_lock.clone().unwrap();
             let author_guard = author_shared_lock.read();
             let ua_or_user_guard = UA_STYLESHEETS.shared_lock.read();
             let guards = StylesheetGuards {
--- a/servo/components/malloc_size_of/lib.rs
+++ b/servo/components/malloc_size_of/lib.rs
@@ -711,30 +711,42 @@ impl MallocSizeOf for url::Host {
         match *self {
             url::Host::Domain(ref s) => s.size_of(ops),
             _ => 0,
         }
     }
 }
 
 #[cfg(feature = "servo")]
+malloc_size_of_is_0!(webrender_api::BorderStyle);
+#[cfg(feature = "servo")]
+malloc_size_of_is_0!(webrender_api::BoxShadowClipMode);
+#[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::ClipAndScrollInfo);
 #[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::ClipId);
 #[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::ColorF);
 #[cfg(feature = "servo")]
+malloc_size_of_is_0!(webrender_api::ExtendMode);
+#[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::GradientStop);
 #[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::ImageKey);
 #[cfg(feature = "servo")]
+malloc_size_of_is_0!(webrender_api::ImageRendering);
+#[cfg(feature = "servo")]
+malloc_size_of_is_0!(webrender_api::LineStyle);
+#[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::LocalClip);
 #[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::MixBlendMode);
 #[cfg(feature = "servo")]
+malloc_size_of_is_0!(webrender_api::NormalBorder);
+#[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::RepeatMode);
 #[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::ScrollPolicy);
 #[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::ScrollSensitivity);
 #[cfg(feature = "servo")]
 malloc_size_of_is_0!(webrender_api::StickyOffsetBounds);
 #[cfg(feature = "servo")]
--- a/servo/components/script/dom/window.rs
+++ b/servo/components/script/dom/window.rs
@@ -79,17 +79,17 @@ use script_thread::{ImageCacheMsg, MainT
 use script_thread::{ScriptThread, SendableMainThreadScriptChan};
 use script_traits::{ConstellationControlMsg, DocumentState, LoadData, MozBrowserEvent};
 use script_traits::{ScriptToConstellationChan, ScriptMsg, ScrollState, TimerEvent, TimerEventId};
 use script_traits::{TimerSchedulerMsg, UntrustedNodeAddress, WindowSizeData, WindowSizeType};
 use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult};
 use selectors::attr::CaseSensitivity;
 use servo_config::opts;
 use servo_config::prefs::PREFS;
-use servo_geometry::{f32_rect_to_au_rect, max_rect};
+use servo_geometry::{f32_rect_to_au_rect, MaxRect};
 use servo_url::{Host, MutableOrigin, ImmutableOrigin, ServoUrl};
 use std::borrow::ToOwned;
 use std::cell::Cell;
 use std::collections::{HashMap, HashSet};
 use std::collections::hash_map::Entry;
 use std::default::Default;
 use std::env;
 use std::fs;
@@ -1601,25 +1601,25 @@ impl Window {
         let proposed_clip_rect = f32_rect_to_au_rect(
             viewport.inflate(viewport.size.width * VIEWPORT_EXPANSION,
             viewport.size.height * VIEWPORT_EXPANSION));
         let clip_rect = self.page_clip_rect.get();
         if proposed_clip_rect == clip_rect {
             return false;
         }
 
-        let had_clip_rect = clip_rect != max_rect();
+        let had_clip_rect = clip_rect != MaxRect::max_rect();
         if had_clip_rect && !should_move_clip_rect(clip_rect, viewport) {
             return false;
         }
 
         self.page_clip_rect.set(proposed_clip_rect);
 
         // If we didn't have a clip rect, the previous display doesn't need rebuilding
-        // because it was built for infinite clip (max_rect()).
+        // because it was built for infinite clip (MaxRect::amax_rect()).
         had_clip_rect
     }
 
     // https://html.spec.whatwg.org/multipage/#accessing-other-browsing-contexts
     pub fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<DomRoot<Window>> {
         None
     }
 
@@ -1830,17 +1830,17 @@ impl Window {
             session_storage: Default::default(),
             local_storage: Default::default(),
             status: DomRefCell::new(DOMString::new()),
             parent_info,
             dom_static: GlobalStaticData::new(),
             js_runtime: DomRefCell::new(Some(runtime.clone())),
             bluetooth_thread,
             bluetooth_extra_permission_data: BluetoothExtraPermissionData::new(),
-            page_clip_rect: Cell::new(max_rect()),
+            page_clip_rect: Cell::new(MaxRect::max_rect()),
             resize_event: Default::default(),
             layout_chan,
             layout_rpc,
             window_size: Cell::new(window_size),
             current_viewport: Cell::new(Rect::zero()),
             suppress_reflow: Cell::new(true),
             pending_reflow_count: Default::default(),
             current_state: Cell::new(WindowState::Alive),
--- a/servo/tests/unit/metrics/Cargo.toml
+++ b/servo/tests/unit/metrics/Cargo.toml
@@ -5,19 +5,18 @@ authors = ["The Servo Project Developers
 license = "MPL-2.0"
 
 [lib]
 name = "metrics_tests"
 path = "lib.rs"
 doctest = false
 
 [dependencies]
-euclid = "0.16"
 gfx = {path = "../../../components/gfx"}
 gfx_traits = {path = "../../../components/gfx_traits"}
 ipc-channel = "0.9"
 metrics = {path = "../../../components/metrics"}
 msg = {path = "../../../components/msg"}
 net_traits = {path = "../../../components/net_traits"}
 profile_traits = {path = "../../../components/profile_traits"}
 servo_url = {path = "../../../components/url"}
-style = {path = "../../../components/style"}
 time = "0.1.12"
+webrender_api = {git = "https://github.com/servo/webrender"}
--- a/servo/tests/unit/metrics/lib.rs
+++ b/servo/tests/unit/metrics/lib.rs
@@ -1,20 +1,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #![cfg(test)]
 
-extern crate euclid;
 extern crate gfx;
 extern crate gfx_traits;
 extern crate ipc_channel;
 extern crate metrics;
 extern crate msg;
 extern crate net_traits;
 extern crate profile_traits;
 extern crate servo_url;
-extern crate style;
 extern crate time;
+extern crate webrender_api;
 
 mod interactive_time;
 mod paint_time;
--- a/servo/tests/unit/metrics/paint_time.rs
+++ b/servo/tests/unit/metrics/paint_time.rs
@@ -1,24 +1,23 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-use euclid::Size2D;
 use gfx::display_list::{BaseDisplayItem, WebRenderImageInfo};
 use gfx::display_list::{DisplayItem, DisplayList, ImageDisplayItem};
 use gfx_traits::Epoch;
 use ipc_channel::ipc;
 use metrics::{PaintTimeMetrics, ProfilerMetadataFactory, ProgressiveWebMetric};
 use msg::constellation_msg::TEST_PIPELINE_ID;
 use net_traits::image::base::PixelFormat;
 use profile_traits::time::{ProfilerChan, TimerMetadata};
 use servo_url::ServoUrl;
-use style::computed_values::image_rendering::T as ImageRendering;
 use time;
+use webrender_api::{ImageRendering, LayoutSize};
 
 struct DummyProfilerMetadataFactory {}
 impl ProfilerMetadataFactory for DummyProfilerMetadataFactory {
     fn new_metadata(&self) -> Option<TimerMetadata> {
         None
     }
 }
 
@@ -123,18 +122,18 @@ fn test_first_contentful_paint_setter() 
         base: BaseDisplayItem::empty(),
         webrender_image: WebRenderImageInfo {
             width: 1,
             height: 1,
             format: PixelFormat::RGB8,
             key: None,
         },
         image_data: None,
-        stretch_size: Size2D::zero(),
-        tile_spacing: Size2D::zero(),
+        stretch_size: LayoutSize::zero(),
+        tile_spacing: LayoutSize::zero(),
         image_rendering: ImageRendering::Auto,
     }));
     let display_list = DisplayList {
         list: vec![image],
         clip_scroll_nodes: Vec::new(),
     };
     let epoch = Epoch(0);
     let paint_time_metrics = test_common(&display_list, epoch);