Bug 1400216 - Update webrender to commit 68e2e7cd0e39d216bb6c35dfb353dc0700bb6948. r=jrmuizel
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 19 Sep 2017 12:11:59 -0400
changeset 381745 d54626f98cc471254ce0e677950545117b3bf951
parent 381744 40b3b10f78c2d5a72356d21532add0848fc928b2
child 381746 d7bf0ddc77a71c17e3ae6418eb486154843e288c
push id95191
push userkwierso@gmail.com
push dateTue, 19 Sep 2017 21:53:48 +0000
treeherdermozilla-inbound@d9db71772f1d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1400216
milestone57.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
Bug 1400216 - Update webrender to commit 68e2e7cd0e39d216bb6c35dfb353dc0700bb6948. r=jrmuizel MozReview-Commit-ID: DYEZNrGLKnC
gfx/doc/README.webrender
gfx/webrender/Cargo.toml
gfx/webrender/build.rs
gfx/webrender/examples/animation.rs
gfx/webrender/examples/basic.rs
gfx/webrender/examples/blob.rs
gfx/webrender/examples/common/boilerplate.rs
gfx/webrender/examples/frame_output.rs
gfx/webrender/examples/iframe.rs
gfx/webrender/examples/image_resize.rs
gfx/webrender/examples/nested_display_list.rs
gfx/webrender/examples/scrolling.rs
gfx/webrender/examples/texture_cache_stress.rs
gfx/webrender/examples/yuv.rs
gfx/webrender/res/clip_shared.glsl
gfx/webrender/res/cs_blur.glsl
gfx/webrender/res/cs_clip_border.fs.glsl
gfx/webrender/res/cs_clip_border.glsl
gfx/webrender/res/cs_clip_border.vs.glsl
gfx/webrender/res/cs_clip_image.fs.glsl
gfx/webrender/res/cs_clip_image.glsl
gfx/webrender/res/cs_clip_image.vs.glsl
gfx/webrender/res/cs_text_run.fs.glsl
gfx/webrender/res/cs_text_run.glsl
gfx/webrender/res/cs_text_run.vs.glsl
gfx/webrender/res/prim_shared.glsl
gfx/webrender/res/ps_blend.fs.glsl
gfx/webrender/res/ps_blend.glsl
gfx/webrender/res/ps_blend.vs.glsl
gfx/webrender/res/ps_box_shadow.glsl
gfx/webrender/res/ps_cache_image.fs.glsl
gfx/webrender/res/ps_cache_image.glsl
gfx/webrender/res/ps_cache_image.vs.glsl
gfx/webrender/res/ps_composite.glsl
gfx/webrender/res/ps_hardware_composite.fs.glsl
gfx/webrender/res/ps_hardware_composite.glsl
gfx/webrender/res/ps_hardware_composite.vs.glsl
gfx/webrender/res/ps_line.glsl
gfx/webrender/res/ps_yuv_image.glsl
gfx/webrender/res/rect.glsl
gfx/webrender/src/border.rs
gfx/webrender/src/clip.rs
gfx/webrender/src/clip_scroll_node.rs
gfx/webrender/src/clip_scroll_tree.rs
gfx/webrender/src/debug_render.rs
gfx/webrender/src/debug_server.rs
gfx/webrender/src/device.rs
gfx/webrender/src/ellipse.rs
gfx/webrender/src/frame.rs
gfx/webrender/src/frame_builder.rs
gfx/webrender/src/freelist.rs
gfx/webrender/src/geometry.rs
gfx/webrender/src/glyph_cache.rs
gfx/webrender/src/glyph_rasterizer.rs
gfx/webrender/src/gpu_cache.rs
gfx/webrender/src/gpu_types.rs
gfx/webrender/src/internal_types.rs
gfx/webrender/src/lib.rs
gfx/webrender/src/platform/macos/font.rs
gfx/webrender/src/platform/unix/font.rs
gfx/webrender/src/platform/windows/font.rs
gfx/webrender/src/prim_store.rs
gfx/webrender/src/print_tree.rs
gfx/webrender/src/profiler.rs
gfx/webrender/src/record.rs
gfx/webrender/src/render_backend.rs
gfx/webrender/src/render_task.rs
gfx/webrender/src/renderer.rs
gfx/webrender/src/resource_cache.rs
gfx/webrender/src/scene.rs
gfx/webrender/src/spring.rs
gfx/webrender/src/texture_allocator.rs
gfx/webrender/src/texture_cache.rs
gfx/webrender/src/tiling.rs
gfx/webrender/src/util.rs
gfx/webrender/tests/angle_shader_validation.rs
gfx/webrender_api/src/api.rs
gfx/webrender_api/src/channel.rs
gfx/webrender_api/src/color.rs
gfx/webrender_api/src/display_item.rs
gfx/webrender_api/src/display_list.rs
gfx/webrender_api/src/font.rs
gfx/webrender_api/src/image.rs
gfx/webrender_api/src/lib.rs
gfx/webrender_api/src/units.rs
--- a/gfx/doc/README.webrender
+++ b/gfx/doc/README.webrender
@@ -74,9 +74,9 @@ there is another crate in m-c called moz
 the same folder to store its rust dependencies. If one of the libraries that is
 required by both mozjs_sys and webrender is updated without updating the other
 project's Cargo.lock file, that results in build bustage.
 This means that any time you do this sort of manual update of packages, you need
 to make sure that mozjs_sys also has its Cargo.lock file updated if needed, hence
 the need to run the cargo update command in js/src as well. Hopefully this will
 be resolved soon.
 
-Latest Commit: 878914aaf4d230fa449ff7800b529fe9023fc3c5
+Latest Commit: 68e2e7cd0e39d216bb6c35dfb353dc0700bb6948
--- a/gfx/webrender/Cargo.toml
+++ b/gfx/webrender/Cargo.toml
@@ -10,29 +10,27 @@ build = "build.rs"
 default = ["freetype-lib"]
 freetype-lib = ["freetype/servo-freetype-sys"]
 profiler = ["thread_profiler/thread_profiler"]
 debugger = ["ws", "serde_json", "serde", "serde_derive"]
 
 [dependencies]
 app_units = "0.5.6"
 bincode = "0.8"
-bit-set = "0.4"
 byteorder = "1.0"
 euclid = "0.15.2"
 fxhash = "0.2.1"
 gleam = "0.4.8"
 lazy_static = "0.2"
 log = "0.3"
 num-traits = "0.1.32"
 time = "0.1"
 rayon = "0.8"
 webrender_api = {path = "../webrender_api"}
 bitflags = "0.9"
-gamma-lut = "0.2"
 thread_profiler = "0.1.1"
 plane-split = "0.6"
 ws = { optional = true, version = "0.7.3" }
 serde_json = { optional = true, version = "1.0" }
 serde = { optional = true, version = "1.0" }
 serde_derive = { optional = true, version = "1.0" }
 
 [dev-dependencies]
@@ -40,12 +38,14 @@ angle = {git = "https://github.com/servo
 rand = "0.3"                # for the benchmarks
 servo-glutin = "0.11"     # for the example apps
 
 [target.'cfg(any(target_os = "android", all(unix, not(target_os = "macos"))))'.dependencies]
 freetype = { version = "0.3", default-features = false }
 
 [target.'cfg(target_os = "windows")'.dependencies]
 dwrote = "0.4"
+gamma-lut = "0.2"
 
 [target.'cfg(target_os = "macos")'.dependencies]
 core-graphics = "0.8.0"
 core-text = { version = "6.1", default-features = false }
+gamma-lut = "0.2"
--- a/gfx/webrender/build.rs
+++ b/gfx/webrender/build.rs
@@ -1,36 +1,43 @@
 /* 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 std::env;
-use std::path::{Path, PathBuf};
+use std::fs::{canonicalize, read_dir, File};
 use std::io::prelude::*;
-use std::fs::{canonicalize, read_dir, File};
+use std::path::{Path, PathBuf};
 
 fn write_shaders(glsl_files: Vec<PathBuf>, shader_file_path: &Path) {
     let mut shader_file = File::create(shader_file_path).unwrap();
 
     write!(shader_file, "/// AUTO GENERATED BY build.rs\n\n").unwrap();
     write!(shader_file, "use std::collections::HashMap;\n").unwrap();
     write!(shader_file, "lazy_static! {{\n").unwrap();
-    write!(shader_file, "  pub static ref SHADERS: HashMap<&'static str, &'static str> = {{\n").unwrap();
+    write!(
+        shader_file,
+        "  pub static ref SHADERS: HashMap<&'static str, &'static str> = {{\n"
+    ).unwrap();
     write!(shader_file, "    let mut h = HashMap::new();\n").unwrap();
     for glsl in glsl_files {
         let shader_name = glsl.file_name().unwrap().to_str().unwrap();
         // strip .glsl
         let shader_name = shader_name.replace(".glsl", "");
         let full_path = canonicalize(&glsl).unwrap();
         let full_name = full_path.as_os_str().to_str().unwrap();
         // if someone is building on a network share, I'm sorry.
         let full_name = full_name.replace("\\\\?\\", "");
         let full_name = full_name.replace("\\", "/");
-        write!(shader_file, "    h.insert(\"{}\", include_str!(\"{}\"));\n",
-               shader_name, full_name).unwrap();
+        write!(
+            shader_file,
+            "    h.insert(\"{}\", include_str!(\"{}\"));\n",
+            shader_name,
+            full_name
+        ).unwrap();
     }
     write!(shader_file, "    h\n").unwrap();
     write!(shader_file, "  }};\n").unwrap();
     write!(shader_file, "}}\n").unwrap();
 }
 
 fn main() {
     let out_dir = env::var("OUT_DIR").unwrap_or("out".to_owned());
--- a/gfx/webrender/examples/animation.rs
+++ b/gfx/webrender/examples/animation.rs
@@ -1,90 +1,91 @@
 /* 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 gleam;
 extern crate glutin;
 extern crate webrender;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use boilerplate::{Example, HandyDandyRectBuilder};
 use webrender::api::*;
 
 // This example creates a 100x100 white rect and allows the user to move it
 // around by using the arrow keys. It does this by using the animation API.
 
 struct App {
     transform: LayoutTransform,
 }
 
 impl Example for App {
-    fn render(&mut self,
-              _api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              _resources: &mut ResourceUpdates,
-              _layout_size: LayoutSize,
-              _pipeline_id: PipelineId,
-              _document_id: DocumentId) {
+    fn render(
+        &mut self,
+        _api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        _resources: &mut ResourceUpdates,
+        _layout_size: LayoutSize,
+        _pipeline_id: PipelineId,
+        _document_id: DocumentId,
+    ) {
         // Create a 100x100 stacking context with an animatable transform property.
         // Note the magic "42" we use as the animation key. That is used to update
         // the transform in the keyboard event handler code.
-        let bounds = (0,0).to(100, 100);
-        let info = LayoutPrimitiveInfo {
-            rect: bounds,
-            local_clip: None,
-            is_backface_visible: true,
-        };
+        let bounds = (0, 0).to(100, 100);
+        let info = LayoutPrimitiveInfo::new(bounds);
 
-        builder.push_stacking_context(&info,
-                                      ScrollPolicy::Scrollable,
-                                      Some(PropertyBinding::Binding(PropertyBindingKey::new(42))),
-                                      TransformStyle::Flat,
-                                      None,
-                                      MixBlendMode::Normal,
-                                      Vec::new());
+        builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            Some(PropertyBinding::Binding(PropertyBindingKey::new(42))),
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
 
         // Fill it with a white rect
         builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0));
 
         builder.pop_stacking_context();
     }
 
-    fn on_event(&mut self,
-                event: glutin::Event,
-                api: &RenderApi,
-                document_id: DocumentId) -> bool {
+    fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool {
         match event {
             glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => {
                 let offset = match key {
-                     glutin::VirtualKeyCode::Down => (0.0, 10.0),
-                     glutin::VirtualKeyCode::Up => (0.0, -10.0),
-                     glutin::VirtualKeyCode::Right => (10.0, 0.0),
-                     glutin::VirtualKeyCode::Left => (-10.0, 0.0),
-                     _ => return false,
+                    glutin::VirtualKeyCode::Down => (0.0, 10.0),
+                    glutin::VirtualKeyCode::Up => (0.0, -10.0),
+                    glutin::VirtualKeyCode::Right => (10.0, 0.0),
+                    glutin::VirtualKeyCode::Left => (-10.0, 0.0),
+                    _ => return false,
                 };
                 // Update the transform based on the keyboard input and push it to
                 // webrender using the generate_frame API. This will recomposite with
                 // the updated transform.
-                let new_transform = self.transform.post_translate(LayoutVector3D::new(offset.0, offset.1, 0.0));
-                api.generate_frame(document_id, Some(DynamicProperties {
-                    transforms: vec![
-                      PropertyValue {
-                        key: PropertyBindingKey::new(42),
-                        value: new_transform,
-                      },
-                    ],
-                    floats: vec![],
-                }));
+                let new_transform = self.transform
+                    .post_translate(LayoutVector3D::new(offset.0, offset.1, 0.0));
+                api.generate_frame(
+                    document_id,
+                    Some(DynamicProperties {
+                        transforms: vec![
+                            PropertyValue {
+                                key: PropertyBindingKey::new(42),
+                                value: new_transform,
+                            },
+                        ],
+                        floats: vec![],
+                    }),
+                );
                 self.transform = new_transform;
             }
-            _ => ()
+            _ => (),
         }
 
         false
     }
 }
 
 fn main() {
     let mut app = App {
--- a/gfx/webrender/examples/basic.rs
+++ b/gfx/webrender/examples/basic.rs
@@ -3,17 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 extern crate app_units;
 extern crate euclid;
 extern crate gleam;
 extern crate glutin;
 extern crate webrender;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use app_units::Au;
 use boilerplate::{Example, HandyDandyRectBuilder};
 use euclid::vec2;
 use glutin::TouchPhase;
 use std::collections::HashMap;
 use std::fs::File;
@@ -47,17 +47,22 @@ impl Touch {
         dist(self.start_x, self.start_y, self.current_x, self.current_y)
     }
 
     fn initial_distance_from_other(&self, other: &Touch) -> f32 {
         dist(self.start_x, self.start_y, other.start_x, other.start_y)
     }
 
     fn current_distance_from_other(&self, other: &Touch) -> f32 {
-        dist(self.current_x, self.current_y, other.current_x, other.current_y)
+        dist(
+            self.current_x,
+            self.current_y,
+            other.current_x,
+            other.current_y,
+        )
     }
 }
 
 struct TouchState {
     active_touches: HashMap<u64, Touch>,
     current_gesture: Gesture,
     start_zoom: f32,
     current_zoom: f32,
@@ -82,32 +87,35 @@ impl TouchState {
             current_pan: DeviceIntPoint::zero(),
         }
     }
 
     fn handle_event(&mut self, touch: glutin::Touch) -> TouchResult {
         match touch.phase {
             TouchPhase::Started => {
                 debug_assert!(!self.active_touches.contains_key(&touch.id));
-                self.active_touches.insert(touch.id, Touch {
-                    id: touch.id,
-                    start_x: touch.location.0 as f32,
-                    start_y: touch.location.1 as f32,
-                    current_x: touch.location.0 as f32,
-                    current_y: touch.location.1 as f32,
-                });
+                self.active_touches.insert(
+                    touch.id,
+                    Touch {
+                        id: touch.id,
+                        start_x: touch.location.0 as f32,
+                        start_y: touch.location.1 as f32,
+                        current_x: touch.location.0 as f32,
+                        current_y: touch.location.1 as f32,
+                    },
+                );
                 self.current_gesture = Gesture::None;
             }
             TouchPhase::Moved => {
                 match self.active_touches.get_mut(&touch.id) {
                     Some(active_touch) => {
                         active_touch.current_x = touch.location.0 as f32;
                         active_touch.current_y = touch.location.1 as f32;
                     }
-                    None => panic!("move touch event with unknown touch id!")
+                    None => panic!("move touch event with unknown touch id!"),
                 }
 
                 match self.current_gesture {
                     Gesture::None => {
                         let mut over_threshold_count = 0;
                         let active_touch_count = self.active_touches.len();
 
                         for (_, touch) in &self.active_touches {
@@ -172,65 +180,57 @@ fn main() {
     boilerplate::main_wrapper(&mut app, None);
 }
 
 struct App {
     touch_state: TouchState,
 }
 
 impl Example for App {
-    fn render(&mut self,
-              api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              resources: &mut ResourceUpdates,
-              layout_size: LayoutSize,
-              _pipeline_id: PipelineId,
-              _document_id: DocumentId) {
+    fn render(
+        &mut self,
+        api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        resources: &mut ResourceUpdates,
+        layout_size: LayoutSize,
+        _pipeline_id: PipelineId,
+        _document_id: DocumentId,
+    ) {
         let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size);
-        let info = LayoutPrimitiveInfo {
-            rect: bounds,
-            local_clip: None,
-            is_backface_visible: true,
-        };
-        builder.push_stacking_context(&info,
-                                      ScrollPolicy::Scrollable,
-                                      None,
-                                      TransformStyle::Flat,
-                                      None,
-                                      MixBlendMode::Normal,
-                                      Vec::new());
+        let info = LayoutPrimitiveInfo::new(bounds);
+        builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            None,
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
 
         let image_mask_key = api.generate_image_key();
         resources.add_image(
             image_mask_key,
             ImageDescriptor::new(2, 2, ImageFormat::A8, true),
             ImageData::new(vec![0, 80, 180, 255]),
-            None
+            None,
         );
         let mask = ImageMask {
             image: image_mask_key,
             rect: (75, 75).by(100, 100),
             repeat: false,
         };
         let complex = ComplexClipRegion::new((50, 50).to(150, 150), BorderRadius::uniform(20.0));
         let id = builder.define_clip(None, bounds, vec![complex], Some(mask));
         builder.push_clip_id(id);
 
-        let info = LayoutPrimitiveInfo {
-            rect: (100, 100).to(200, 200),
-            local_clip: None,
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::new((100, 100).to(200, 200));
         builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));
 
-        let info = LayoutPrimitiveInfo {
-            rect: (250, 100).to(350, 200),
-            local_clip: None,
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::new((250, 100).to(350, 200));
         builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));
         let border_side = BorderSide {
             color: ColorF::new(0.0, 0.0, 1.0, 1.0),
             style: BorderStyle::Groove,
         };
         let border_widths = BorderWidths {
             top: 10.0,
             left: 10.0,
@@ -240,25 +240,22 @@ impl Example for App {
         let border_details = BorderDetails::Normal(NormalBorder {
             top: border_side,
             right: border_side,
             bottom: border_side,
             left: border_side,
             radius: BorderRadius::uniform(20.0),
         });
 
-        let info = LayoutPrimitiveInfo {
-            rect: (100, 100).to(200, 200),
-            local_clip: None,
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::new((100, 100).to(200, 200));
         builder.push_border(&info, border_widths, border_details);
 
 
-        if false { // draw text?
+        if false {
+            // draw text?
             let font_key = api.generate_font_key();
             let font_bytes = load_file("res/FreeSans.ttf");
             resources.add_raw_font(font_key, font_bytes, 0);
 
             let font_instance_key = api.generate_font_instance_key();
             resources.add_font_instance(font_instance_key, font_key, Au::from_px(32), None, None);
 
             let text_bounds = (100, 200).by(700, 300);
@@ -307,74 +304,66 @@ impl Example for App {
                     index: 87,
                     point: LayoutPoint::new(600.0, 100.0),
                 },
                 GlyphInstance {
                     index: 17,
                     point: LayoutPoint::new(650.0, 100.0),
                 },
             ];
-            let info = LayoutPrimitiveInfo {
-                rect: text_bounds,
-                local_clip: None,
-                is_backface_visible: true,
-            };
 
-            builder.push_text(&info,
-                              &glyphs,
-                              font_instance_key,
-                              ColorF::new(1.0, 1.0, 0.0, 1.0),
-                              None);
+            let info = LayoutPrimitiveInfo::new(text_bounds);
+            builder.push_text(
+                &info,
+                &glyphs,
+                font_instance_key,
+                ColorF::new(1.0, 1.0, 0.0, 1.0),
+                None,
+            );
         }
 
-        if false { // draw box shadow?
+        if false {
+            // draw box shadow?
             let rect = LayoutRect::zero();
             let simple_box_bounds = (20, 200).by(50, 50);
             let offset = vec2(10.0, 10.0);
             let color = ColorF::new(1.0, 1.0, 1.0, 1.0);
             let blur_radius = 0.0;
             let spread_radius = 0.0;
             let simple_border_radius = 8.0;
             let box_shadow_type = BoxShadowClipMode::Inset;
-            let info = LayoutPrimitiveInfo {
-                rect: rect,
-                local_clip: Some(LocalClip::from(bounds)),
-                is_backface_visible: true,
-            };
+            let info = LayoutPrimitiveInfo::with_clip_rect(rect, bounds);
 
-            builder.push_box_shadow(&info,
-                                    simple_box_bounds,
-                                    offset,
-                                    color,
-                                    blur_radius,
-                                    spread_radius,
-                                    simple_border_radius,
-                                    box_shadow_type);
+            builder.push_box_shadow(
+                &info,
+                simple_box_bounds,
+                offset,
+                color,
+                blur_radius,
+                spread_radius,
+                simple_border_radius,
+                box_shadow_type,
+            );
         }
 
         builder.pop_clip_id();
         builder.pop_stacking_context();
     }
 
-    fn on_event(&mut self,
-                event: glutin::Event,
-                api: &RenderApi,
-                document_id: DocumentId) -> bool {
+    fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool {
         match event {
-            glutin::Event::Touch(touch) => {
-                match self.touch_state.handle_event(touch) {
-                    TouchResult::Pan(pan) => {
-                        api.set_pan(document_id, pan);
-                        api.generate_frame(document_id, None);
-                    }
-                    TouchResult::Zoom(zoom) => {
-                        api.set_pinch_zoom(document_id, ZoomFactor::new(zoom));
-                        api.generate_frame(document_id, None);
-                    }
-                    TouchResult::None => {}
+            glutin::Event::Touch(touch) => match self.touch_state.handle_event(touch) {
+                TouchResult::Pan(pan) => {
+                    api.set_pan(document_id, pan);
+                    api.generate_frame(document_id, None);
                 }
-            }
-            _ => ()
+                TouchResult::Zoom(zoom) => {
+                    api.set_pinch_zoom(document_id, ZoomFactor::new(zoom));
+                    api.generate_frame(document_id, None);
+                }
+                TouchResult::None => {}
+            },
+            _ => (),
         }
 
         false
     }
 }
--- a/gfx/webrender/examples/blob.rs
+++ b/gfx/webrender/examples/blob.rs
@@ -1,28 +1,29 @@
 /* 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 gleam;
 extern crate glutin;
+extern crate rayon;
 extern crate webrender;
-extern crate rayon;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use boilerplate::{Example, HandyDandyRectBuilder};
+use rayon::Configuration as ThreadPoolConfig;
 use rayon::ThreadPool;
-use rayon::Configuration as ThreadPoolConfig;
 use std::collections::HashMap;
 use std::collections::hash_map::Entry;
 use std::sync::Arc;
-use std::sync::mpsc::{channel, Sender, Receiver};
-use webrender::api::{self, RenderApi, DisplayListBuilder, ResourceUpdates, LayoutSize, PipelineId, DocumentId};
+use std::sync::mpsc::{channel, Receiver, Sender};
+use webrender::api::{self, DisplayListBuilder, DocumentId, LayoutSize, PipelineId, RenderApi,
+                     ResourceUpdates};
 
 // This example shows how to implement a very basic BlobImageRenderer that can only render
 // a checkerboard pattern.
 
 // The deserialized command list internally used by this example is just a color.
 type ImageRenderingCommands = api::ColorU;
 
 // Serialize/deserialze the blob.
@@ -33,66 +34,69 @@ fn serialize_blob(color: api::ColorU) ->
 }
 
 fn deserialize_blob(blob: &[u8]) -> Result<ImageRenderingCommands, ()> {
     let mut iter = blob.iter();
     return match (iter.next(), iter.next(), iter.next(), iter.next()) {
         (Some(&r), Some(&g), Some(&b), Some(&a)) => Ok(api::ColorU::new(r, g, b, a)),
         (Some(&a), None, None, None) => Ok(api::ColorU::new(a, a, a, a)),
         _ => Err(()),
-    }
+    };
 }
 
 // This is the function that applies the deserialized drawing commands and generates
 // actual image data.
 fn render_blob(
     commands: Arc<ImageRenderingCommands>,
-   descriptor: &api::BlobImageDescriptor,
-   tile: Option<api::TileOffset>
+    descriptor: &api::BlobImageDescriptor,
+    tile: Option<api::TileOffset>,
 ) -> api::BlobImageResult {
     let color = *commands;
 
     // Allocate storage for the result. Right now the resource cache expects the
     // tiles to have have no stride or offset.
     let mut texels = Vec::with_capacity((descriptor.width * descriptor.height * 4) as usize);
 
     // Generate a per-tile pattern to see it in the demo. For a real use case it would not
     // make sense for the rendered content to depend on its tile.
     let tile_checker = match tile {
         Some(tile) => (tile.x % 2 == 0) != (tile.y % 2 == 0),
         None => true,
     };
 
-    for y in 0..descriptor.height {
-        for x in 0..descriptor.width {
+    for y in 0 .. descriptor.height {
+        for x in 0 .. descriptor.width {
             // Apply the tile's offset. This is important: all drawing commands should be
             // translated by this offset to give correct results with tiled blob images.
             let x2 = x + descriptor.offset.x as u32;
             let y2 = y + descriptor.offset.y as u32;
 
             // Render a simple checkerboard pattern
-            let checker = if (x2 % 20 >= 10) != (y2 % 20 >= 10) { 1 } else { 0 };
+            let checker = if (x2 % 20 >= 10) != (y2 % 20 >= 10) {
+                1
+            } else {
+                0
+            };
             // ..nested in the per-tile cherkerboard pattern
             let tc = if tile_checker { 0 } else { (1 - checker) * 40 };
 
             match descriptor.format {
                 api::ImageFormat::BGRA8 => {
                     texels.push(color.b * checker + tc);
                     texels.push(color.g * checker + tc);
                     texels.push(color.r * checker + tc);
                     texels.push(color.a * checker + tc);
                 }
                 api::ImageFormat::A8 => {
                     texels.push(color.a * checker + tc);
                 }
                 _ => {
-                    return Err(api::BlobImageError::Other(format!(
-                        "Usupported image format {:?}",
-                        descriptor.format
-                    )));
+                    return Err(api::BlobImageError::Other(
+                        format!("Usupported image format {:?}", descriptor.format),
+                    ));
                 }
             }
         }
     }
 
     Ok(api::RasterizedBlobImage {
         data: texels,
         width: descriptor.width,
@@ -132,34 +136,38 @@ impl CheckerboardRenderer {
             tx,
             rx,
         }
     }
 }
 
 impl api::BlobImageRenderer for CheckerboardRenderer {
     fn add(&mut self, key: api::ImageKey, cmds: api::BlobImageData, _: Option<api::TileSize>) {
-        self.image_cmds.insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap()));
+        self.image_cmds
+            .insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap()));
     }
 
     fn update(&mut self, key: api::ImageKey, cmds: api::BlobImageData) {
         // Here, updating is just replacing the current version of the commands with
         // the new one (no incremental updates).
-        self.image_cmds.insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap()));
+        self.image_cmds
+            .insert(key, Arc::new(deserialize_blob(&cmds[..]).unwrap()));
     }
 
     fn delete(&mut self, key: api::ImageKey) {
         self.image_cmds.remove(&key);
     }
 
-    fn request(&mut self,
-               _resources: &api::BlobImageResources,
-               request: api::BlobImageRequest,
-               descriptor: &api::BlobImageDescriptor,
-               _dirty_rect: Option<api::DeviceUintRect>) {
+    fn request(
+        &mut self,
+        _resources: &api::BlobImageResources,
+        request: api::BlobImageRequest,
+        descriptor: &api::BlobImageDescriptor,
+        _dirty_rect: Option<api::DeviceUintRect>,
+    ) {
         // This method is where we kick off our rendering jobs.
         // It should avoid doing work on the calling thread as much as possible.
         // In this example we will use the thread pool to render individual tiles.
 
         // Gather the input data to send to a worker thread.
         let cmds = Arc::clone(&self.image_cmds.get(&request.key).unwrap());
         let tx = self.tx.clone();
         let descriptor = descriptor.clone();
@@ -194,40 +202,40 @@ impl api::BlobImageRenderer for Checkerb
                 }
             }
         }
 
         // We haven't received it yet, pull from the channel until we receive it.
         while let Ok((req, result)) = self.rx.recv() {
             if req == request {
                 // There it is!
-                return result
+                return result;
             }
             self.rendered_images.insert(req, Some(result));
         }
 
         // If we break out of the loop above it means the channel closed unexpectedly.
         Err(api::BlobImageError::Other("Channel closed".into()))
     }
-    fn delete_font(&mut self, _font: api::FontKey) { }
-    fn delete_font_instance(&mut self, _instance: api::FontInstanceKey) { }
-}
-
-struct App {
-
+    fn delete_font(&mut self, _font: api::FontKey) {}
+    fn delete_font_instance(&mut self, _instance: api::FontInstanceKey) {}
 }
 
+struct App {}
+
 impl Example for App {
-    fn render(&mut self,
-              api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              resources: &mut ResourceUpdates,
-              layout_size: LayoutSize,
-              _pipeline_id: PipelineId,
-              _document_id: DocumentId) {
+    fn render(
+        &mut self,
+        api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        resources: &mut ResourceUpdates,
+        layout_size: LayoutSize,
+        _pipeline_id: PipelineId,
+        _document_id: DocumentId,
+    ) {
         let blob_img1 = api.generate_image_key();
         resources.add_image(
             blob_img1,
             api::ImageDescriptor::new(500, 500, api::ImageFormat::BGRA8, true),
             api::ImageData::new_blob_image(serialize_blob(api::ColorU::new(50, 50, 150, 255))),
             Some(128),
         );
 
@@ -235,77 +243,68 @@ impl Example for App {
         resources.add_image(
             blob_img2,
             api::ImageDescriptor::new(200, 200, api::ImageFormat::BGRA8, true),
             api::ImageData::new_blob_image(serialize_blob(api::ColorU::new(50, 150, 50, 255))),
             None,
         );
 
         let bounds = api::LayoutRect::new(api::LayoutPoint::zero(), layout_size);
-        let info = api::LayoutPrimitiveInfo {
-            rect: bounds,
-            local_clip: None,
-            is_backface_visible: true,
-        };
-        builder.push_stacking_context(&info,
-                                      api::ScrollPolicy::Scrollable,
-                                      None,
-                                      api::TransformStyle::Flat,
-                                      None,
-                                      api::MixBlendMode::Normal,
-                                      Vec::new());
+        let info = api::LayoutPrimitiveInfo::new(bounds);
+        builder.push_stacking_context(
+            &info,
+            api::ScrollPolicy::Scrollable,
+            None,
+            api::TransformStyle::Flat,
+            None,
+            api::MixBlendMode::Normal,
+            Vec::new(),
+        );
 
-        let info = api::LayoutPrimitiveInfo {
-            rect: (30, 30).by(500, 500),
-            local_clip: Some(api::LocalClip::from(bounds)),
-            is_backface_visible: true,
-        };
+        let info = api::LayoutPrimitiveInfo::new((30, 30).by(500, 500));
         builder.push_image(
             &info,
             api::LayoutSize::new(500.0, 500.0),
             api::LayoutSize::new(0.0, 0.0),
             api::ImageRendering::Auto,
             blob_img1,
         );
 
-        let info = api::LayoutPrimitiveInfo {
-            rect: (600, 600).by(200, 200),
-            local_clip: Some(api::LocalClip::from(bounds)),
-            is_backface_visible: true,
-        };
+        let info = api::LayoutPrimitiveInfo::new((600, 600).by(200, 200));
         builder.push_image(
             &info,
             api::LayoutSize::new(200.0, 200.0),
             api::LayoutSize::new(0.0, 0.0),
             api::ImageRendering::Auto,
             blob_img2,
         );
 
         builder.pop_stacking_context();
     }
 
-    fn on_event(&mut self,
-                _event: glutin::Event,
-                _api: &RenderApi,
-                _document_id: DocumentId) -> bool {
+    fn on_event(
+        &mut self,
+        _event: glutin::Event,
+        _api: &RenderApi,
+        _document_id: DocumentId,
+    ) -> bool {
         false
     }
 }
 
 fn main() {
-    let worker_config = ThreadPoolConfig::new().thread_name(|idx|{
-        format!("WebRender:Worker#{}", idx)
-    });
+    let worker_config =
+        ThreadPoolConfig::new().thread_name(|idx| format!("WebRender:Worker#{}", idx));
 
     let workers = Arc::new(ThreadPool::new(worker_config).unwrap());
 
     let opts = webrender::RendererOptions {
         workers: Some(Arc::clone(&workers)),
         // Register our blob renderer, so that WebRender integrates it in the resource cache..
         // Share the same pool of worker threads between WebRender and our blob renderer.
         blob_image_renderer: Some(Box::new(CheckerboardRenderer::new(Arc::clone(&workers)))),
-        .. Default::default()
+        ..Default::default()
     };
 
     let mut app = App {};
 
     boilerplate::main_wrapper(&mut app, Some(opts));
 }
--- a/gfx/webrender/examples/common/boilerplate.rs
+++ b/gfx/webrender/examples/common/boilerplate.rs
@@ -10,19 +10,17 @@ use webrender;
 use webrender::api::*;
 
 struct Notifier {
     window_proxy: glutin::WindowProxy,
 }
 
 impl Notifier {
     fn new(window_proxy: glutin::WindowProxy) -> Notifier {
-        Notifier {
-            window_proxy,
-        }
+        Notifier { window_proxy }
     }
 }
 
 impl RenderNotifier for Notifier {
     fn new_frame_ready(&mut self) {
         #[cfg(not(target_os = "android"))]
         self.window_proxy.wakeup_event_loop();
     }
@@ -36,88 +34,95 @@ impl RenderNotifier for Notifier {
 pub trait HandyDandyRectBuilder {
     fn to(&self, x2: i32, y2: i32) -> LayoutRect;
     fn by(&self, w: i32, h: i32) -> LayoutRect;
 }
 // Allows doing `(x, y).to(x2, y2)` or `(x, y).by(width, height)` with i32
 // values to build a f32 LayoutRect
 impl HandyDandyRectBuilder for (i32, i32) {
     fn to(&self, x2: i32, y2: i32) -> LayoutRect {
-        LayoutRect::new(LayoutPoint::new(self.0 as f32, self.1 as f32),
-                        LayoutSize::new((x2 - self.0) as f32, (y2 - self.1) as f32))
+        LayoutRect::new(
+            LayoutPoint::new(self.0 as f32, self.1 as f32),
+            LayoutSize::new((x2 - self.0) as f32, (y2 - self.1) as f32),
+        )
     }
 
     fn by(&self, w: i32, h: i32) -> LayoutRect {
-        LayoutRect::new(LayoutPoint::new(self.0 as f32, self.1 as f32),
-                        LayoutSize::new(w as f32, h as f32))
+        LayoutRect::new(
+            LayoutPoint::new(self.0 as f32, self.1 as f32),
+            LayoutSize::new(w as f32, h as f32),
+        )
     }
 }
 
 pub trait Example {
-    fn render(&mut self,
-              api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              resources: &mut ResourceUpdates,
-              layout_size: LayoutSize,
-              pipeline_id: PipelineId,
-              document_id: DocumentId);
-    fn on_event(&mut self,
-                event: glutin::Event,
-                api: &RenderApi,
-                document_id: DocumentId) -> bool;
+    fn render(
+        &mut self,
+        api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        resources: &mut ResourceUpdates,
+        layout_size: LayoutSize,
+        pipeline_id: PipelineId,
+        document_id: DocumentId,
+    );
+    fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool;
     fn get_external_image_handler(&self) -> Option<Box<webrender::ExternalImageHandler>> {
         None
     }
-    fn get_output_image_handler(&mut self, _gl: &gl::Gl) -> Option<Box<webrender::OutputImageHandler>> {
+    fn get_output_image_handler(
+        &mut self,
+        _gl: &gl::Gl,
+    ) -> Option<Box<webrender::OutputImageHandler>> {
         None
     }
-    fn draw_custom(&self, _gl: &gl::Gl) {
-    }
+    fn draw_custom(&self, _gl: &gl::Gl) {}
 }
 
-pub fn main_wrapper(example: &mut Example,
-                    options: Option<webrender::RendererOptions>)
-{
+pub fn main_wrapper(example: &mut Example, options: Option<webrender::RendererOptions>) {
     let args: Vec<String> = env::args().collect();
     let res_path = if args.len() > 1 {
         Some(PathBuf::from(&args[1]))
     } else {
         None
     };
 
     let window = glutin::WindowBuilder::new()
-                .with_title("WebRender Sample App")
-                .with_multitouch()
-                .with_gl(glutin::GlRequest::GlThenGles {
-                    opengl_version: (3, 2),
-                    opengles_version: (3, 0)
-                })
-                .build()
-                .unwrap();
+        .with_title("WebRender Sample App")
+        .with_multitouch()
+        .with_gl(glutin::GlRequest::GlThenGles {
+            opengl_version: (3, 2),
+            opengles_version: (3, 0),
+        })
+        .build()
+        .unwrap();
 
     unsafe {
         window.make_current().ok();
     }
 
     let gl = match gl::GlType::default() {
-        gl::GlType::Gl => unsafe { gl::GlFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) },
-        gl::GlType::Gles => unsafe { gl::GlesFns::load_with(|symbol| window.get_proc_address(symbol) as *const _) },
+        gl::GlType::Gl => unsafe {
+            gl::GlFns::load_with(|symbol| window.get_proc_address(symbol) as *const _)
+        },
+        gl::GlType::Gles => unsafe {
+            gl::GlesFns::load_with(|symbol| window.get_proc_address(symbol) as *const _)
+        },
     };
 
     println!("OpenGL version {}", gl.get_string(gl::VERSION));
     println!("Shader resource path: {:?}", res_path);
 
     let (width, height) = window.get_inner_size_pixels().unwrap();
 
     let opts = webrender::RendererOptions {
         resource_override_path: res_path,
         debug: true,
         precache_shaders: true,
         device_pixel_ratio: window.hidpi_factor(),
-        .. options.unwrap_or(webrender::RendererOptions::default())
+        ..options.unwrap_or(webrender::RendererOptions::default())
     };
 
     let size = DeviceUintSize::new(width, height);
     let (mut renderer, sender) = webrender::Renderer::new(gl.clone(), opts).unwrap();
     let api = sender.create_api();
     let document_id = api.add_document(size);
 
     let notifier = Box::new(Notifier::new(window.create_window_proxy()));
@@ -133,25 +138,32 @@ pub fn main_wrapper(example: &mut Exampl
     let epoch = Epoch(0);
     let root_background_color = ColorF::new(0.3, 0.0, 0.0, 1.0);
 
     let pipeline_id = PipelineId(0, 0);
     let layout_size = LayoutSize::new(width as f32, height as f32);
     let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
     let mut resources = ResourceUpdates::new();
 
-    example.render(&api, &mut builder, &mut resources, layout_size, pipeline_id, document_id);
+    example.render(
+        &api,
+        &mut builder,
+        &mut resources,
+        layout_size,
+        pipeline_id,
+        document_id,
+    );
     api.set_display_list(
         document_id,
         epoch,
         Some(root_background_color),
         LayoutSize::new(width as f32, height as f32),
         builder.finalize(),
         true,
-        resources
+        resources,
     );
     api.set_root_pipeline(document_id, pipeline_id);
     api.generate_frame(document_id, None);
 
     'outer: for event in window.wait_events() {
         let mut events = Vec::new();
         events.push(event);
 
@@ -160,62 +172,82 @@ pub fn main_wrapper(example: &mut Exampl
         }
 
         for event in events {
             match event {
                 glutin::Event::Closed |
                 glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) |
                 glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Q)) => break 'outer,
 
-                glutin::Event::KeyboardInput(glutin::ElementState::Pressed,
-                                             _, Some(glutin::VirtualKeyCode::P)) => {
+                glutin::Event::KeyboardInput(
+                    glutin::ElementState::Pressed,
+                    _,
+                    Some(glutin::VirtualKeyCode::P),
+                ) => {
                     let mut flags = renderer.get_debug_flags();
                     flags.toggle(webrender::PROFILER_DBG);
                     renderer.set_debug_flags(flags);
                 }
-                glutin::Event::KeyboardInput(glutin::ElementState::Pressed,
-                                             _, Some(glutin::VirtualKeyCode::O)) => {
+                glutin::Event::KeyboardInput(
+                    glutin::ElementState::Pressed,
+                    _,
+                    Some(glutin::VirtualKeyCode::O),
+                ) => {
                     let mut flags = renderer.get_debug_flags();
                     flags.toggle(webrender::RENDER_TARGET_DBG);
                     renderer.set_debug_flags(flags);
                 }
-                glutin::Event::KeyboardInput(glutin::ElementState::Pressed,
-                                             _, Some(glutin::VirtualKeyCode::I)) => {
+                glutin::Event::KeyboardInput(
+                    glutin::ElementState::Pressed,
+                    _,
+                    Some(glutin::VirtualKeyCode::I),
+                ) => {
                     let mut flags = renderer.get_debug_flags();
                     flags.toggle(webrender::TEXTURE_CACHE_DBG);
                     renderer.set_debug_flags(flags);
                 }
-                glutin::Event::KeyboardInput(glutin::ElementState::Pressed,
-                                             _, Some(glutin::VirtualKeyCode::B)) => {
+                glutin::Event::KeyboardInput(
+                    glutin::ElementState::Pressed,
+                    _,
+                    Some(glutin::VirtualKeyCode::B),
+                ) => {
                     let mut flags = renderer.get_debug_flags();
                     flags.toggle(webrender::ALPHA_PRIM_DBG);
                     renderer.set_debug_flags(flags);
                 }
-                glutin::Event::KeyboardInput(glutin::ElementState::Pressed,
-                                             _, Some(glutin::VirtualKeyCode::M)) => {
+                glutin::Event::KeyboardInput(
+                    glutin::ElementState::Pressed,
+                    _,
+                    Some(glutin::VirtualKeyCode::M),
+                ) => {
                     api.notify_memory_pressure();
                 }
-                _ => {
-                    if example.on_event(event, &api, document_id) {
-                        let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
-                        let mut resources = ResourceUpdates::new();
+                _ => if example.on_event(event, &api, document_id) {
+                    let mut builder = DisplayListBuilder::new(pipeline_id, layout_size);
+                    let mut resources = ResourceUpdates::new();
 
-                        example.render(&api, &mut builder, &mut resources, layout_size, pipeline_id, document_id);
-                        api.set_display_list(
-                            document_id,
-                            epoch,
-                            Some(root_background_color),
-                            LayoutSize::new(width as f32, height as f32),
-                            builder.finalize(),
-                            true,
-                            resources
-                        );
-                        api.generate_frame(document_id, None);
-                    }
-                }
+                    example.render(
+                        &api,
+                        &mut builder,
+                        &mut resources,
+                        layout_size,
+                        pipeline_id,
+                        document_id,
+                    );
+                    api.set_display_list(
+                        document_id,
+                        epoch,
+                        Some(root_background_color),
+                        LayoutSize::new(width as f32, height as f32),
+                        builder.finalize(),
+                        true,
+                        resources,
+                    );
+                    api.generate_frame(document_id, None);
+                },
             }
         }
 
         renderer.update();
         renderer.render(DeviceUintSize::new(width, height)).unwrap();
         example.draw_custom(&*gl);
         window.swap_buffers().ok();
     }
--- a/gfx/webrender/examples/frame_output.rs
+++ b/gfx/webrender/examples/frame_output.rs
@@ -1,137 +1,133 @@
 /* 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 gleam;
 extern crate glutin;
 extern crate webrender;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use boilerplate::{Example, HandyDandyRectBuilder};
 use gleam::gl;
 use webrender::api::*;
 
 // This example demonstrates using the frame output feature to copy
 // the output of a WR framebuffer to a custom texture.
 
-const VS: &str = "#version 130\nin vec2 aPos;out vec2 vUv;\nvoid main() { vUv = aPos; gl_Position = vec4(aPos, 0.0, 1.0); }\n";
-const FS: &str = "#version 130\nout vec4 oFragColor;\nin vec2 vUv;\nuniform sampler2D s;\nvoid main() { oFragColor = texture(s, vUv); }\n";
+const VS: &str = "#version 130
+    in vec2 aPos;out vec2 vUv;
+    void main() { vUv = aPos; gl_Position = vec4(aPos, 0.0, 1.0); }
+";
+const FS: &str = "#version 130
+    out vec4 oFragColor;
+    in vec2 vUv;
+    uniform sampler2D s;
+    void main() { oFragColor = texture(s, vUv); }
+";
 
 struct App {
     iframe_pipeline_id: Option<PipelineId>,
     texture_id: gl::GLuint,
 }
 
 struct OutputHandler {
     texture_id: gl::GLuint,
 }
 
 impl OutputHandler {
     fn new(texture_id: gl::GLuint) -> OutputHandler {
-        OutputHandler {
-            texture_id
-        }
+        OutputHandler { texture_id }
     }
 }
 
 impl webrender::OutputImageHandler for OutputHandler {
     fn lock(&mut self, _id: PipelineId) -> Option<(u32, DeviceIntSize)> {
         Some((self.texture_id, DeviceIntSize::new(100, 100)))
     }
 
-    fn unlock(&mut self, _id: PipelineId) {
-    }
+    fn unlock(&mut self, _id: PipelineId) {}
 }
 
 impl Example for App {
-    fn render(&mut self,
-              api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              _resources: &mut ResourceUpdates,
-              _layout_size: LayoutSize,
-              _pipeline_id: PipelineId,
-              document_id: DocumentId) {
+    fn render(
+        &mut self,
+        api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        _resources: &mut ResourceUpdates,
+        _layout_size: LayoutSize,
+        _pipeline_id: PipelineId,
+        document_id: DocumentId,
+    ) {
         // Build the iframe display list on first render.
         if self.iframe_pipeline_id.is_none() {
             let epoch = Epoch(0);
             let root_background_color = ColorF::new(0.0, 1.0, 0.0, 1.0);
 
             let iframe_pipeline_id = PipelineId(0, 1);
             let layout_size = LayoutSize::new(100.0, 100.0);
             let mut builder = DisplayListBuilder::new(iframe_pipeline_id, layout_size);
             let resources = ResourceUpdates::new();
 
-            let bounds = (0,0).to(50, 50);
-            let info = LayoutPrimitiveInfo {
-                rect: bounds,
-                local_clip: None,
-                is_backface_visible: true,
-            };
-            builder.push_stacking_context(&info,
-                                          ScrollPolicy::Scrollable,
-                                          None,
-                                          TransformStyle::Flat,
-                                          None,
-                                          MixBlendMode::Normal,
-                                          Vec::new());
+            let bounds = (0, 0).to(50, 50);
+            let info = LayoutPrimitiveInfo::new(bounds);
+            builder.push_stacking_context(
+                &info,
+                ScrollPolicy::Scrollable,
+                None,
+                TransformStyle::Flat,
+                None,
+                MixBlendMode::Normal,
+                Vec::new(),
+            );
 
             builder.push_rect(&info, ColorF::new(1.0, 1.0, 0.0, 1.0));
             builder.pop_stacking_context();
 
             api.set_display_list(
                 document_id,
                 epoch,
                 Some(root_background_color),
                 layout_size,
                 builder.finalize(),
                 true,
-                resources
+                resources,
             );
 
             self.iframe_pipeline_id = Some(iframe_pipeline_id);
             api.enable_frame_output(document_id, iframe_pipeline_id, true);
         }
 
-        let bounds = (100,100).to(200, 200);
-        let info = LayoutPrimitiveInfo {
-            rect: bounds,
-            local_clip: None,
-            is_backface_visible: true,
-        };
-        builder.push_stacking_context(&info,
-                                      ScrollPolicy::Scrollable,
-                                      None,
-                                      TransformStyle::Flat,
-                                      None,
-                                      MixBlendMode::Normal,
-                                      Vec::new());
+        let bounds = (100, 100).to(200, 200);
+        let info = LayoutPrimitiveInfo::new(bounds);
+        builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            None,
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
 
         builder.push_iframe(&info, self.iframe_pipeline_id.unwrap());
 
         builder.pop_stacking_context();
     }
 
     fn draw_custom(&self, gl: &gl::Gl) {
         let vbo = gl.gen_buffers(1)[0];
         let vao = gl.gen_vertex_arrays(1)[0];
 
         let pid = create_program(gl);
 
-        let vertices: [f32; 12] = [
-            0.0, 1.0,
-            1.0, 0.0,
-            0.0, 0.0,
-            0.0, 1.0,
-            1.0, 1.0,
-            1.0, 0.0
-        ];
+        let vertices: [f32; 12] = [0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0];
 
         gl.active_texture(gl::TEXTURE0);
         gl.bind_texture(gl::TEXTURE_2D, self.texture_id);
 
         gl.use_program(pid);
         let sampler = gl.get_uniform_location(pid, "s");
         debug_assert!(sampler != -1);
         gl.uniform_1i(sampler, 0);
@@ -145,59 +141,79 @@ impl Example for App {
 
         gl.draw_arrays(gl::TRIANGLES, 0, 6);
 
         gl.delete_vertex_arrays(&[vao]);
         gl.delete_buffers(&[vbo]);
         gl.delete_program(pid);
     }
 
-    fn on_event(&mut self,
-                _event: glutin::Event,
-                _api: &RenderApi,
-                _document_id: DocumentId) -> bool {
+    fn on_event(
+        &mut self,
+        _event: glutin::Event,
+        _api: &RenderApi,
+        _document_id: DocumentId,
+    ) -> bool {
         false
     }
 
-    fn get_output_image_handler(&mut self, gl: &gl::Gl) -> Option<Box<webrender::OutputImageHandler>> {
+    fn get_output_image_handler(
+        &mut self,
+        gl: &gl::Gl,
+    ) -> Option<Box<webrender::OutputImageHandler>> {
         let texture_id = gl.gen_textures(1)[0];
 
         gl.bind_texture(gl::TEXTURE_2D, texture_id);
-        gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MAG_FILTER, gl::LINEAR as gl::GLint);
-        gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_MIN_FILTER, gl::LINEAR as gl::GLint);
-        gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint);
-        gl.tex_parameter_i(gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint);
-        gl.tex_image_2d(gl::TEXTURE_2D,
-                        0,
-                        gl::RGBA as gl::GLint,
-                        100,
-                        100,
-                        0,
-                        gl::BGRA,
-                        gl::UNSIGNED_BYTE,
-                        None);
+        gl.tex_parameter_i(
+            gl::TEXTURE_2D,
+            gl::TEXTURE_MAG_FILTER,
+            gl::LINEAR as gl::GLint,
+        );
+        gl.tex_parameter_i(
+            gl::TEXTURE_2D,
+            gl::TEXTURE_MIN_FILTER,
+            gl::LINEAR as gl::GLint,
+        );
+        gl.tex_parameter_i(
+            gl::TEXTURE_2D,
+            gl::TEXTURE_WRAP_S,
+            gl::CLAMP_TO_EDGE as gl::GLint,
+        );
+        gl.tex_parameter_i(
+            gl::TEXTURE_2D,
+            gl::TEXTURE_WRAP_T,
+            gl::CLAMP_TO_EDGE as gl::GLint,
+        );
+        gl.tex_image_2d(
+            gl::TEXTURE_2D,
+            0,
+            gl::RGBA as gl::GLint,
+            100,
+            100,
+            0,
+            gl::BGRA,
+            gl::UNSIGNED_BYTE,
+            None,
+        );
         gl.bind_texture(gl::TEXTURE_2D, 0);
 
         self.texture_id = texture_id;
         Some(Box::new(OutputHandler::new(texture_id)))
     }
 }
 
 fn main() {
     let mut app = App {
         iframe_pipeline_id: None,
         texture_id: 0,
     };
     boilerplate::main_wrapper(&mut app, None);
 }
 
-pub fn compile_shader(gl: &gl::Gl,
-                      shader_type: gl::GLenum,
-                      source: &str)
-                      -> gl::GLuint {
+pub fn compile_shader(gl: &gl::Gl, shader_type: gl::GLenum, source: &str) -> gl::GLuint {
     let id = gl.create_shader(shader_type);
     gl.shader_source(id, &[source.as_bytes()]);
     gl.compile_shader(id);
     let log = gl.get_shader_info_log(id);
     if gl.get_shader_iv(id, gl::COMPILE_STATUS) == (0 as gl::GLint) {
         panic!("{:?} {}", source, log);
     }
     id
--- a/gfx/webrender/examples/iframe.rs
+++ b/gfx/webrender/examples/iframe.rs
@@ -1,89 +1,92 @@
 /* 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 gleam;
 extern crate glutin;
 extern crate webrender;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use boilerplate::{Example, HandyDandyRectBuilder};
 use webrender::api::*;
 
 // This example uses the push_iframe API to nest a second pipeline's displaylist
 // inside the root pipeline's display list. When it works, a green square is
 // shown. If it fails, a red square is shown.
 
-struct App {
-
-}
+struct App {}
 
 impl Example for App {
-    fn render(&mut self,
-              api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              _resources: &mut ResourceUpdates,
-              _layout_size: LayoutSize,
-              pipeline_id: PipelineId,
-              document_id: DocumentId) {
+    fn render(
+        &mut self,
+        api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        _resources: &mut ResourceUpdates,
+        _layout_size: LayoutSize,
+        pipeline_id: PipelineId,
+        document_id: DocumentId,
+    ) {
         // All the sub_* things are for the nested pipeline
         let sub_size = DeviceUintSize::new(100, 100);
-        let sub_bounds = (0,0).to(sub_size.width as i32, sub_size.height as i32);
+        let sub_bounds = (0, 0).to(sub_size.width as i32, sub_size.height as i32);
 
         let sub_pipeline_id = PipelineId(pipeline_id.0, 42);
         let mut sub_builder = DisplayListBuilder::new(sub_pipeline_id, sub_bounds.size);
-        let info = LayoutPrimitiveInfo {
-            rect: sub_bounds,
-            local_clip: None,
-            is_backface_visible: true,
-        };
 
-        sub_builder.push_stacking_context(&info,
-                                          ScrollPolicy::Scrollable,
-                                          None,
-                                          TransformStyle::Flat,
-                                          None,
-                                          MixBlendMode::Normal,
-                                          Vec::new());
+        let info = LayoutPrimitiveInfo::new(sub_bounds);
+        sub_builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            None,
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
+
         // green rect visible == success
         sub_builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));
         sub_builder.pop_stacking_context();
 
         api.set_display_list(
             document_id,
             Epoch(0),
             None,
             sub_bounds.size,
             sub_builder.finalize(),
             true,
             ResourceUpdates::new(),
         );
 
         // And this is for the root pipeline
-        builder.push_stacking_context(&info,
-                                      ScrollPolicy::Scrollable,
-                                      Some(PropertyBinding::Binding(PropertyBindingKey::new(42))),
-                                      TransformStyle::Flat,
-                                      None,
-                                      MixBlendMode::Normal,
-                                      Vec::new());
+        builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            Some(PropertyBinding::Binding(PropertyBindingKey::new(42))),
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
         // red rect under the iframe: if this is visible, things have gone wrong
         builder.push_rect(&info, ColorF::new(1.0, 0.0, 0.0, 1.0));
         builder.push_iframe(&info, sub_pipeline_id);
         builder.pop_stacking_context();
     }
 
-    fn on_event(&mut self,
-                _event: glutin::Event,
-                _api: &RenderApi,
-                _document_id: DocumentId) -> bool {
+    fn on_event(
+        &mut self,
+        _event: glutin::Event,
+        _api: &RenderApi,
+        _document_id: DocumentId,
+    ) -> bool {
         false
     }
 }
 
 fn main() {
     let mut app = App {};
     boilerplate::main_wrapper(&mut app, None);
 }
--- a/gfx/webrender/examples/image_resize.rs
+++ b/gfx/webrender/examples/image_resize.rs
@@ -1,123 +1,120 @@
 /* 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 gleam;
 extern crate glutin;
 extern crate webrender;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use boilerplate::{Example, HandyDandyRectBuilder};
 use webrender::api::*;
 
 struct App {
     image_key: ImageKey,
 }
 
 impl Example for App {
-    fn render(&mut self,
-              _api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              resources: &mut ResourceUpdates,
-              _layout_size: LayoutSize,
-              _pipeline_id: PipelineId,
-              _document_id: DocumentId) {
+    fn render(
+        &mut self,
+        _api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        resources: &mut ResourceUpdates,
+        _layout_size: LayoutSize,
+        _pipeline_id: PipelineId,
+        _document_id: DocumentId,
+    ) {
         let mut image_data = Vec::new();
-        for y in 0..32 {
-            for x in 0..32 {
+        for y in 0 .. 32 {
+            for x in 0 .. 32 {
                 let lum = 255 * (((x & 8) == 0) ^ ((y & 8) == 0)) as u8;
                 image_data.extend_from_slice(&[lum, lum, lum, 0xff]);
             }
         }
 
         resources.add_image(
             self.image_key,
             ImageDescriptor::new(32, 32, ImageFormat::BGRA8, true),
             ImageData::new(image_data),
             None,
         );
 
         let bounds = (0, 0).to(512, 512);
-        let info = LayoutPrimitiveInfo {
-            rect: bounds,
-            local_clip: None,
-            is_backface_visible: true,
-        };
-        builder.push_stacking_context(&info,
-                                      ScrollPolicy::Scrollable,
-                                      None,
-                                      TransformStyle::Flat,
-                                      None,
-                                      MixBlendMode::Normal,
-                                      Vec::new());
+        let info = LayoutPrimitiveInfo::new(bounds);
+        builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            None,
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
 
         let image_size = LayoutSize::new(100.0, 100.0);
 
-        let info = LayoutPrimitiveInfo {
-            rect: LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
-            local_clip: Some(LocalClip::from(bounds)),
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::with_clip_rect(
+            LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
+            bounds,
+        );
         builder.push_image(
             &info,
             image_size,
             LayoutSize::zero(),
             ImageRendering::Auto,
-            self.image_key
+            self.image_key,
         );
 
-        let info = LayoutPrimitiveInfo {
-            rect: LayoutRect::new(LayoutPoint::new(250.0, 100.0), image_size),
-            local_clip: Some(LocalClip::from(bounds)),
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::with_clip_rect(
+            LayoutRect::new(LayoutPoint::new(250.0, 100.0), image_size),
+            bounds,
+        );
         builder.push_image(
             &info,
             image_size,
             LayoutSize::zero(),
             ImageRendering::Pixelated,
-            self.image_key
+            self.image_key,
         );
 
         builder.pop_stacking_context();
     }
 
-    fn on_event(&mut self,
-                event: glutin::Event,
-                api: &RenderApi,
-                document_id: DocumentId) -> bool {
+    fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool {
         match event {
             glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => {
                 match key {
-                     glutin::VirtualKeyCode::Space => {
+                    glutin::VirtualKeyCode::Space => {
                         let mut image_data = Vec::new();
-                        for y in 0..64 {
-                            for x in 0..64 {
+                        for y in 0 .. 64 {
+                            for x in 0 .. 64 {
                                 let r = 255 * ((y & 32) == 0) as u8;
                                 let g = 255 * ((x & 32) == 0) as u8;
                                 image_data.extend_from_slice(&[0, g, r, 0xff]);
                             }
                         }
 
                         let mut updates = ResourceUpdates::new();
-                        updates.update_image(self.image_key,
-                                             ImageDescriptor::new(64, 64, ImageFormat::BGRA8, true),
-                                             ImageData::new(image_data),
-                                             None);
+                        updates.update_image(
+                            self.image_key,
+                            ImageDescriptor::new(64, 64, ImageFormat::BGRA8, true),
+                            ImageData::new(image_data),
+                            None,
+                        );
                         api.update_resources(updates);
                         api.generate_frame(document_id, None);
-                     }
-                     _ => {}
-                 }
-             }
-             _ => {}
+                    }
+                    _ => {}
+                }
+            }
+            _ => {}
         }
 
         false
     }
 }
 
 fn main() {
     let mut app = App {
--- a/gfx/webrender/examples/nested_display_list.rs
+++ b/gfx/webrender/examples/nested_display_list.rs
@@ -1,171 +1,154 @@
 /* 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 gleam;
 extern crate glutin;
 extern crate webrender;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use boilerplate::{Example, HandyDandyRectBuilder};
 use webrender::api::*;
 
 struct App {
     cursor_position: WorldPoint,
 }
 
 impl Example for App {
-    fn render(&mut self,
-              _api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              _resources: &mut ResourceUpdates,
-              layout_size: LayoutSize,
-              pipeline_id: PipelineId,
-              _document_id: DocumentId) {
+    fn render(
+        &mut self,
+        _api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        _resources: &mut ResourceUpdates,
+        layout_size: LayoutSize,
+        pipeline_id: PipelineId,
+        _document_id: DocumentId,
+    ) {
         let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size);
-        let info = LayoutPrimitiveInfo {
-            rect: bounds,
-            local_clip: None,
-            is_backface_visible: true,
-        };
-        builder.push_stacking_context(&info,
-                                      ScrollPolicy::Scrollable,
-                                      None,
-                                      TransformStyle::Flat,
-                                      None,
-                                      MixBlendMode::Normal,
-                                      Vec::new());
+        let info = LayoutPrimitiveInfo::new(bounds);
+        builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            None,
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
 
         let outer_scroll_frame_rect = (100, 100).to(600, 400);
-        let info = LayoutPrimitiveInfo {
-            rect: outer_scroll_frame_rect,
-            local_clip: None,
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::new(outer_scroll_frame_rect);
         builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0));
 
-        let nested_clip_id = builder.define_scroll_frame(None,
-                                                         (100, 100).to(1000, 1000),
-                                                         outer_scroll_frame_rect,
-                                                         vec![],
-                                                         None,
-                                                         ScrollSensitivity::ScriptAndInputEvents);
+        let nested_clip_id = builder.define_scroll_frame(
+            None,
+            (100, 100).to(1000, 1000),
+            outer_scroll_frame_rect,
+            vec![],
+            None,
+            ScrollSensitivity::ScriptAndInputEvents,
+        );
         builder.push_clip_id(nested_clip_id);
 
         let mut builder2 = DisplayListBuilder::new(pipeline_id, layout_size);
         let mut builder3 = DisplayListBuilder::new(pipeline_id, layout_size);
 
-        let info = LayoutPrimitiveInfo {
-            rect: (110, 110).to(210, 210),
-            local_clip: None,
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::new((110, 110).to(210, 210));
         builder3.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));
 
         // A fixed position rectangle should be fixed to the reference frame that starts
         // in the outer display list.
-        let info = LayoutPrimitiveInfo {
-            rect: (220, 110).to(320, 210),
-            local_clip: None,
-            is_backface_visible: true,
-        };
-        builder3.push_stacking_context(&info,
-                                       ScrollPolicy::Fixed,
-                                       None,
-                                       TransformStyle::Flat,
-                                       None,
-                                       MixBlendMode::Normal,
-                                       Vec::new());
-        let info = LayoutPrimitiveInfo {
-            rect: (0, 0).to(100, 100),
-            local_clip: None,
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::new((220, 110).to(320, 210));
+        builder3.push_stacking_context(
+            &info,
+            ScrollPolicy::Fixed,
+            None,
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
+
+        let info = LayoutPrimitiveInfo::new((0, 0).to(100, 100));
         builder3.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));
         builder3.pop_stacking_context();
 
         // Now we push an inner scroll frame that should have the same id as the outer one,
         // but the WebRender nested display list replacement code should convert it into
         // a unique ClipId.
         let inner_scroll_frame_rect = (330, 110).to(530, 360);
-        let info = LayoutPrimitiveInfo {
-            rect: inner_scroll_frame_rect,
-            local_clip: None,
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::new(inner_scroll_frame_rect);
         builder3.push_rect(&info, ColorF::new(1.0, 0.0, 1.0, 0.5));
-        let inner_nested_clip_id =
-            builder3.define_scroll_frame(None,
-                                         (330, 110).to(2000, 2000),
-                                         inner_scroll_frame_rect,
-                                         vec![],
-                                         None,
-                                         ScrollSensitivity::ScriptAndInputEvents);
+        let inner_nested_clip_id = builder3.define_scroll_frame(
+            None,
+            (330, 110).to(2000, 2000),
+            inner_scroll_frame_rect,
+            vec![],
+            None,
+            ScrollSensitivity::ScriptAndInputEvents,
+        );
         builder3.push_clip_id(inner_nested_clip_id);
-        let info = LayoutPrimitiveInfo {
-            rect: (340, 120).to(440, 220),
-            local_clip: None,
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::new((340, 120).to(440, 220));
         builder3.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));
         builder3.pop_clip_id();
 
         let (_, _, built_list) = builder3.finalize();
         builder2.push_nested_display_list(&built_list);
         let (_, _, built_list) = builder2.finalize();
         builder.push_nested_display_list(&built_list);
 
         builder.pop_clip_id();
 
         builder.pop_stacking_context();
     }
 
-    fn on_event(&mut self,
-                event: glutin::Event,
-                api: &RenderApi,
-                document_id: DocumentId) -> bool {
+    fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool {
         match event {
             glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => {
                 let offset = match key {
-                     glutin::VirtualKeyCode::Down => (0.0, -10.0),
-                     glutin::VirtualKeyCode::Up => (0.0, 10.0),
-                     glutin::VirtualKeyCode::Right => (-10.0, 0.0),
-                     glutin::VirtualKeyCode::Left => (10.0, 0.0),
-                     _ => return false,
+                    glutin::VirtualKeyCode::Down => (0.0, -10.0),
+                    glutin::VirtualKeyCode::Up => (0.0, 10.0),
+                    glutin::VirtualKeyCode::Right => (-10.0, 0.0),
+                    glutin::VirtualKeyCode::Left => (10.0, 0.0),
+                    _ => return false,
                 };
 
-                api.scroll(document_id,
-                           ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)),
-                           self.cursor_position,
-                           ScrollEventPhase::Start);
+                api.scroll(
+                    document_id,
+                    ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)),
+                    self.cursor_position,
+                    ScrollEventPhase::Start,
+                );
             }
             glutin::Event::MouseMoved(x, y) => {
                 self.cursor_position = WorldPoint::new(x as f32, y as f32);
             }
             glutin::Event::MouseWheel(delta, _, event_cursor_position) => {
                 if let Some((x, y)) = event_cursor_position {
                     self.cursor_position = WorldPoint::new(x as f32, y as f32);
                 }
 
                 const LINE_HEIGHT: f32 = 38.0;
                 let (dx, dy) = match delta {
                     glutin::MouseScrollDelta::LineDelta(dx, dy) => (dx, dy * LINE_HEIGHT),
                     glutin::MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy),
                 };
 
-                api.scroll(document_id,
-                           ScrollLocation::Delta(LayoutVector2D::new(dx, dy)),
-                           self.cursor_position,
-                           ScrollEventPhase::Start);
+                api.scroll(
+                    document_id,
+                    ScrollLocation::Delta(LayoutVector2D::new(dx, dy)),
+                    self.cursor_position,
+                    ScrollEventPhase::Start,
+                );
             }
-            _ => ()
+            _ => (),
         }
 
         false
     }
 }
 
 fn main() {
     let mut app = App {
--- a/gfx/webrender/examples/scrolling.rs
+++ b/gfx/webrender/examples/scrolling.rs
@@ -1,204 +1,187 @@
 /* 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 gleam;
 extern crate glutin;
 extern crate webrender;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use boilerplate::{Example, HandyDandyRectBuilder};
 use webrender::api::*;
 
 struct App {
     cursor_position: WorldPoint,
 }
 
 impl Example for App {
-    fn render(&mut self,
-              _api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              _resources: &mut ResourceUpdates,
-              layout_size: LayoutSize,
-              _pipeline_id: PipelineId,
-              _document_id: DocumentId) {
-        let info = LayoutPrimitiveInfo {
-            rect: LayoutRect::new(LayoutPoint::zero(), layout_size),
-            local_clip: None,
-            is_backface_visible: true,
-        };
-        builder.push_stacking_context(&info,
-                                      ScrollPolicy::Scrollable,
-                                      None,
-                                      TransformStyle::Flat,
-                                      None,
-                                      MixBlendMode::Normal,
-                                      Vec::new());
+    fn render(
+        &mut self,
+        _api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        _resources: &mut ResourceUpdates,
+        layout_size: LayoutSize,
+        _pipeline_id: PipelineId,
+        _document_id: DocumentId,
+    ) {
+        let info = LayoutPrimitiveInfo::new(LayoutRect::new(LayoutPoint::zero(), layout_size));
+        builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            None,
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
 
-        if true {   // scrolling and clips stuff
+        if true {
+            // scrolling and clips stuff
             // let's make a scrollbox
             let scrollbox = (0, 0).to(300, 400);
-            let info = LayoutPrimitiveInfo {
-                rect: LayoutRect::new(LayoutPoint::new(10.0, 10.0),
-                                      LayoutSize::zero()),
-                local_clip: None,
-                is_backface_visible: true,
-            };
-            builder.push_stacking_context(&info,
-                                          ScrollPolicy::Scrollable,
-                                          None,
-                                          TransformStyle::Flat,
-                                          None,
-                                          MixBlendMode::Normal,
-                                          Vec::new());
+            let info = LayoutPrimitiveInfo::new((10, 10).by(0, 0));
+            builder.push_stacking_context(
+                &info,
+                ScrollPolicy::Scrollable,
+                None,
+                TransformStyle::Flat,
+                None,
+                MixBlendMode::Normal,
+                Vec::new(),
+            );
             // set the scrolling clip
-            let clip_id = builder.define_scroll_frame(None,
-                                                      (0, 0).by(1000, 1000),
-                                                      scrollbox,
-                                                      vec![],
-                                                      None,
-                                                      ScrollSensitivity::ScriptAndInputEvents);
+            let clip_id = builder.define_scroll_frame(
+                None,
+                (0, 0).by(1000, 1000),
+                scrollbox,
+                vec![],
+                None,
+                ScrollSensitivity::ScriptAndInputEvents,
+            );
             builder.push_clip_id(clip_id);
 
             // now put some content into it.
             // start with a white background
-            let info = LayoutPrimitiveInfo {
-                rect: (0, 0).to(1000, 1000),
-                local_clip: None,
-                is_backface_visible: true,
-            };
+            let info = LayoutPrimitiveInfo::new((0, 0).to(1000, 1000));
             builder.push_rect(&info, ColorF::new(1.0, 1.0, 1.0, 1.0));
 
             // let's make a 50x50 blue square as a visual reference
-            let info = LayoutPrimitiveInfo {
-                rect: (0, 0).to(50, 50),
-                local_clip: None,
-                is_backface_visible: true,
-            };
+            let info = LayoutPrimitiveInfo::new((0, 0).to(50, 50));
             builder.push_rect(&info, ColorF::new(0.0, 0.0, 1.0, 1.0));
 
             // and a 50x50 green square next to it with an offset clip
             // to see what that looks like
-            let info = LayoutPrimitiveInfo {
-                rect: (50, 0).to(100, 50),
-                local_clip: Some(LocalClip::from((60, 10).to(110, 60))),
-                is_backface_visible: true,
-            };
-            builder.push_rect(&info,
-                              ColorF::new(0.0, 1.0, 0.0, 1.0));
+            let info =
+                LayoutPrimitiveInfo::with_clip_rect((50, 0).to(100, 50), (60, 10).to(110, 60));
+            builder.push_rect(&info, ColorF::new(0.0, 1.0, 0.0, 1.0));
 
             // Below the above rectangles, set up a nested scrollbox. It's still in
             // the same stacking context, so note that the rects passed in need to
             // be relative to the stacking context.
-            let nested_clip_id = builder.define_scroll_frame(None,
-                                                             (0, 100).to(300, 400),
-                                                             (0, 100).to(200, 300),
-                                                             vec![],
-                                                             None,
-                                                             ScrollSensitivity::ScriptAndInputEvents);
+            let nested_clip_id = builder.define_scroll_frame(
+                None,
+                (0, 100).to(300, 400),
+                (0, 100).to(200, 300),
+                vec![],
+                None,
+                ScrollSensitivity::ScriptAndInputEvents,
+            );
             builder.push_clip_id(nested_clip_id);
 
             // give it a giant gray background just to distinguish it and to easily
             // visually identify the nested scrollbox
-            let info = LayoutPrimitiveInfo {
-                rect: (-1000, -1000).to(5000, 5000),
-                local_clip: None,
-                is_backface_visible: true,
-            };
+            let info = LayoutPrimitiveInfo::new((-1000, -1000).to(5000, 5000));
             builder.push_rect(&info, ColorF::new(0.5, 0.5, 0.5, 1.0));
 
             // add a teal square to visualize the scrolling/clipping behaviour
             // as you scroll the nested scrollbox
-            let info = LayoutPrimitiveInfo {
-                rect: (0, 200).to(50, 250),
-                local_clip: None,
-                is_backface_visible: true,
-            };
+            let info = LayoutPrimitiveInfo::new((0, 200).to(50, 250));
             builder.push_rect(&info, ColorF::new(0.0, 1.0, 1.0, 1.0));
 
             // Add a sticky frame. It will "stick" at a margin of 10px from the top, until
             // the scrollframe scrolls another 60px, at which point it will "unstick". This lines
             // it up with the above teal square as it scrolls out of the visible area of the
             // scrollframe
             let sticky_id = builder.define_sticky_frame(
                 None,
                 (50, 140).to(100, 190),
-                StickyFrameInfo::new(Some(StickySideConstraint{ margin: 10.0, max_offset: 60.0 }),
-                                     None, None, None));
+                StickyFrameInfo::new(
+                    Some(StickySideConstraint {
+                        margin: 10.0,
+                        max_offset: 60.0,
+                    }),
+                    None,
+                    None,
+                    None,
+                ),
+            );
             builder.push_clip_id(sticky_id);
-            let info = LayoutPrimitiveInfo {
-                rect: (50, 140).to(100, 190),
-                local_clip: None,
-                is_backface_visible: true,
-            };
+            let info = LayoutPrimitiveInfo::new((50, 140).to(100, 190));
             builder.push_rect(&info, ColorF::new(0.5, 0.5, 1.0, 1.0));
             builder.pop_clip_id(); // sticky_id
 
             // just for good measure add another teal square in the bottom-right
             // corner of the nested scrollframe content, which can be scrolled into
             // view by the user
-            let info = LayoutPrimitiveInfo {
-                rect: (250, 350).to(300, 400),
-                local_clip: None,
-                is_backface_visible: true,
-            };
+            let info = LayoutPrimitiveInfo::new((250, 350).to(300, 400));
             builder.push_rect(&info, ColorF::new(0.0, 1.0, 1.0, 1.0));
 
             builder.pop_clip_id(); // nested_clip_id
 
             builder.pop_clip_id(); // clip_id
             builder.pop_stacking_context();
         }
 
         builder.pop_stacking_context();
     }
 
-    fn on_event(&mut self,
-                event: glutin::Event,
-                api: &RenderApi,
-                document_id: DocumentId) -> bool {
+    fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool {
         match event {
             glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => {
                 let offset = match key {
-                     glutin::VirtualKeyCode::Down => (0.0, -10.0),
-                     glutin::VirtualKeyCode::Up => (0.0, 10.0),
-                     glutin::VirtualKeyCode::Right => (-10.0, 0.0),
-                     glutin::VirtualKeyCode::Left => (10.0, 0.0),
-                     _ => return false,
+                    glutin::VirtualKeyCode::Down => (0.0, -10.0),
+                    glutin::VirtualKeyCode::Up => (0.0, 10.0),
+                    glutin::VirtualKeyCode::Right => (-10.0, 0.0),
+                    glutin::VirtualKeyCode::Left => (10.0, 0.0),
+                    _ => return false,
                 };
 
-                api.scroll(document_id,
-                           ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)),
-                           self.cursor_position,
-                           ScrollEventPhase::Start);
+                api.scroll(
+                    document_id,
+                    ScrollLocation::Delta(LayoutVector2D::new(offset.0, offset.1)),
+                    self.cursor_position,
+                    ScrollEventPhase::Start,
+                );
             }
             glutin::Event::MouseMoved(x, y) => {
                 self.cursor_position = WorldPoint::new(x as f32, y as f32);
             }
             glutin::Event::MouseWheel(delta, _, event_cursor_position) => {
                 if let Some((x, y)) = event_cursor_position {
                     self.cursor_position = WorldPoint::new(x as f32, y as f32);
                 }
 
                 const LINE_HEIGHT: f32 = 38.0;
                 let (dx, dy) = match delta {
                     glutin::MouseScrollDelta::LineDelta(dx, dy) => (dx, dy * LINE_HEIGHT),
                     glutin::MouseScrollDelta::PixelDelta(dx, dy) => (dx, dy),
                 };
 
-                api.scroll(document_id,
-                           ScrollLocation::Delta(LayoutVector2D::new(dx, dy)),
-                           self.cursor_position,
-                           ScrollEventPhase::Start);
+                api.scroll(
+                    document_id,
+                    ScrollLocation::Delta(LayoutVector2D::new(dx, dy)),
+                    self.cursor_position,
+                    ScrollEventPhase::Start,
+                );
             }
-            _ => ()
+            _ => (),
         }
 
         false
     }
 }
 
 fn main() {
     let mut app = App {
--- a/gfx/webrender/examples/texture_cache_stress.rs
+++ b/gfx/webrender/examples/texture_cache_stress.rs
@@ -1,17 +1,17 @@
 /* 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 gleam;
 extern crate glutin;
 extern crate webrender;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use boilerplate::{Example, HandyDandyRectBuilder};
 use std::mem;
 use webrender::api::*;
 
 struct ImageGenerator {
     patterns: [[u8; 3]; 6],
@@ -33,23 +33,25 @@ impl ImageGenerator {
             ],
             current_image: Vec::new(),
         }
     }
 
     fn generate_image(&mut self, size: u32) {
         let pattern = &self.patterns[self.next_pattern];
         self.current_image.clear();
-        for y in 0..size {
-            for x in 0..size {
+        for y in 0 .. size {
+            for x in 0 .. size {
                 let lum = 255 * (1 - (((x & 8) == 0) ^ ((y & 8) == 0)) as u8);
-                self.current_image.extend_from_slice(&[lum * pattern[0],
-                                                     lum * pattern[1],
-                                                     lum * pattern[2],
-                                                     0xff]);
+                self.current_image.extend_from_slice(&[
+                    lum * pattern[0],
+                    lum * pattern[1],
+                    lum * pattern[2],
+                    0xff,
+                ]);
             }
         }
 
         self.next_pattern = (self.next_pattern + 1) % self.patterns.len();
     }
 
     fn take(&mut self) -> Vec<u8> {
         mem::replace(&mut self.current_image, Vec::new())
@@ -59,52 +61,51 @@ impl ImageGenerator {
 impl webrender::ExternalImageHandler for ImageGenerator {
     fn lock(&mut self, _key: ExternalImageId, channel_index: u8) -> webrender::ExternalImage {
         self.generate_image(channel_index as u32);
         webrender::ExternalImage {
             u0: 0.0,
             v0: 0.0,
             u1: 1.0,
             v1: 1.0,
-            source: webrender::ExternalImageSource::RawData(&self.current_image)
+            source: webrender::ExternalImageSource::RawData(&self.current_image),
         }
     }
-    fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {
-    }
+    fn unlock(&mut self, _key: ExternalImageId, _channel_index: u8) {}
 }
 
 struct App {
     stress_keys: Vec<ImageKey>,
     image_key: Option<ImageKey>,
     image_generator: ImageGenerator,
     swap_keys: Vec<ImageKey>,
     swap_index: usize,
 }
 
 impl Example for App {
-    fn render(&mut self,
-              api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              resources: &mut ResourceUpdates,
-              _layout_size: LayoutSize,
-              _pipeline_id: PipelineId,
-              _document_id: DocumentId) {
+    fn render(
+        &mut self,
+        api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        resources: &mut ResourceUpdates,
+        _layout_size: LayoutSize,
+        _pipeline_id: PipelineId,
+        _document_id: DocumentId,
+    ) {
         let bounds = (0, 0).to(512, 512);
-        let info = LayoutPrimitiveInfo {
-            rect: bounds,
-            local_clip: None,
-            is_backface_visible: true,
-        };
-        builder.push_stacking_context(&info,
-                                      ScrollPolicy::Scrollable,
-                                      None,
-                                      TransformStyle::Flat,
-                                      None,
-                                      MixBlendMode::Normal,
-                                      Vec::new());
+        let info = LayoutPrimitiveInfo::new(bounds);
+        builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            None,
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
 
         let x0 = 50.0;
         let y0 = 50.0;
         let image_size = LayoutSize::new(4.0, 4.0);
 
         if self.swap_keys.is_empty() {
             let key0 = api.generate_image_key();
             let key1 = api.generate_image_key();
@@ -127,82 +128,82 @@ impl Example for App {
 
             self.swap_keys.push(key0);
             self.swap_keys.push(key1);
         }
 
         for (i, key) in self.stress_keys.iter().enumerate() {
             let x = (i % 128) as f32;
             let y = (i / 128) as f32;
-            let info = LayoutPrimitiveInfo {
-                rect: LayoutRect::new(LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y), image_size),
-                local_clip: Some(LocalClip::from(bounds)),
-                is_backface_visible: true,
-            };
-
-            builder.push_image(
-                &info,
-                image_size,
-                LayoutSize::zero(),
-                ImageRendering::Auto,
-                *key
+            let info = LayoutPrimitiveInfo::with_clip_rect(
+                LayoutRect::new(
+                    LayoutPoint::new(x0 + image_size.width * x, y0 + image_size.height * y),
+                    image_size,
+                ),
+                bounds,
             );
-        }
-
-        if let Some(image_key) = self.image_key {
-            let image_size = LayoutSize::new(100.0, 100.0);
-            let info = LayoutPrimitiveInfo {
-                rect: LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
-                local_clip: Some(LocalClip::from(bounds)),
-                is_backface_visible: true,
-            };
 
             builder.push_image(
                 &info,
                 image_size,
                 LayoutSize::zero(),
                 ImageRendering::Auto,
-                image_key
+                *key,
+            );
+        }
+
+        if let Some(image_key) = self.image_key {
+            let image_size = LayoutSize::new(100.0, 100.0);
+            let info = LayoutPrimitiveInfo::with_clip_rect(
+                LayoutRect::new(LayoutPoint::new(100.0, 100.0), image_size),
+                bounds,
+            );
+            builder.push_image(
+                &info,
+                image_size,
+                LayoutSize::zero(),
+                ImageRendering::Auto,
+                image_key,
             );
         }
 
         let swap_key = self.swap_keys[self.swap_index];
         let image_size = LayoutSize::new(64.0, 64.0);
-        let info = LayoutPrimitiveInfo {
-            rect: LayoutRect::new(LayoutPoint::new(100.0, 400.0), image_size),
-            local_clip: Some(LocalClip::from(bounds)),
-            is_backface_visible: true,
-        };
-
+        let info = LayoutPrimitiveInfo::with_clip_rect(
+            LayoutRect::new(LayoutPoint::new(100.0, 400.0), image_size),
+            bounds,
+        );
         builder.push_image(
             &info,
             image_size,
             LayoutSize::zero(),
             ImageRendering::Auto,
-            swap_key
+            swap_key,
         );
         self.swap_index = 1 - self.swap_index;
 
         builder.pop_stacking_context();
     }
 
-    fn on_event(&mut self,
-                event: glutin::Event,
-                api: &RenderApi,
-                _document_id: DocumentId) -> bool {
+    fn on_event(
+        &mut self,
+        event: glutin::Event,
+        api: &RenderApi,
+        _document_id: DocumentId,
+    ) -> bool {
         match event {
             glutin::Event::KeyboardInput(glutin::ElementState::Pressed, _, Some(key)) => {
                 let mut updates = ResourceUpdates::new();
 
                 match key {
                     glutin::VirtualKeyCode::S => {
                         self.stress_keys.clear();
 
-                        for _ in 0..16 {
-                            for _ in 0..16 {
+                        for _ in 0 .. 16 {
+                            for _ in 0 .. 16 {
                                 let size = 4;
 
                                 let image_key = api.generate_image_key();
 
                                 self.image_generator.generate_image(size);
 
                                 updates.add_image(
                                     image_key,
@@ -210,34 +211,30 @@ impl Example for App {
                                     ImageData::new(self.image_generator.take()),
                                     None,
                                 );
 
                                 self.stress_keys.push(image_key);
                             }
                         }
                     }
-                    glutin::VirtualKeyCode::D => {
-                        if let Some(image_key) = self.image_key.take() {
-                            updates.delete_image(image_key);
-                        }
-                    }
-                    glutin::VirtualKeyCode::U => {
-                        if let Some(image_key) = self.image_key {
-                            let size = 128;
-                            self.image_generator.generate_image(size);
+                    glutin::VirtualKeyCode::D => if let Some(image_key) = self.image_key.take() {
+                        updates.delete_image(image_key);
+                    },
+                    glutin::VirtualKeyCode::U => if let Some(image_key) = self.image_key {
+                        let size = 128;
+                        self.image_generator.generate_image(size);
 
-                            updates.update_image(
-                                image_key,
-                                ImageDescriptor::new(size, size, ImageFormat::BGRA8, true),
-                                ImageData::new(self.image_generator.take()),
-                                None,
-                            );
-                        }
-                    }
+                        updates.update_image(
+                            image_key,
+                            ImageDescriptor::new(size, size, ImageFormat::BGRA8, true),
+                            ImageData::new(self.image_generator.take()),
+                            None,
+                        );
+                    },
                     glutin::VirtualKeyCode::E => {
                         if let Some(image_key) = self.image_key.take() {
                             updates.delete_image(image_key);
                         }
 
                         let size = 32;
                         let image_key = api.generate_image_key();
 
--- a/gfx/webrender/examples/yuv.rs
+++ b/gfx/webrender/examples/yuv.rs
@@ -1,17 +1,17 @@
 /* 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 gleam;
 extern crate glutin;
 extern crate webrender;
 
-#[path="common/boilerplate.rs"]
+#[path = "common/boilerplate.rs"]
 mod boilerplate;
 
 use boilerplate::Example;
 use glutin::TouchPhase;
 use std::collections::HashMap;
 use webrender::api::*;
 
 #[derive(Debug)]
@@ -41,17 +41,22 @@ impl Touch {
         dist(self.start_x, self.start_y, self.current_x, self.current_y)
     }
 
     fn initial_distance_from_other(&self, other: &Touch) -> f32 {
         dist(self.start_x, self.start_y, other.start_x, other.start_y)
     }
 
     fn current_distance_from_other(&self, other: &Touch) -> f32 {
-        dist(self.current_x, self.current_y, other.current_x, other.current_y)
+        dist(
+            self.current_x,
+            self.current_y,
+            other.current_x,
+            other.current_y,
+        )
     }
 }
 
 struct TouchState {
     active_touches: HashMap<u64, Touch>,
     current_gesture: Gesture,
     start_zoom: f32,
     current_zoom: f32,
@@ -76,32 +81,35 @@ impl TouchState {
             current_pan: DeviceIntPoint::zero(),
         }
     }
 
     fn handle_event(&mut self, touch: glutin::Touch) -> TouchResult {
         match touch.phase {
             TouchPhase::Started => {
                 debug_assert!(!self.active_touches.contains_key(&touch.id));
-                self.active_touches.insert(touch.id, Touch {
-                    id: touch.id,
-                    start_x: touch.location.0 as f32,
-                    start_y: touch.location.1 as f32,
-                    current_x: touch.location.0 as f32,
-                    current_y: touch.location.1 as f32,
-                });
+                self.active_touches.insert(
+                    touch.id,
+                    Touch {
+                        id: touch.id,
+                        start_x: touch.location.0 as f32,
+                        start_y: touch.location.1 as f32,
+                        current_x: touch.location.0 as f32,
+                        current_y: touch.location.1 as f32,
+                    },
+                );
                 self.current_gesture = Gesture::None;
             }
             TouchPhase::Moved => {
                 match self.active_touches.get_mut(&touch.id) {
                     Some(active_touch) => {
                         active_touch.current_x = touch.location.0 as f32;
                         active_touch.current_y = touch.location.1 as f32;
                     }
-                    None => panic!("move touch event with unknown touch id!")
+                    None => panic!("move touch event with unknown touch id!"),
                 }
 
                 match self.current_gesture {
                     Gesture::None => {
                         let mut over_threshold_count = 0;
                         let active_touch_count = self.active_touches.len();
 
                         for (_, touch) in &self.active_touches {
@@ -152,36 +160,36 @@ impl TouchState {
     }
 }
 
 struct App {
     touch_state: TouchState,
 }
 
 impl Example for App {
-    fn render(&mut self,
-              api: &RenderApi,
-              builder: &mut DisplayListBuilder,
-              resources: &mut ResourceUpdates,
-              layout_size: LayoutSize,
-              _pipeline_id: PipelineId,
-              _document_id: DocumentId) {
+    fn render(
+        &mut self,
+        api: &RenderApi,
+        builder: &mut DisplayListBuilder,
+        resources: &mut ResourceUpdates,
+        layout_size: LayoutSize,
+        _pipeline_id: PipelineId,
+        _document_id: DocumentId,
+    ) {
         let bounds = LayoutRect::new(LayoutPoint::zero(), layout_size);
-        let info = LayoutPrimitiveInfo {
-            rect: bounds,
-            local_clip: None,
-            is_backface_visible: true,
-        };
-        builder.push_stacking_context(&info,
-                                      ScrollPolicy::Scrollable,
-                                      None,
-                                      TransformStyle::Flat,
-                                      None,
-                                      MixBlendMode::Normal,
-                                      Vec::new());
+        let info = LayoutPrimitiveInfo::new(bounds);
+        builder.push_stacking_context(
+            &info,
+            ScrollPolicy::Scrollable,
+            None,
+            TransformStyle::Flat,
+            None,
+            MixBlendMode::Normal,
+            Vec::new(),
+        );
 
         let yuv_chanel1 = api.generate_image_key();
         let yuv_chanel2 = api.generate_image_key();
         let yuv_chanel2_1 = api.generate_image_key();
         let yuv_chanel3 = api.generate_image_key();
         resources.add_image(
             yuv_chanel1,
             ImageDescriptor::new(100, 100, ImageFormat::A8, true),
@@ -202,62 +210,55 @@ impl Example for App {
         );
         resources.add_image(
             yuv_chanel3,
             ImageDescriptor::new(100, 100, ImageFormat::A8, true),
             ImageData::new(vec![127; 100 * 100]),
             None,
         );
 
-        let info = LayoutPrimitiveInfo {
-            rect: LayoutRect::new(LayoutPoint::new(100.0, 0.0), LayoutSize::new(100.0, 100.0)),
-            local_clip: Some(LocalClip::from(bounds)),
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::with_clip_rect(
+            LayoutRect::new(LayoutPoint::new(100.0, 0.0), LayoutSize::new(100.0, 100.0)),
+            bounds,
+        );
         builder.push_yuv_image(
             &info,
             YuvData::NV12(yuv_chanel1, yuv_chanel2),
             YuvColorSpace::Rec601,
             ImageRendering::Auto,
         );
 
-        let info = LayoutPrimitiveInfo {
-            rect: LayoutRect::new(LayoutPoint::new(300.0, 0.0), LayoutSize::new(100.0, 100.0)),
-            local_clip: Some(LocalClip::from(bounds)),
-            is_backface_visible: true,
-        };
+        let info = LayoutPrimitiveInfo::with_clip_rect(
+            LayoutRect::new(LayoutPoint::new(300.0, 0.0), LayoutSize::new(100.0, 100.0)),
+            bounds,
+        );
         builder.push_yuv_image(
             &info,
             YuvData::PlanarYCbCr(yuv_chanel1, yuv_chanel2_1, yuv_chanel3),
             YuvColorSpace::Rec601,
             ImageRendering::Auto,
         );
 
         builder.pop_stacking_context();
     }
 
-    fn on_event(&mut self,
-                event: glutin::Event,
-                api: &RenderApi,
-                document_id: DocumentId) -> bool {
+    fn on_event(&mut self, event: glutin::Event, api: &RenderApi, document_id: DocumentId) -> bool {
         match event {
-            glutin::Event::Touch(touch) => {
-                match self.touch_state.handle_event(touch) {
-                    TouchResult::Pan(pan) => {
-                        api.set_pan(document_id, pan);
-                        api.generate_frame(document_id, None);
-                    }
-                    TouchResult::Zoom(zoom) => {
-                        api.set_pinch_zoom(document_id, ZoomFactor::new(zoom));
-                        api.generate_frame(document_id, None);
-                    }
-                    TouchResult::None => {}
+            glutin::Event::Touch(touch) => match self.touch_state.handle_event(touch) {
+                TouchResult::Pan(pan) => {
+                    api.set_pan(document_id, pan);
+                    api.generate_frame(document_id, None);
                 }
-            }
-            _ => ()
+                TouchResult::Zoom(zoom) => {
+                    api.set_pinch_zoom(document_id, ZoomFactor::new(zoom));
+                    api.generate_frame(document_id, None);
+                }
+                TouchResult::None => {}
+            },
+            _ => (),
         }
 
         false
     }
 }
 
 fn main() {
     let mut app = App {
--- a/gfx/webrender/res/clip_shared.glsl
+++ b/gfx/webrender/res/clip_shared.glsl
@@ -36,16 +36,21 @@ ClipMaskInstance fetch_clip_item() {
 }
 
 struct ClipVertexInfo {
     vec3 local_pos;
     vec2 screen_pos;
     RectWithSize clipped_local_rect;
 };
 
+RectWithSize intersect_rect(RectWithSize a, RectWithSize b) {
+    vec4 p = clamp(vec4(a.p0, a.p0 + a.size), b.p0.xyxy, b.p0.xyxy + b.size.xyxy);
+    return RectWithSize(p.xy, max(vec2(0.0), p.zw - p.xy));
+}
+
 // The transformed vertex function that always covers the whole clip area,
 // which is the intersection of all clip instances of a given primitive
 ClipVertexInfo write_clip_tile_vertex(RectWithSize local_clip_rect,
                                       Layer layer,
                                       ClipArea area,
                                       int segment) {
 
     RectWithSize clipped_local_rect = intersect_rect(local_clip_rect,
--- a/gfx/webrender/res/cs_blur.glsl
+++ b/gfx/webrender/res/cs_blur.glsl
@@ -28,18 +28,18 @@ void main(void) {
     vec4 local_rect = task.data0;
 
     vec2 pos = mix(local_rect.xy,
                    local_rect.xy + local_rect.zw,
                    aPosition.xy);
 
     vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0).xy);
     vUv.z = src_task.data1.x;
-    vBlurRadius = int(task.data1.y);
-    vSigma = task.data1.y * 0.5;
+    vBlurRadius = 3 * int(task.data1.y);
+    vSigma = task.data1.y;
 
     switch (aBlurDirection) {
         case DIR_HORIZONTAL:
             vOffsetScale = vec2(1.0 / texture_size.x, 0.0);
             break;
         case DIR_VERTICAL:
             vOffsetScale = vec2(0.0, 1.0 / texture_size.y);
             break;
@@ -60,46 +60,46 @@ void main(void) {
 #ifdef WR_FRAGMENT_SHADER
 // TODO(gw): Write a fast path blur that handles smaller blur radii
 //           with a offset / weight uniform table and a constant
 //           loop iteration count!
 
 // TODO(gw): Make use of the bilinear sampling trick to reduce
 //           the number of texture fetches needed for a gaussian blur.
 
-float gauss(float x, float sigma) {
-    return (1.0 / sqrt(6.283185307179586 * sigma * sigma)) * exp(-(x * x) / (2.0 * sigma * sigma));
-}
-
 void main(void) {
-    vec4 cache_sample = texture(sCacheRGBA8, vUv);
+    vec4 original_color = texture(sCacheRGBA8, vUv);
 
     // TODO(gw): The gauss function gets NaNs when blur radius
     //           is zero. In the future, detect this earlier
     //           and skip the blur passes completely.
     if (vBlurRadius == 0) {
-        oFragColor = cache_sample;
+        oFragColor = original_color;
         return;
     }
 
-    vec4 color = vec4(cache_sample.rgb, 1.0) * (cache_sample.a * gauss(0.0, vSigma));
+    // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
+    vec3 gauss_coefficient;
+    gauss_coefficient.x = 1.0 / (sqrt(2.0 * 3.14159265) * vSigma);
+    gauss_coefficient.y = exp(-0.5 / (vSigma * vSigma));
+    gauss_coefficient.z = gauss_coefficient.y * gauss_coefficient.y;
 
-    for (int i=1 ; i < vBlurRadius ; ++i) {
-        vec2 offset = vec2(float(i)) * vOffsetScale;
-
-        vec2 st0 = clamp(vUv.xy + offset, vUvRect.xy, vUvRect.zw);
-        vec4 color0 = texture(sCacheRGBA8, vec3(st0, vUv.z));
+    float gauss_coefficient_sum = 0.0;
+    vec4 avg_color = original_color * gauss_coefficient.x;
+    gauss_coefficient_sum += gauss_coefficient.x;
+    gauss_coefficient.xy *= gauss_coefficient.yz;
 
-        vec2 st1 = clamp(vUv.xy - offset, vUvRect.xy, vUvRect.zw);
-        vec4 color1 = texture(sCacheRGBA8, vec3(st1, vUv.z));
+    for (int i=1 ; i <= vBlurRadius/2 ; ++i) {
+        vec2 offset = vOffsetScale * float(i);
+
+        vec2 st0 = clamp(vUv.xy - offset, vUvRect.xy, vUvRect.zw);
+        avg_color += texture(sCacheRGBA8, vec3(st0, vUv.z)) * gauss_coefficient.x;
 
-        // Alpha must be premultiplied in order to properly blur the alpha channel.
-        float weight = gauss(float(i), vSigma);
-        color += vec4(color0.rgb * color0.a, color0.a) * weight;
-        color += vec4(color1.rgb * color1.a, color1.a) * weight;
+        vec2 st1 = clamp(vUv.xy + offset, vUvRect.xy, vUvRect.zw);
+        avg_color += texture(sCacheRGBA8, vec3(st1, vUv.z)) * gauss_coefficient.x;
+
+        gauss_coefficient_sum += 2.0 * gauss_coefficient.x;
+        gauss_coefficient.xy *= gauss_coefficient.yz;
     }
 
-    // Unpremultiply the alpha.
-    color.rgb /= color.a;
-
-    oFragColor = dither(color);
+    oFragColor = avg_color / gauss_coefficient_sum;
 }
 #endif
deleted file mode 100644
--- a/gfx/webrender/res/cs_clip_border.fs.glsl
+++ /dev/null
@@ -1,39 +0,0 @@
-/* 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/. */
-
-void main(void) {
-    vec2 local_pos = vPos.xy / vPos.z;
-
-    // Get local space position relative to the clip center.
-    vec2 clip_relative_pos = local_pos - vClipCenter;
-
-    // Get the signed distances to the two clip lines.
-    float d0 = distance_to_line(vPoint_Tangent0.xy,
-                                vPoint_Tangent0.zw,
-                                clip_relative_pos);
-    float d1 = distance_to_line(vPoint_Tangent1.xy,
-                                vPoint_Tangent1.zw,
-                                clip_relative_pos);
-
-    // Get AA widths based on zoom / scale etc.
-    vec2 fw = fwidth(local_pos);
-    float afwidth = length(fw);
-
-    // SDF subtract edges for dash clip
-    float dash_distance = max(d0, -d1);
-
-    // Get distance from dot.
-    float dot_distance = distance(clip_relative_pos, vDotParams.xy) - vDotParams.z;
-
-    // Select between dot/dash clip based on mode.
-    float d = mix(dash_distance, dot_distance, vAlphaMask.x);
-
-    // Apply AA over half a device pixel for the clip.
-    d = 1.0 - smoothstep(0.0, 0.5 * afwidth, d);
-
-    // Completely mask out clip if zero'ing out the rect.
-    d = d * vAlphaMask.y;
-
-    oFragColor = vec4(d, 0.0, 0.0, 1.0);
-}
--- a/gfx/webrender/res/cs_clip_border.glsl
+++ b/gfx/webrender/res/cs_clip_border.glsl
@@ -7,8 +7,172 @@
 varying vec3 vPos;
 
 flat varying vec2 vClipCenter;
 
 flat varying vec4 vPoint_Tangent0;
 flat varying vec4 vPoint_Tangent1;
 flat varying vec3 vDotParams;
 flat varying vec2 vAlphaMask;
+
+#ifdef WR_VERTEX_SHADER
+// Matches BorderCorner enum in border.rs
+#define CORNER_TOP_LEFT     0
+#define CORNER_TOP_RIGHT    1
+#define CORNER_BOTTOM_LEFT  2
+#define CORNER_BOTTOM_RIGHT 3
+
+// Matches BorderCornerClipKind enum in border.rs
+#define CLIP_MODE_DASH      0
+#define CLIP_MODE_DOT       1
+
+// Header for a border corner clip.
+struct BorderCorner {
+    RectWithSize rect;
+    vec2 clip_center;
+    int corner;
+    int clip_mode;
+};
+
+BorderCorner fetch_border_corner(ivec2 address) {
+    vec4 data[2] = fetch_from_resource_cache_2_direct(address);
+    return BorderCorner(RectWithSize(data[0].xy, data[0].zw),
+                        data[1].xy,
+                        int(data[1].z),
+                        int(data[1].w));
+}
+
+// Per-dash clip information.
+struct BorderClipDash {
+    vec4 point_tangent_0;
+    vec4 point_tangent_1;
+};
+
+BorderClipDash fetch_border_clip_dash(ivec2 address, int segment) {
+    vec4 data[2] = fetch_from_resource_cache_2_direct(address + ivec2(2 + 2 * (segment - 1), 0));
+    return BorderClipDash(data[0], data[1]);
+}
+
+// Per-dot clip information.
+struct BorderClipDot {
+    vec3 center_radius;
+};
+
+BorderClipDot fetch_border_clip_dot(ivec2 address, int segment) {
+    vec4 data = fetch_from_resource_cache_1_direct(address + ivec2(2 + (segment - 1), 0));
+    return BorderClipDot(data.xyz);
+}
+
+void main(void) {
+    ClipMaskInstance cmi = fetch_clip_item();
+    ClipArea area = fetch_clip_area(cmi.render_task_address);
+    Layer layer = fetch_layer(cmi.layer_address);
+
+    // Fetch the header information for this corner clip.
+    BorderCorner corner = fetch_border_corner(cmi.clip_data_address);
+    vClipCenter = corner.clip_center;
+
+    if (cmi.segment == 0) {
+        // The first segment is used to zero out the border corner.
+        vAlphaMask = vec2(0.0);
+        vDotParams = vec3(0.0);
+        vPoint_Tangent0 = vec4(1.0);
+        vPoint_Tangent1 = vec4(1.0);
+    } else {
+        vec2 sign_modifier;
+        switch (corner.corner) {
+            case CORNER_TOP_LEFT:
+                sign_modifier = vec2(-1.0);
+                break;
+            case CORNER_TOP_RIGHT:
+                sign_modifier = vec2(1.0, -1.0);
+                break;
+            case CORNER_BOTTOM_RIGHT:
+                sign_modifier = vec2(1.0);
+                break;
+            case CORNER_BOTTOM_LEFT:
+                sign_modifier = vec2(-1.0, 1.0);
+                break;
+        };
+
+        switch (corner.clip_mode) {
+            case CLIP_MODE_DASH: {
+                // Fetch the information about this particular dash.
+                BorderClipDash dash = fetch_border_clip_dash(cmi.clip_data_address, cmi.segment);
+                vPoint_Tangent0 = dash.point_tangent_0 * sign_modifier.xyxy;
+                vPoint_Tangent1 = dash.point_tangent_1 * sign_modifier.xyxy;
+                vDotParams = vec3(0.0);
+                vAlphaMask = vec2(0.0, 1.0);
+                break;
+            }
+            case CLIP_MODE_DOT: {
+                BorderClipDot cdot = fetch_border_clip_dot(cmi.clip_data_address, cmi.segment);
+                vPoint_Tangent0 = vec4(1.0);
+                vPoint_Tangent1 = vec4(1.0);
+                vDotParams = vec3(cdot.center_radius.xy * sign_modifier, cdot.center_radius.z);
+                vAlphaMask = vec2(1.0, 1.0);
+                break;
+            }
+        }
+    }
+
+    // Get local vertex position for the corner rect.
+    // TODO(gw): We could reduce the number of pixels written here
+    // by calculating a tight fitting bounding box of the dash itself.
+    vec2 pos = corner.rect.p0 + aPosition.xy * corner.rect.size;
+
+    // Transform to world pos
+    vec4 world_pos = layer.transform * vec4(pos, 0.0, 1.0);
+    world_pos.xyz /= world_pos.w;
+
+    // Scale into device pixels.
+    vec2 device_pos = world_pos.xy * uDevicePixelRatio;
+
+    // Position vertex within the render task area.
+    vec2 final_pos = device_pos -
+                     area.screen_origin_target_index.xy +
+                     area.task_bounds.xy;
+
+    // Calculate the local space position for this vertex.
+    vec4 layer_pos = get_layer_pos(world_pos.xy, layer);
+    vPos = layer_pos.xyw;
+
+    gl_Position = uTransform * vec4(final_pos, 0.0, 1.0);
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+    vec2 local_pos = vPos.xy / vPos.z;
+
+    // Get local space position relative to the clip center.
+    vec2 clip_relative_pos = local_pos - vClipCenter;
+
+    // Get the signed distances to the two clip lines.
+    float d0 = distance_to_line(vPoint_Tangent0.xy,
+                                vPoint_Tangent0.zw,
+                                clip_relative_pos);
+    float d1 = distance_to_line(vPoint_Tangent1.xy,
+                                vPoint_Tangent1.zw,
+                                clip_relative_pos);
+
+    // Get AA widths based on zoom / scale etc.
+    vec2 fw = fwidth(local_pos);
+    float afwidth = length(fw);
+
+    // SDF subtract edges for dash clip
+    float dash_distance = max(d0, -d1);
+
+    // Get distance from dot.
+    float dot_distance = distance(clip_relative_pos, vDotParams.xy) - vDotParams.z;
+
+    // Select between dot/dash clip based on mode.
+    float d = mix(dash_distance, dot_distance, vAlphaMask.x);
+
+    // Apply AA over half a device pixel for the clip.
+    d = 1.0 - smoothstep(0.0, 0.5 * afwidth, d);
+
+    // Completely mask out clip if zero'ing out the rect.
+    d = d * vAlphaMask.y;
+
+    oFragColor = vec4(d, 0.0, 0.0, 1.0);
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/cs_clip_border.vs.glsl
+++ /dev/null
@@ -1,127 +0,0 @@
-/* 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/. */
-
-// Matches BorderCorner enum in border.rs
-#define CORNER_TOP_LEFT     0
-#define CORNER_TOP_RIGHT    1
-#define CORNER_BOTTOM_LEFT  2
-#define CORNER_BOTTOM_RIGHT 3
-
-// Matches BorderCornerClipKind enum in border.rs
-#define CLIP_MODE_DASH      0
-#define CLIP_MODE_DOT       1
-
-// Header for a border corner clip.
-struct BorderCorner {
-    RectWithSize rect;
-    vec2 clip_center;
-    int corner;
-    int clip_mode;
-};
-
-BorderCorner fetch_border_corner(ivec2 address) {
-    vec4 data[2] = fetch_from_resource_cache_2_direct(address);
-    return BorderCorner(RectWithSize(data[0].xy, data[0].zw),
-                        data[1].xy,
-                        int(data[1].z),
-                        int(data[1].w));
-}
-
-// Per-dash clip information.
-struct BorderClipDash {
-    vec4 point_tangent_0;
-    vec4 point_tangent_1;
-};
-
-BorderClipDash fetch_border_clip_dash(ivec2 address, int segment) {
-    vec4 data[2] = fetch_from_resource_cache_2_direct(address + ivec2(2 + 2 * (segment - 1), 0));
-    return BorderClipDash(data[0], data[1]);
-}
-
-// Per-dot clip information.
-struct BorderClipDot {
-    vec3 center_radius;
-};
-
-BorderClipDot fetch_border_clip_dot(ivec2 address, int segment) {
-    vec4 data = fetch_from_resource_cache_1_direct(address + ivec2(2 + (segment - 1), 0));
-    return BorderClipDot(data.xyz);
-}
-
-void main(void) {
-    ClipMaskInstance cmi = fetch_clip_item();
-    ClipArea area = fetch_clip_area(cmi.render_task_address);
-    Layer layer = fetch_layer(cmi.layer_address);
-
-    // Fetch the header information for this corner clip.
-    BorderCorner corner = fetch_border_corner(cmi.clip_data_address);
-    vClipCenter = corner.clip_center;
-
-    if (cmi.segment == 0) {
-        // The first segment is used to zero out the border corner.
-        vAlphaMask = vec2(0.0);
-        vDotParams = vec3(0.0);
-        vPoint_Tangent0 = vec4(1.0);
-        vPoint_Tangent1 = vec4(1.0);
-    } else {
-        vec2 sign_modifier;
-        switch (corner.corner) {
-            case CORNER_TOP_LEFT:
-                sign_modifier = vec2(-1.0);
-                break;
-            case CORNER_TOP_RIGHT:
-                sign_modifier = vec2(1.0, -1.0);
-                break;
-            case CORNER_BOTTOM_RIGHT:
-                sign_modifier = vec2(1.0);
-                break;
-            case CORNER_BOTTOM_LEFT:
-                sign_modifier = vec2(-1.0, 1.0);
-                break;
-        };
-
-        switch (corner.clip_mode) {
-            case CLIP_MODE_DASH: {
-                // Fetch the information about this particular dash.
-                BorderClipDash dash = fetch_border_clip_dash(cmi.clip_data_address, cmi.segment);
-                vPoint_Tangent0 = dash.point_tangent_0 * sign_modifier.xyxy;
-                vPoint_Tangent1 = dash.point_tangent_1 * sign_modifier.xyxy;
-                vDotParams = vec3(0.0);
-                vAlphaMask = vec2(0.0, 1.0);
-                break;
-            }
-            case CLIP_MODE_DOT: {
-                BorderClipDot cdot = fetch_border_clip_dot(cmi.clip_data_address, cmi.segment);
-                vPoint_Tangent0 = vec4(1.0);
-                vPoint_Tangent1 = vec4(1.0);
-                vDotParams = vec3(cdot.center_radius.xy * sign_modifier, cdot.center_radius.z);
-                vAlphaMask = vec2(1.0, 1.0);
-                break;
-            }
-        }
-    }
-
-    // Get local vertex position for the corner rect.
-    // TODO(gw): We could reduce the number of pixels written here
-    // by calculating a tight fitting bounding box of the dash itself.
-    vec2 pos = corner.rect.p0 + aPosition.xy * corner.rect.size;
-
-    // Transform to world pos
-    vec4 world_pos = layer.transform * vec4(pos, 0.0, 1.0);
-    world_pos.xyz /= world_pos.w;
-
-    // Scale into device pixels.
-    vec2 device_pos = world_pos.xy * uDevicePixelRatio;
-
-    // Position vertex within the render task area.
-    vec2 final_pos = device_pos -
-                     area.screen_origin_target_index.xy +
-                     area.task_bounds.xy;
-
-    // Calculate the local space position for this vertex.
-    vec4 layer_pos = get_layer_pos(world_pos.xy, layer);
-    vPos = layer_pos.xyw;
-
-    gl_Position = uTransform * vec4(final_pos, 0.0, 1.0);
-}
deleted file mode 100644
--- a/gfx/webrender/res/cs_clip_image.fs.glsl
+++ /dev/null
@@ -1,17 +0,0 @@
-/* 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/. */
-
-void main(void) {
-    float alpha = 1.f;
-    vec2 local_pos = init_transform_fs(vPos, alpha);
-
-    bool repeat_mask = false; //TODO
-    vec2 clamped_mask_uv = repeat_mask ? fract(vClipMaskUv.xy) :
-        clamp(vClipMaskUv.xy, vec2(0.0, 0.0), vec2(1.0, 1.0));
-    vec2 source_uv = clamp(clamped_mask_uv * vClipMaskUvRect.zw + vClipMaskUvRect.xy,
-        vClipMaskUvInnerRect.xy, vClipMaskUvInnerRect.zw);
-    float clip_alpha = texture(sColor0, vec3(source_uv, vLayer)).r; //careful: texture has type A8
-
-    oFragColor = vec4(min(alpha, clip_alpha), 1.0, 1.0, 1.0);
-}
--- a/gfx/webrender/res/cs_clip_image.glsl
+++ b/gfx/webrender/res/cs_clip_image.glsl
@@ -3,8 +3,59 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include shared,prim_shared,clip_shared
 
 varying vec3 vPos;
 flat varying vec4 vClipMaskUvRect;
 flat varying vec4 vClipMaskUvInnerRect;
 flat varying float vLayer;
+
+#ifdef WR_VERTEX_SHADER
+struct ImageMaskData {
+    RectWithSize local_rect;
+};
+
+ImageMaskData fetch_mask_data(ivec2 address) {
+    vec4 data = fetch_from_resource_cache_1_direct(address);
+    return ImageMaskData(RectWithSize(data.xy, data.zw));
+}
+
+void main(void) {
+    ClipMaskInstance cmi = fetch_clip_item();
+    ClipArea area = fetch_clip_area(cmi.render_task_address);
+    Layer layer = fetch_layer(cmi.layer_address);
+    ImageMaskData mask = fetch_mask_data(cmi.clip_data_address);
+    RectWithSize local_rect = mask.local_rect;
+    ImageResource res = fetch_image_resource_direct(cmi.resource_address);
+
+    ClipVertexInfo vi = write_clip_tile_vertex(local_rect,
+                                               layer,
+                                               area,
+                                               cmi.segment);
+
+    vPos = vi.local_pos;
+    vLayer = res.layer;
+
+    vClipMaskUv = vec3((vPos.xy / vPos.z - local_rect.p0) / local_rect.size, 0.0);
+    vec2 texture_size = vec2(textureSize(sColor0, 0));
+    vClipMaskUvRect = vec4(res.uv_rect.xy, res.uv_rect.zw - res.uv_rect.xy) / texture_size.xyxy;
+    // applying a half-texel offset to the UV boundaries to prevent linear samples from the outside
+    vec4 inner_rect = vec4(res.uv_rect.xy, res.uv_rect.zw);
+    vClipMaskUvInnerRect = (inner_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+    float alpha = 1.f;
+    vec2 local_pos = init_transform_fs(vPos, alpha);
+
+    bool repeat_mask = false; //TODO
+    vec2 clamped_mask_uv = repeat_mask ? fract(vClipMaskUv.xy) :
+        clamp(vClipMaskUv.xy, vec2(0.0, 0.0), vec2(1.0, 1.0));
+    vec2 source_uv = clamp(clamped_mask_uv * vClipMaskUvRect.zw + vClipMaskUvRect.xy,
+        vClipMaskUvInnerRect.xy, vClipMaskUvInnerRect.zw);
+    float clip_alpha = texture(sColor0, vec3(source_uv, vLayer)).r; //careful: texture has type A8
+
+    oFragColor = vec4(min(alpha, clip_alpha), 1.0, 1.0, 1.0);
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/cs_clip_image.vs.glsl
+++ /dev/null
@@ -1,36 +0,0 @@
-/* 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/. */
-
-struct ImageMaskData {
-    RectWithSize local_rect;
-};
-
-ImageMaskData fetch_mask_data(ivec2 address) {
-    vec4 data = fetch_from_resource_cache_1_direct(address);
-    return ImageMaskData(RectWithSize(data.xy, data.zw));
-}
-
-void main(void) {
-    ClipMaskInstance cmi = fetch_clip_item();
-    ClipArea area = fetch_clip_area(cmi.render_task_address);
-    Layer layer = fetch_layer(cmi.layer_address);
-    ImageMaskData mask = fetch_mask_data(cmi.clip_data_address);
-    RectWithSize local_rect = mask.local_rect;
-    ImageResource res = fetch_image_resource_direct(cmi.resource_address);
-
-    ClipVertexInfo vi = write_clip_tile_vertex(local_rect,
-                                               layer,
-                                               area,
-                                               cmi.segment);
-
-    vPos = vi.local_pos;
-    vLayer = res.layer;
-
-    vClipMaskUv = vec3((vPos.xy / vPos.z - local_rect.p0) / local_rect.size, 0.0);
-    vec2 texture_size = vec2(textureSize(sColor0, 0));
-    vClipMaskUvRect = vec4(res.uv_rect.xy, res.uv_rect.zw - res.uv_rect.xy) / texture_size.xyxy;
-    // applying a half-texel offset to the UV boundaries to prevent linear samples from the outside
-    vec4 inner_rect = vec4(res.uv_rect.xy, res.uv_rect.zw);
-    vClipMaskUvInnerRect = (inner_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
-}
deleted file mode 100644
--- a/gfx/webrender/res/cs_text_run.fs.glsl
+++ /dev/null
@@ -1,8 +0,0 @@
-/* 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/. */
-
-void main(void) {
-    float a = texture(sColor0, vUv).a;
-    oFragColor = vec4(vColor.rgb, vColor.a * a);
-}
--- a/gfx/webrender/res/cs_text_run.glsl
+++ b/gfx/webrender/res/cs_text_run.glsl
@@ -1,8 +1,67 @@
 /* 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/. */
 
 #include shared,prim_shared
 
 varying vec3 vUv;
 flat varying vec4 vColor;
+
+#ifdef WR_VERTEX_SHADER
+// Draw a text run to a cache target. These are always
+// drawn un-transformed. These are used for effects such
+// as text-shadow.
+
+void main(void) {
+    Primitive prim = load_primitive();
+    TextRun text = fetch_text_run(prim.specific_prim_address);
+
+    int glyph_index = prim.user_data0;
+    int resource_address = prim.user_data1;
+    int text_shadow_address = prim.user_data2;
+
+    // Fetch the parent text-shadow for this primitive. This allows the code
+    // below to normalize the glyph offsets relative to the original text
+    // shadow rect, which is the union of all elements that make up this
+    // text shadow. This allows the text shadow to be rendered at an
+    // arbitrary location in a render target (provided by the render
+    // task render_target_origin field).
+    PrimitiveGeometry shadow_geom = fetch_primitive_geometry(text_shadow_address);
+    TextShadow shadow = fetch_text_shadow(text_shadow_address + VECS_PER_PRIM_HEADER);
+
+    Glyph glyph = fetch_glyph(prim.specific_prim_address,
+                              glyph_index,
+                              text.subpx_dir);
+
+    GlyphResource res = fetch_glyph_resource(resource_address);
+
+    // Glyphs size is already in device-pixels.
+    // The render task origin is in device-pixels. Offset that by
+    // the glyph offset, relative to its primitive bounding rect.
+    vec2 size = res.uv_rect.zw - res.uv_rect.xy;
+    vec2 local_pos = glyph.offset + vec2(res.offset.x, -res.offset.y) / uDevicePixelRatio;
+    vec2 origin = prim.task.render_target_origin +
+                  uDevicePixelRatio * (local_pos + shadow.offset - shadow_geom.local_rect.p0);
+    vec4 local_rect = vec4(origin, size);
+
+    vec2 texture_size = vec2(textureSize(sColor0, 0));
+    vec2 st0 = res.uv_rect.xy / texture_size;
+    vec2 st1 = res.uv_rect.zw / texture_size;
+
+    vec2 pos = mix(local_rect.xy,
+                   local_rect.xy + local_rect.zw,
+                   aPosition.xy);
+
+    vUv = vec3(mix(st0, st1, aPosition.xy), res.layer);
+    vColor = shadow.color;
+
+    gl_Position = uTransform * vec4(pos, 0.0, 1.0);
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+    float a = texture(sColor0, vUv).a;
+    oFragColor = vec4(vColor.rgb, vColor.a * a);
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/cs_text_run.vs.glsl
+++ /dev/null
@@ -1,53 +0,0 @@
-/* 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/. */
-
-// Draw a text run to a cache target. These are always
-// drawn un-transformed. These are used for effects such
-// as text-shadow.
-
-void main(void) {
-    Primitive prim = load_primitive();
-    TextRun text = fetch_text_run(prim.specific_prim_address);
-
-    int glyph_index = prim.user_data0;
-    int resource_address = prim.user_data1;
-    int text_shadow_address = prim.user_data2;
-
-    // Fetch the parent text-shadow for this primitive. This allows the code
-    // below to normalize the glyph offsets relative to the original text
-    // shadow rect, which is the union of all elements that make up this
-    // text shadow. This allows the text shadow to be rendered at an
-    // arbitrary location in a render target (provided by the render
-    // task render_target_origin field).
-    PrimitiveGeometry shadow_geom = fetch_primitive_geometry(text_shadow_address);
-    TextShadow shadow = fetch_text_shadow(text_shadow_address + VECS_PER_PRIM_HEADER);
-
-    Glyph glyph = fetch_glyph(prim.specific_prim_address,
-                              glyph_index,
-                              text.subpx_dir);
-
-    GlyphResource res = fetch_glyph_resource(resource_address);
-
-    // Glyphs size is already in device-pixels.
-    // The render task origin is in device-pixels. Offset that by
-    // the glyph offset, relative to its primitive bounding rect.
-    vec2 size = res.uv_rect.zw - res.uv_rect.xy;
-    vec2 local_pos = glyph.offset + vec2(res.offset.x, -res.offset.y) / uDevicePixelRatio;
-    vec2 origin = prim.task.render_target_origin +
-                  uDevicePixelRatio * (local_pos + shadow.offset - shadow_geom.local_rect.p0);
-    vec4 local_rect = vec4(origin, size);
-
-    vec2 texture_size = vec2(textureSize(sColor0, 0));
-    vec2 st0 = res.uv_rect.xy / texture_size;
-    vec2 st1 = res.uv_rect.zw / texture_size;
-
-    vec2 pos = mix(local_rect.xy,
-                   local_rect.xy + local_rect.zw,
-                   aPosition.xy);
-
-    vUv = vec3(mix(st0, st1, aPosition.xy), res.layer);
-    vColor = shadow.color;
-
-    gl_Position = uTransform * vec4(pos, 0.0, 1.0);
-}
--- a/gfx/webrender/res/prim_shared.glsl
+++ b/gfx/webrender/res/prim_shared.glsl
@@ -1,12 +1,14 @@
 /* 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/. */
 
+#include rect
+
 #define EXTEND_MODE_CLAMP  0
 #define EXTEND_MODE_REPEAT 1
 
 #define LINE_STYLE_SOLID        0
 #define LINE_STYLE_DOTTED       1
 #define LINE_STYLE_DASHED       2
 #define LINE_STYLE_WAVY         3
 
@@ -17,51 +19,20 @@
 uniform sampler2DArray sCacheA8;
 uniform sampler2DArray sCacheRGBA8;
 
 // An A8 target for standalone tasks that is available to all passes.
 uniform sampler2DArray sSharedCacheA8;
 
 uniform sampler2D sGradients;
 
-struct RectWithSize {
-    vec2 p0;
-    vec2 size;
-};
-
-struct RectWithEndpoint {
-    vec2 p0;
-    vec2 p1;
-};
-
-RectWithEndpoint to_rect_with_endpoint(RectWithSize rect) {
-    RectWithEndpoint result;
-    result.p0 = rect.p0;
-    result.p1 = rect.p0 + rect.size;
-
-    return result;
-}
-
-RectWithSize to_rect_with_size(RectWithEndpoint rect) {
-    RectWithSize result;
-    result.p0 = rect.p0;
-    result.size = rect.p1 - rect.p0;
-
-    return result;
-}
-
 vec2 clamp_rect(vec2 point, RectWithSize rect) {
     return clamp(point, rect.p0, rect.p0 + rect.size);
 }
 
-RectWithSize intersect_rect(RectWithSize a, RectWithSize b) {
-    vec4 p = clamp(vec4(a.p0, a.p0 + a.size), b.p0.xyxy, b.p0.xyxy + b.size.xyxy);
-    return RectWithSize(p.xy, max(vec2(0.0), p.zw - p.xy));
-}
-
 float distance_to_line(vec2 p0, vec2 perp_dir, vec2 p) {
     vec2 dir_to_p0 = p0 - p;
     return dot(normalize(perp_dir), dir_to_p0);
 }
 
 // TODO: convert back to RectWithEndPoint if driver issues are resolved, if ever.
 flat varying vec4 vClipMaskUvBounds;
 varying vec3 vClipMaskUv;
@@ -237,33 +208,16 @@ AlphaBatchTask fetch_alpha_batch_task(in
     task.render_target_origin = data.data0.xy;
     task.size = data.data0.zw;
     task.screen_space_origin = data.data1.xy;
     task.render_target_layer_index = data.data1.z;
 
     return task;
 }
 
-struct ReadbackTask {
-    vec2 render_target_origin;
-    vec2 size;
-    float render_target_layer_index;
-};
-
-ReadbackTask fetch_readback_task(int index) {
-    RenderTaskData data = fetch_render_task(index);
-
-    ReadbackTask task;
-    task.render_target_origin = data.data0.xy;
-    task.size = data.data0.zw;
-    task.render_target_layer_index = data.data1.x;
-
-    return task;
-}
-
 struct ClipArea {
     vec4 task_bounds;
     vec4 screen_origin_target_index;
     vec4 inner_rect;
 };
 
 ClipArea fetch_clip_area(int index) {
     ClipArea area;
@@ -330,31 +284,30 @@ Glyph fetch_glyph(int specific_prim_addr
     vec2 glyph = mix(data.xy, data.zw, bvec2(glyph_index % 2 == 1));
 
     // In subpixel mode, the subpixel offset has already been
     // accounted for while rasterizing the glyph.
     switch (subpx_dir) {
         case SUBPX_DIR_NONE:
             break;
         case SUBPX_DIR_HORIZONTAL:
-            glyph.x = trunc(glyph.x);
+            // Glyphs positioned [-0.125, 0.125] get a
+            // subpx position of zero. So include that
+            // offset in the glyph position to ensure
+            // we truncate to the correct whole position.
+            glyph.x = trunc(glyph.x + 0.125);
             break;
         case SUBPX_DIR_VERTICAL:
-            glyph.y = trunc(glyph.y);
+            glyph.y = trunc(glyph.y + 0.125);
             break;
     }
 
     return Glyph(glyph);
 }
 
-RectWithSize fetch_instance_geometry(int address) {
-    vec4 data = fetch_from_resource_cache_1(address);
-    return RectWithSize(data.xy, data.zw);
-}
-
 struct PrimitiveInstance {
     int prim_address;
     int specific_prim_address;
     int render_task_index;
     int clip_task_index;
     int layer_index;
     int z;
     int user_data0;
@@ -705,27 +658,16 @@ struct TextShadow {
     float blur_radius;
 };
 
 TextShadow fetch_text_shadow(int address) {
     vec4 data[2] = fetch_from_resource_cache_2(address);
     return TextShadow(data[0], data[1].xy, data[1].z);
 }
 
-struct Line {
-    vec4 color;
-    float style;
-    float orientation;
-};
-
-Line fetch_line(int address) {
-    vec4 data[2] = fetch_from_resource_cache_2(address);
-    return Line(data[0], data[1].x, data[1].y);
-}
-
 struct TextRun {
     vec4 color;
     vec2 offset;
     int subpx_dir;
 };
 
 TextRun fetch_text_run(int address) {
     vec4 data[2] = fetch_from_resource_cache_2(address);
@@ -738,25 +680,16 @@ struct Image {
     vec4 sub_rect;                          // If negative, ignored.
 };
 
 Image fetch_image(int address) {
     vec4 data[2] = fetch_from_resource_cache_2(address);
     return Image(data[0], data[1]);
 }
 
-struct YuvImage {
-    vec2 size;
-};
-
-YuvImage fetch_yuv_image(int address) {
-    vec4 data = fetch_from_resource_cache_1(address);
-    return YuvImage(data.xy);
-}
-
 struct BoxShadow {
     vec4 src_rect;
     vec4 bs_rect;
     vec4 color;
     vec4 border_radius_edge_size_blur_radius_inverted;
 };
 
 BoxShadow fetch_boxshadow(int address) {
deleted file mode 100644
--- a/gfx/webrender/res/ps_blend.fs.glsl
+++ /dev/null
@@ -1,139 +0,0 @@
-/* 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/. */
-
-vec3 rgbToHsv(vec3 c) {
-    float value = max(max(c.r, c.g), c.b);
-
-    float chroma = value - min(min(c.r, c.g), c.b);
-    if (chroma == 0.0) {
-        return vec3(0.0);
-    }
-    float saturation = chroma / value;
-
-    float hue;
-    if (c.r == value)
-        hue = (c.g - c.b) / chroma;
-    else if (c.g == value)
-        hue = 2.0 + (c.b - c.r) / chroma;
-    else // if (c.b == value)
-        hue = 4.0 + (c.r - c.g) / chroma;
-
-    hue *= 1.0/6.0;
-    if (hue < 0.0)
-        hue += 1.0;
-    return vec3(hue, saturation, value);
-}
-
-vec3 hsvToRgb(vec3 c) {
-    if (c.s == 0.0) {
-        return vec3(c.z);
-    }
-
-    float hue = c.x * 6.0;
-    int sector = int(hue);
-    float residualHue = hue - float(sector);
-
-    vec3 pqt = c.z * vec3(1.0 - c.y, 1.0 - c.y * residualHue, 1.0 - c.y * (1.0 - residualHue));
-    switch (sector) {
-        case 0:
-            return vec3(c.z, pqt.z, pqt.x);
-        case 1:
-            return vec3(pqt.y, c.z, pqt.x);
-        case 2:
-            return vec3(pqt.x, c.z, pqt.z);
-        case 3:
-            return vec3(pqt.x, pqt.y, c.z);
-        case 4:
-            return vec3(pqt.z, pqt.x, c.z);
-        default:
-            return vec3(c.z, pqt.x, pqt.y);
-    }
-}
-
-vec4 Blur(float radius, vec2 direction) {
-    // TODO(gw): Support blur in WR2!
-    return vec4(1.0);
-}
-
-vec4 Contrast(vec4 Cs, float amount) {
-    return vec4(Cs.rgb * amount - 0.5 * amount + 0.5, 1.0);
-}
-
-vec4 Grayscale(vec4 Cs, float amount) {
-    float ia = 1.0 - amount;
-    return mat4(vec4(0.2126 + 0.7874 * ia, 0.2126 - 0.2126 * ia, 0.2126 - 0.2126 * ia, 0.0),
-                vec4(0.7152 - 0.7152 * ia, 0.7152 + 0.2848 * ia, 0.7152 - 0.7152 * ia, 0.0),
-                vec4(0.0722 - 0.0722 * ia, 0.0722 - 0.0722 * ia, 0.0722 + 0.9278 * ia, 0.0),
-                vec4(0.0, 0.0, 0.0, 1.0)) * Cs;
-}
-
-vec4 HueRotate(vec4 Cs, float amount) {
-    vec3 CsHsv = rgbToHsv(Cs.rgb);
-    CsHsv.x = mod(CsHsv.x + amount / 6.283185307179586, 1.0);
-    return vec4(hsvToRgb(CsHsv), Cs.a);
-}
-
-vec4 Invert(vec4 Cs, float amount) {
-    return mix(Cs, vec4(1.0, 1.0, 1.0, Cs.a) - vec4(Cs.rgb, 0.0), amount);
-}
-
-vec4 Saturate(vec4 Cs, float amount) {
-    return vec4(hsvToRgb(min(vec3(1.0, amount, 1.0) * rgbToHsv(Cs.rgb), vec3(1.0))), Cs.a);
-}
-
-vec4 Sepia(vec4 Cs, float amount) {
-    float ia = 1.0 - amount;
-    return mat4(vec4(0.393 + 0.607 * ia, 0.349 - 0.349 * ia, 0.272 - 0.272 * ia, 0.0),
-                vec4(0.769 - 0.769 * ia, 0.686 + 0.314 * ia, 0.534 - 0.534 * ia, 0.0),
-                vec4(0.189 - 0.189 * ia, 0.168 - 0.168 * ia, 0.131 + 0.869 * ia, 0.0),
-                vec4(0.0, 0.0, 0.0, 1.0)) * Cs;
-}
-
-vec4 Brightness(vec4 Cs, float amount) {
-    return vec4(Cs.rgb * amount, Cs.a);
-}
-
-vec4 Opacity(vec4 Cs, float amount) {
-    return Cs * amount;
-}
-
-void main(void) {
-    vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw);
-    vec4 Cs = textureLod(sCacheRGBA8, vec3(uv, vUv.z), 0.0);
-
-    if (Cs.a == 0.0) {
-        discard;
-    }
-
-    switch (vOp) {
-        case 0:
-            // Gaussian blur is specially handled:
-            oFragColor = Cs;// Blur(vAmount, vec2(0,0));
-            break;
-        case 1:
-            oFragColor = Contrast(Cs, vAmount);
-            break;
-        case 2:
-            oFragColor = Grayscale(Cs, vAmount);
-            break;
-        case 3:
-            oFragColor = HueRotate(Cs, vAmount);
-            break;
-        case 4:
-            oFragColor = Invert(Cs, vAmount);
-            break;
-        case 5:
-            oFragColor = Saturate(Cs, vAmount);
-            break;
-        case 6:
-            oFragColor = Sepia(Cs, vAmount);
-            break;
-        case 7:
-            oFragColor = Brightness(Cs, vAmount);
-            break;
-        case 8:
-            oFragColor = Opacity(Cs, vAmount);
-            break;
-    }
-}
--- a/gfx/webrender/res/ps_blend.glsl
+++ b/gfx/webrender/res/ps_blend.glsl
@@ -3,8 +3,179 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include shared,prim_shared
 
 varying vec3 vUv;
 flat varying vec4 vUvBounds;
 flat varying float vAmount;
 flat varying int vOp;
+
+#ifdef WR_VERTEX_SHADER
+void main(void) {
+    CompositeInstance ci = fetch_composite_instance();
+    AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
+    AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
+
+    vec2 dest_origin = dest_task.render_target_origin -
+                       dest_task.screen_space_origin +
+                       src_task.screen_space_origin;
+
+    vec2 local_pos = mix(dest_origin,
+                         dest_origin + src_task.size,
+                         aPosition.xy);
+
+    vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0));
+    vec2 st0 = src_task.render_target_origin;
+    vec2 st1 = src_task.render_target_origin + src_task.size;
+
+    vec2 uv = src_task.render_target_origin + aPosition.xy * src_task.size;
+    vUv = vec3(uv / texture_size, src_task.render_target_layer_index);
+    vUvBounds = vec4(st0 + 0.5, st1 - 0.5) / texture_size.xyxy;
+
+    vOp = ci.user_data0;
+    vAmount = float(ci.user_data1) / 65535.0;
+
+    gl_Position = uTransform * vec4(local_pos, ci.z, 1.0);
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+/* 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/. */
+
+vec3 rgbToHsv(vec3 c) {
+    float value = max(max(c.r, c.g), c.b);
+
+    float chroma = value - min(min(c.r, c.g), c.b);
+    if (chroma == 0.0) {
+        return vec3(0.0);
+    }
+    float saturation = chroma / value;
+
+    float hue;
+    if (c.r == value)
+        hue = (c.g - c.b) / chroma;
+    else if (c.g == value)
+        hue = 2.0 + (c.b - c.r) / chroma;
+    else // if (c.b == value)
+        hue = 4.0 + (c.r - c.g) / chroma;
+
+    hue *= 1.0/6.0;
+    if (hue < 0.0)
+        hue += 1.0;
+    return vec3(hue, saturation, value);
+}
+
+vec3 hsvToRgb(vec3 c) {
+    if (c.s == 0.0) {
+        return vec3(c.z);
+    }
+
+    float hue = c.x * 6.0;
+    int sector = int(hue);
+    float residualHue = hue - float(sector);
+
+    vec3 pqt = c.z * vec3(1.0 - c.y, 1.0 - c.y * residualHue, 1.0 - c.y * (1.0 - residualHue));
+    switch (sector) {
+        case 0:
+            return vec3(c.z, pqt.z, pqt.x);
+        case 1:
+            return vec3(pqt.y, c.z, pqt.x);
+        case 2:
+            return vec3(pqt.x, c.z, pqt.z);
+        case 3:
+            return vec3(pqt.x, pqt.y, c.z);
+        case 4:
+            return vec3(pqt.z, pqt.x, c.z);
+        default:
+            return vec3(c.z, pqt.x, pqt.y);
+    }
+}
+
+vec4 Blur(float radius, vec2 direction) {
+    // TODO(gw): Support blur in WR2!
+    return vec4(1.0);
+}
+
+vec4 Contrast(vec4 Cs, float amount) {
+    return vec4(Cs.rgb * amount - 0.5 * amount + 0.5, 1.0);
+}
+
+vec4 Grayscale(vec4 Cs, float amount) {
+    float ia = 1.0 - amount;
+    return mat4(vec4(0.2126 + 0.7874 * ia, 0.2126 - 0.2126 * ia, 0.2126 - 0.2126 * ia, 0.0),
+                vec4(0.7152 - 0.7152 * ia, 0.7152 + 0.2848 * ia, 0.7152 - 0.7152 * ia, 0.0),
+                vec4(0.0722 - 0.0722 * ia, 0.0722 - 0.0722 * ia, 0.0722 + 0.9278 * ia, 0.0),
+                vec4(0.0, 0.0, 0.0, 1.0)) * Cs;
+}
+
+vec4 HueRotate(vec4 Cs, float amount) {
+    vec3 CsHsv = rgbToHsv(Cs.rgb);
+    CsHsv.x = mod(CsHsv.x + amount / 6.283185307179586, 1.0);
+    return vec4(hsvToRgb(CsHsv), Cs.a);
+}
+
+vec4 Invert(vec4 Cs, float amount) {
+    return mix(Cs, vec4(1.0, 1.0, 1.0, Cs.a) - vec4(Cs.rgb, 0.0), amount);
+}
+
+vec4 Saturate(vec4 Cs, float amount) {
+    return vec4(hsvToRgb(min(vec3(1.0, amount, 1.0) * rgbToHsv(Cs.rgb), vec3(1.0))), Cs.a);
+}
+
+vec4 Sepia(vec4 Cs, float amount) {
+    float ia = 1.0 - amount;
+    return mat4(vec4(0.393 + 0.607 * ia, 0.349 - 0.349 * ia, 0.272 - 0.272 * ia, 0.0),
+                vec4(0.769 - 0.769 * ia, 0.686 + 0.314 * ia, 0.534 - 0.534 * ia, 0.0),
+                vec4(0.189 - 0.189 * ia, 0.168 - 0.168 * ia, 0.131 + 0.869 * ia, 0.0),
+                vec4(0.0, 0.0, 0.0, 1.0)) * Cs;
+}
+
+vec4 Brightness(vec4 Cs, float amount) {
+    return vec4(Cs.rgb * amount, Cs.a);
+}
+
+vec4 Opacity(vec4 Cs, float amount) {
+    return Cs * amount;
+}
+
+void main(void) {
+    vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw);
+    vec4 Cs = textureLod(sCacheRGBA8, vec3(uv, vUv.z), 0.0);
+
+    if (Cs.a == 0.0) {
+        discard;
+    }
+
+    switch (vOp) {
+        case 0:
+            // Gaussian blur is specially handled:
+            oFragColor = Cs;// Blur(vAmount, vec2(0,0));
+            break;
+        case 1:
+            oFragColor = Contrast(Cs, vAmount);
+            break;
+        case 2:
+            oFragColor = Grayscale(Cs, vAmount);
+            break;
+        case 3:
+            oFragColor = HueRotate(Cs, vAmount);
+            break;
+        case 4:
+            oFragColor = Invert(Cs, vAmount);
+            break;
+        case 5:
+            oFragColor = Saturate(Cs, vAmount);
+            break;
+        case 6:
+            oFragColor = Sepia(Cs, vAmount);
+            break;
+        case 7:
+            oFragColor = Brightness(Cs, vAmount);
+            break;
+        case 8:
+            oFragColor = Opacity(Cs, vAmount);
+            break;
+    }
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/ps_blend.vs.glsl
+++ /dev/null
@@ -1,30 +0,0 @@
-/* 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/. */
-
-void main(void) {
-    CompositeInstance ci = fetch_composite_instance();
-    AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
-    AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
-
-    vec2 dest_origin = dest_task.render_target_origin -
-                       dest_task.screen_space_origin +
-                       src_task.screen_space_origin;
-
-    vec2 local_pos = mix(dest_origin,
-                         dest_origin + src_task.size,
-                         aPosition.xy);
-
-    vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0));
-    vec2 st0 = src_task.render_target_origin;
-    vec2 st1 = src_task.render_target_origin + src_task.size;
-
-    vec2 uv = src_task.render_target_origin + aPosition.xy * src_task.size;
-    vUv = vec3(uv / texture_size, src_task.render_target_layer_index);
-    vUvBounds = vec4(st0 + 0.5, st1 - 0.5) / texture_size.xyxy;
-
-    vOp = ci.user_data0;
-    vAmount = float(ci.user_data1) / 65535.0;
-
-    gl_Position = uTransform * vec4(local_pos, ci.z, 1.0);
-}
--- a/gfx/webrender/res/ps_box_shadow.glsl
+++ b/gfx/webrender/res/ps_box_shadow.glsl
@@ -8,16 +8,21 @@ flat varying vec4 vColor;
 
 varying vec3 vUv;
 flat varying vec2 vMirrorPoint;
 flat varying vec4 vCacheUvRectCoords;
 
 #ifdef WR_VERTEX_SHADER
 #define BS_HEADER_VECS 4
 
+RectWithSize fetch_instance_geometry(int address) {
+    vec4 data = fetch_from_resource_cache_1(address);
+    return RectWithSize(data.xy, data.zw);
+}
+
 void main(void) {
     Primitive prim = load_primitive();
     BoxShadow bs = fetch_boxshadow(prim.specific_prim_address);
     RectWithSize segment_rect = fetch_instance_geometry(prim.specific_prim_address + BS_HEADER_VECS + prim.user_data0);
 
     VertexInfo vi = write_vertex(segment_rect,
                                  prim.local_clip_rect,
                                  prim.z,
deleted file mode 100644
--- a/gfx/webrender/res/ps_cache_image.fs.glsl
+++ /dev/null
@@ -1,8 +0,0 @@
-/* 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/. */
-
-void main(void) {
-    vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw);
-    oFragColor = texture(sColor0, vec3(uv, vUv.z));
-}
--- a/gfx/webrender/res/ps_cache_image.glsl
+++ b/gfx/webrender/res/ps_cache_image.glsl
@@ -1,8 +1,45 @@
 /* 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/. */
 
 #include shared,prim_shared
 
 varying vec3 vUv;
 flat varying vec4 vUvBounds;
+
+#ifdef WR_VERTEX_SHADER
+// Draw a cached primitive (e.g. a blurred text run) from the
+// target cache to the framebuffer, applying tile clip boundaries.
+
+void main(void) {
+    Primitive prim = load_primitive();
+
+    VertexInfo vi = write_vertex(prim.local_rect,
+                                 prim.local_clip_rect,
+                                 prim.z,
+                                 prim.layer,
+                                 prim.task,
+                                 prim.local_rect);
+
+    RenderTaskData child_task = fetch_render_task(prim.user_data1);
+    vUv.z = child_task.data1.x;
+
+    vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0));
+    vec2 uv0 = child_task.data0.xy;
+    vec2 uv1 = (child_task.data0.xy + child_task.data0.zw);
+
+    vec2 f = (vi.local_pos - prim.local_rect.p0) / prim.local_rect.size;
+
+    vUv.xy = mix(uv0 / texture_size,
+                 uv1 / texture_size,
+                 f);
+    vUvBounds = vec4(uv0 + vec2(0.5), uv1 - vec2(0.5)) / texture_size.xyxy;
+}
+#endif
+
+#ifdef WR_FRAGMENT_SHADER
+void main(void) {
+    vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw);
+    oFragColor = texture(sColor0, vec3(uv, vUv.z));
+}
+#endif
deleted file mode 100644
--- a/gfx/webrender/res/ps_cache_image.vs.glsl
+++ /dev/null
@@ -1,31 +0,0 @@
-/* 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/. */
-
-// Draw a cached primitive (e.g. a blurred text run) from the
-// target cache to the framebuffer, applying tile clip boundaries.
-
-void main(void) {
-    Primitive prim = load_primitive();
-
-    VertexInfo vi = write_vertex(prim.local_rect,
-                                 prim.local_clip_rect,
-                                 prim.z,
-                                 prim.layer,
-                                 prim.task,
-                                 prim.local_rect);
-
-    RenderTaskData child_task = fetch_render_task(prim.user_data1);
-    vUv.z = child_task.data1.x;
-
-    vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0));
-    vec2 uv0 = child_task.data0.xy;
-    vec2 uv1 = (child_task.data0.xy + child_task.data0.zw);
-
-    vec2 f = (vi.local_pos - prim.local_rect.p0) / prim.local_rect.size;
-
-    vUv.xy = mix(uv0 / texture_size,
-                 uv1 / texture_size,
-                 f);
-    vUvBounds = vec4(uv0 + vec2(0.5), uv1 - vec2(0.5)) / texture_size.xyxy;
-}
--- a/gfx/webrender/res/ps_composite.glsl
+++ b/gfx/webrender/res/ps_composite.glsl
@@ -4,16 +4,33 @@
 
 #include shared,prim_shared
 
 varying vec3 vUv0;
 varying vec3 vUv1;
 flat varying int vOp;
 
 #ifdef WR_VERTEX_SHADER
+struct ReadbackTask {
+    vec2 render_target_origin;
+    vec2 size;
+    float render_target_layer_index;
+};
+
+ReadbackTask fetch_readback_task(int index) {
+    RenderTaskData data = fetch_render_task(index);
+
+    ReadbackTask task;
+    task.render_target_origin = data.data0.xy;
+    task.size = data.data0.zw;
+    task.render_target_layer_index = data.data1.x;
+
+    return task;
+}
+
 void main(void) {
     CompositeInstance ci = fetch_composite_instance();
     AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
     ReadbackTask backdrop_task = fetch_readback_task(ci.backdrop_task_index);
     AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
 
     vec2 dest_origin = dest_task.render_target_origin -
                        dest_task.screen_space_origin +
--- a/gfx/webrender/res/ps_hardware_composite.fs.glsl
+++ b/gfx/webrender/res/ps_hardware_composite.fs.glsl
@@ -1,7 +1,8 @@
 /* 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/. */
 
 void main(void) {
-    oFragColor = texture(sCacheRGBA8, vUv);
+    vec2 uv = clamp(vUv.xy, vUvBounds.xy, vUvBounds.zw);
+    oFragColor = texture(sCacheRGBA8, vec3(uv, vUv.z));
 }
--- a/gfx/webrender/res/ps_hardware_composite.glsl
+++ b/gfx/webrender/res/ps_hardware_composite.glsl
@@ -1,7 +1,8 @@
 /* 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/. */
 
 #include shared,prim_shared
 
 varying vec3 vUv;
+flat varying vec4 vUvBounds;
--- a/gfx/webrender/res/ps_hardware_composite.vs.glsl
+++ b/gfx/webrender/res/ps_hardware_composite.vs.glsl
@@ -4,21 +4,22 @@
 
 void main(void) {
     CompositeInstance ci = fetch_composite_instance();
     AlphaBatchTask dest_task = fetch_alpha_batch_task(ci.render_task_index);
     AlphaBatchTask src_task = fetch_alpha_batch_task(ci.src_task_index);
 
     vec2 dest_origin = dest_task.render_target_origin -
                        dest_task.screen_space_origin +
-                       src_task.screen_space_origin;
+                       vec2(ci.user_data0, ci.user_data1);
 
     vec2 local_pos = mix(dest_origin,
                          dest_origin + src_task.size,
                          aPosition.xy);
 
     vec2 texture_size = vec2(textureSize(sCacheRGBA8, 0));
-    vec2 st0 = src_task.render_target_origin / texture_size;
-    vec2 st1 = (src_task.render_target_origin + src_task.size) / texture_size;
-    vUv = vec3(mix(st0, st1, aPosition.xy), src_task.render_target_layer_index);
+    vec2 st0 = src_task.render_target_origin;
+    vec2 st1 = src_task.render_target_origin + src_task.size;
+    vUv = vec3(mix(st0, st1, aPosition.xy) / texture_size, src_task.render_target_layer_index);
+    vUvBounds = vec4(st0 + 0.5, st1 - 0.5) / texture_size.xyxy;
 
     gl_Position = uTransform * vec4(local_pos, ci.z, 1.0);
 }
--- a/gfx/webrender/res/ps_line.glsl
+++ b/gfx/webrender/res/ps_line.glsl
@@ -15,16 +15,27 @@ varying vec3 vLocalPos;
 #else
 varying vec2 vLocalPos;
 #endif
 
 #ifdef WR_VERTEX_SHADER
 #define LINE_ORIENTATION_VERTICAL       0
 #define LINE_ORIENTATION_HORIZONTAL     1
 
+struct Line {
+    vec4 color;
+    float style;
+    float orientation;
+};
+
+Line fetch_line(int address) {
+    vec4 data[2] = fetch_from_resource_cache_2(address);
+    return Line(data[0], data[1].x, data[1].y);
+}
+
 void main(void) {
     Primitive prim = load_primitive();
     Line line = fetch_line(prim.specific_prim_address);
 
     vec2 pos, size;
 
     switch (int(line.orientation)) {
         case LINE_ORIENTATION_HORIZONTAL:
--- a/gfx/webrender/res/ps_yuv_image.glsl
+++ b/gfx/webrender/res/ps_yuv_image.glsl
@@ -19,16 +19,25 @@ flat varying vec3 vLayers;
 
 #ifdef WR_FEATURE_TRANSFORM
 varying vec3 vLocalPos;
 #else
 varying vec2 vLocalPos;
 #endif
 
 #ifdef WR_VERTEX_SHADER
+struct YuvImage {
+    vec2 size;
+};
+
+YuvImage fetch_yuv_image(int address) {
+    vec4 data = fetch_from_resource_cache_1(address);
+    return YuvImage(data.xy);
+}
+
 void main(void) {
     Primitive prim = load_primitive();
 #ifdef WR_FEATURE_TRANSFORM
     TransformVertexInfo vi = write_transform_vertex(prim.local_rect,
                                                     prim.local_clip_rect,
                                                     prim.z,
                                                     prim.layer,
                                                     prim.task,
new file mode 100644
--- /dev/null
+++ b/gfx/webrender/res/rect.glsl
@@ -0,0 +1,29 @@
+/* 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/. */
+
+struct RectWithSize {
+    vec2 p0;
+    vec2 size;
+};
+
+struct RectWithEndpoint {
+    vec2 p0;
+    vec2 p1;
+};
+
+RectWithEndpoint to_rect_with_endpoint(RectWithSize rect) {
+    RectWithEndpoint result;
+    result.p0 = rect.p0;
+    result.p1 = rect.p0 + rect.size;
+
+    return result;
+}
+
+RectWithSize to_rect_with_size(RectWithEndpoint rect) {
+    RectWithSize result;
+    result.p0 = rect.p0;
+    result.size = rect.p1 - rect.p0;
+
+    return result;
+}
--- a/gfx/webrender/src/border.rs
+++ b/gfx/webrender/src/border.rs
@@ -1,27 +1,27 @@
 /* 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 api::{BorderSide, BorderStyle, BorderWidths, ClipAndScrollInfo, ColorF, LayerPoint, LayerRect};
 use api::{LayerPrimitiveInfo, LayerSize, NormalBorder};
 use clip::ClipSource;
 use ellipse::Ellipse;
+use frame_builder::FrameBuilder;
 use gpu_cache::GpuDataRequest;
-use frame_builder::FrameBuilder;
 use prim_store::{BorderPrimitiveCpu, PrimitiveContainer};
 use tiling::PrimitiveFlags;
 use util::{lerp, pack_as_float};
 
 #[repr(u8)]
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub enum BorderCornerInstance {
-    Single,     // Single instance needed - corner styles are same or similar.
-    Double,     // Different corner styles. Draw two instances, one per style.
+    Single, // Single instance needed - corner styles are same or similar.
+    Double, // Different corner styles. Draw two instances, one per style.
 }
 
 #[repr(C)]
 pub enum BorderCornerSide {
     Both,
     First,
     Second,
 }
@@ -34,99 +34,105 @@ enum BorderCorner {
     BottomRight,
 }
 
 #[derive(Clone, Debug, PartialEq)]
 pub enum BorderCornerKind {
     None,
     Solid,
     Clip(BorderCornerInstance),
-    Mask(BorderCornerClipData, LayerSize, LayerSize, BorderCornerClipKind),
+    Mask(
+        BorderCornerClipData,
+        LayerSize,
+        LayerSize,
+        BorderCornerClipKind,
+    ),
 }
 
 impl BorderCornerKind {
-    fn new_mask(kind: BorderCornerClipKind,
-                width0: f32,
-                width1: f32,
-                corner: BorderCorner,
-                radius: LayerSize,
-                border_rect: LayerRect) -> BorderCornerKind {
+    fn new_mask(
+        kind: BorderCornerClipKind,
+        width0: f32,
+        width1: f32,
+        corner: BorderCorner,
+        radius: LayerSize,
+        border_rect: LayerRect,
+    ) -> BorderCornerKind {
         let size = LayerSize::new(width0.max(radius.width), width1.max(radius.height));
         let (origin, clip_center) = match corner {
             BorderCorner::TopLeft => {
                 let origin = border_rect.origin;
                 let clip_center = origin + size;
                 (origin, clip_center)
             }
             BorderCorner::TopRight => {
-                let origin = LayerPoint::new(border_rect.origin.x +
-                                             border_rect.size.width -
-                                             size.width,
-                                             border_rect.origin.y);
+                let origin = LayerPoint::new(
+                    border_rect.origin.x + border_rect.size.width - size.width,
+                    border_rect.origin.y,
+                );
                 let clip_center = origin + LayerSize::new(0.0, size.height);
                 (origin, clip_center)
             }
             BorderCorner::BottomRight => {
                 let origin = border_rect.origin + (border_rect.size - size);
                 let clip_center = origin;
                 (origin, clip_center)
             }
             BorderCorner::BottomLeft => {
-                let origin = LayerPoint::new(border_rect.origin.x,
-                                             border_rect.origin.y +
-                                             border_rect.size.height -
-                                             size.height);
+                let origin = LayerPoint::new(
+                    border_rect.origin.x,
+                    border_rect.origin.y + border_rect.size.height - size.height,
+                );
                 let clip_center = origin + LayerSize::new(size.width, 0.0);
                 (origin, clip_center)
             }
         };
         let clip_data = BorderCornerClipData {
             corner_rect: LayerRect::new(origin, size),
             clip_center,
             corner: pack_as_float(corner as u32),
             kind: pack_as_float(kind as u32),
         };
-        BorderCornerKind::Mask(clip_data,
-                               radius,
-                               LayerSize::new(width0, width1),
-                               kind)
+        BorderCornerKind::Mask(clip_data, radius, LayerSize::new(width0, width1), kind)
     }
 }
 
 #[derive(Copy, Clone, Debug, PartialEq)]
 pub enum BorderEdgeKind {
     None,
     Solid,
     Clip,
 }
 
 trait NormalBorderHelpers {
-    fn get_corner(&self,
-                  edge0: &BorderSide,
-                  width0: f32,
-                  edge1: &BorderSide,
-                  width1: f32,
-                  radius: &LayerSize,
-                  corner: BorderCorner,
-                  border_rect: &LayerRect) -> BorderCornerKind;
+    fn get_corner(
+        &self,
+        edge0: &BorderSide,
+        width0: f32,
+        edge1: &BorderSide,
+        width1: f32,
+        radius: &LayerSize,
+        corner: BorderCorner,
+        border_rect: &LayerRect,
+    ) -> BorderCornerKind;
 
-    fn get_edge(&self,
-                edge: &BorderSide,
-                width: f32) -> (BorderEdgeKind, f32);
+    fn get_edge(&self, edge: &BorderSide, width: f32) -> (BorderEdgeKind, f32);
 }
 
 impl NormalBorderHelpers for NormalBorder {
-    fn get_corner(&self,
-                  edge0: &BorderSide,
-                  width0: f32,
-                  edge1: &BorderSide,
-                  width1: f32,
-                  radius: &LayerSize,
-                  corner: BorderCorner,
-                  border_rect: &LayerRect) -> BorderCornerKind {
+    fn get_corner(
+        &self,
+        edge0: &BorderSide,
+        width0: f32,
+        edge1: &BorderSide,
+        width1: f32,
+        radius: &LayerSize,
+        corner: BorderCorner,
+        border_rect: &LayerRect,
+    ) -> BorderCornerKind {
         // If either width is zero, a corner isn't formed.
         if width0 == 0.0 || width1 == 0.0 {
             return BorderCornerKind::None;
         }
 
         // If both edges are transparent, no corner is formed.
         if edge0.color.a == 0.0 && edge1.color.a == 0.0 {
             return BorderCornerKind::None;
@@ -153,200 +159,207 @@ impl NormalBorderHelpers for NormalBorde
             (BorderStyle::Inset, BorderStyle::Inset) |
             (BorderStyle::Double, BorderStyle::Double) |
             (BorderStyle::Groove, BorderStyle::Groove) |
             (BorderStyle::Ridge, BorderStyle::Ridge) => {
                 BorderCornerKind::Clip(BorderCornerInstance::Single)
             }
 
             // Dashed and dotted border corners get drawn into a clip mask.
-            (BorderStyle::Dashed, BorderStyle::Dashed) => {
-                BorderCornerKind::new_mask(BorderCornerClipKind::Dash,
-                                           width0,
-                                           width1,
-                                           corner,
-                                           *radius,
-                                           *border_rect)
-            }
-            (BorderStyle::Dotted, BorderStyle::Dotted) => {
-                BorderCornerKind::new_mask(BorderCornerClipKind::Dot,
-                                           width0,
-                                           width1,
-                                           corner,
-                                           *radius,
-                                           *border_rect)
-            }
+            (BorderStyle::Dashed, BorderStyle::Dashed) => BorderCornerKind::new_mask(
+                BorderCornerClipKind::Dash,
+                width0,
+                width1,
+                corner,
+                *radius,
+                *border_rect,
+            ),
+            (BorderStyle::Dotted, BorderStyle::Dotted) => BorderCornerKind::new_mask(
+                BorderCornerClipKind::Dot,
+                width0,
+                width1,
+                corner,
+                *radius,
+                *border_rect,
+            ),
 
             // Draw border transitions with dots and/or dashes as
             // solid segments. The old border path didn't support
             // this anyway, so we might as well start using the new
             // border path here, since the dashing in the edges is
             // much higher quality anyway.
             (BorderStyle::Dotted, _) |
             (_, BorderStyle::Dotted) |
             (BorderStyle::Dashed, _) |
-            (_, BorderStyle::Dashed) => {
-                BorderCornerKind::Clip(BorderCornerInstance::Single)
-            }
+            (_, BorderStyle::Dashed) => BorderCornerKind::Clip(BorderCornerInstance::Single),
 
             // Everything else can be handled by drawing the corner twice,
             // where the shader outputs zero alpha for the side it's not
             // drawing. This is somewhat inefficient in terms of pixels
             // written, but it's a fairly rare case, and we can optimize
             // this case later.
             _ => BorderCornerKind::Clip(BorderCornerInstance::Double),
         }
     }
 
-    fn get_edge(&self,
-                edge: &BorderSide,
-                width: f32) -> (BorderEdgeKind, f32) {
+    fn get_edge(&self, edge: &BorderSide, width: f32) -> (BorderEdgeKind, f32) {
         if width == 0.0 {
             return (BorderEdgeKind::None, 0.0);
         }
 
         match edge.style {
-            BorderStyle::None |
-            BorderStyle::Hidden => (BorderEdgeKind::None, 0.0),
+            BorderStyle::None | BorderStyle::Hidden => (BorderEdgeKind::None, 0.0),
 
-            BorderStyle::Solid |
-            BorderStyle::Inset |
-            BorderStyle::Outset => (BorderEdgeKind::Solid, width),
+            BorderStyle::Solid | BorderStyle::Inset | BorderStyle::Outset => {
+                (BorderEdgeKind::Solid, width)
+            }
 
             BorderStyle::Double |
             BorderStyle::Groove |
             BorderStyle::Ridge |
             BorderStyle::Dashed |
             BorderStyle::Dotted => (BorderEdgeKind::Clip, width),
         }
     }
 }
 
 impl FrameBuilder {
-    fn add_normal_border_primitive(&mut self,
-                                   info: &LayerPrimitiveInfo,
-                                   border: &NormalBorder,
-                                   widths: &BorderWidths,
-                                   clip_and_scroll: ClipAndScrollInfo,
-                                   corner_instances: [BorderCornerInstance; 4],
-                                   clip_sources: Vec<ClipSource>) {
+    fn add_normal_border_primitive(
+        &mut self,
+        info: &LayerPrimitiveInfo,
+        border: &NormalBorder,
+        widths: &BorderWidths,
+        clip_and_scroll: ClipAndScrollInfo,
+        corner_instances: [BorderCornerInstance; 4],
+        clip_sources: Vec<ClipSource>,
+    ) {
         let radius = &border.radius;
         let left = &border.left;
         let right = &border.right;
         let top = &border.top;
         let bottom = &border.bottom;
 
         // These colors are used during inset/outset scaling.
-        let left_color      = left.border_color(1.0, 2.0/3.0, 0.3, 0.7);
-        let top_color       = top.border_color(1.0, 2.0/3.0, 0.3, 0.7);
-        let right_color     = right.border_color(2.0/3.0, 1.0, 0.7, 0.3);
-        let bottom_color    = bottom.border_color(2.0/3.0, 1.0, 0.7, 0.3);
+        let left_color = left.border_color(1.0, 2.0 / 3.0, 0.3, 0.7);
+        let top_color = top.border_color(1.0, 2.0 / 3.0, 0.3, 0.7);
+        let right_color = right.border_color(2.0 / 3.0, 1.0, 0.7, 0.3);
+        let bottom_color = bottom.border_color(2.0 / 3.0, 1.0, 0.7, 0.3);
 
         let prim_cpu = BorderPrimitiveCpu {
             corner_instances,
 
             // TODO(gw): In the future, we will build these on demand
             //           from the deserialized display list, rather
             //           than creating it immediately.
             gpu_blocks: [
-                [ pack_as_float(left.style as u32),
-                  pack_as_float(top.style as u32),
-                  pack_as_float(right.style as u32),
-                  pack_as_float(bottom.style as u32) ].into(),
-                [ widths.left,
-                  widths.top,
-                  widths.right,
-                  widths.bottom ].into(),
+                [
+                    pack_as_float(left.style as u32),
+                    pack_as_float(top.style as u32),
+                    pack_as_float(right.style as u32),
+                    pack_as_float(bottom.style as u32),
+                ].into(),
+                [widths.left, widths.top, widths.right, widths.bottom].into(),
                 left_color.into(),
                 top_color.into(),
                 right_color.into(),
                 bottom_color.into(),
-                [ radius.top_left.width,
-                  radius.top_left.height,
-                  radius.top_right.width,
-                  radius.top_right.height ].into(),
-                [ radius.bottom_right.width,
-                  radius.bottom_right.height,
-                  radius.bottom_left.width,
-                  radius.bottom_left.height ].into(),
+                [
+                    radius.top_left.width,
+                    radius.top_left.height,
+                    radius.top_right.width,
+                    radius.top_right.height,
+                ].into(),
+                [
+                    radius.bottom_right.width,
+                    radius.bottom_right.height,
+                    radius.bottom_left.width,
+                    radius.bottom_left.height,
+                ].into(),
             ],
         };
 
-        self.add_primitive(clip_and_scroll,
-                           info,
-                           clip_sources,
-                           PrimitiveContainer::Border(prim_cpu));
+        self.add_primitive(
+            clip_and_scroll,
+            info,
+            clip_sources,
+            PrimitiveContainer::Border(prim_cpu),
+        );
     }
 
     // TODO(gw): This allows us to move border types over to the
     // simplified shader model one at a time. Once all borders
     // are converted, this can be removed, along with the complex
     // border code path.
-    pub fn add_normal_border(&mut self,
-                             info: &LayerPrimitiveInfo,
-                             border: &NormalBorder,
-                             widths: &BorderWidths,
-                             clip_and_scroll: ClipAndScrollInfo) {
+    pub fn add_normal_border(
+        &mut self,
+        info: &LayerPrimitiveInfo,
+        border: &NormalBorder,
+        widths: &BorderWidths,
+        clip_and_scroll: ClipAndScrollInfo,
+    ) {
         // The border shader is quite expensive. For simple borders, we can just draw
         // the border with a few rectangles. This generally gives better batching, and
         // a GPU win in fragment shader time.
         // More importantly, the software (OSMesa) implementation we run tests on is
         // particularly slow at running our complex border shader, compared to the
         // rectangle shader. This has the effect of making some of our tests time
         // out more often on CI (the actual cause is simply too many Servo processes and
         // threads being run on CI at once).
 
         let radius = &border.radius;
         let left = &border.left;
         let right = &border.right;
         let top = &border.top;
         let bottom = &border.bottom;
 
         let corners = [
-            border.get_corner(left,
-                              widths.left,
-                              top,
-                              widths.top,
-                              &radius.top_left,
-                              BorderCorner::TopLeft,
-                              &info.rect),
-            border.get_corner(right,
-                              widths.right,
-                              top,
-                              widths.top,
-                              &radius.top_right,
-                              BorderCorner::TopRight,
-                              &info.rect),
-            border.get_corner(right,
-                              widths.right,
-                              bottom,
-                              widths.bottom,
-                              &radius.bottom_right,
-                              BorderCorner::BottomRight,
-                              &info.rect),
-            border.get_corner(left,
-                              widths.left,
-                              bottom,
-                              widths.bottom,
-                              &radius.bottom_left,
-                              BorderCorner::BottomLeft,
-                              &info.rect),
+            border.get_corner(
+                left,
+                widths.left,
+                top,
+                widths.top,
+                &radius.top_left,
+                BorderCorner::TopLeft,
+                &info.rect,
+            ),
+            border.get_corner(
+                right,
+                widths.right,
+                top,
+                widths.top,
+                &radius.top_right,
+                BorderCorner::TopRight,
+                &info.rect,
+            ),
+            border.get_corner(
+                right,
+                widths.right,
+                bottom,
+                widths.bottom,
+                &radius.bottom_right,
+                BorderCorner::BottomRight,
+                &info.rect,
+            ),
+            border.get_corner(
+                left,
+                widths.left,
+                bottom,
+                widths.bottom,
+                &radius.bottom_left,
+                BorderCorner::BottomLeft,
+                &info.rect,
+            ),
         ];
 
         let (left_edge, left_len) = border.get_edge(left, widths.left);
         let (top_edge, top_len) = border.get_edge(top, widths.top);
         let (right_edge, right_len) = border.get_edge(right, widths.right);
         let (bottom_edge, bottom_len) = border.get_edge(bottom, widths.bottom);
 
-        let edges = [
-            left_edge,
-            top_edge,
-            right_edge,
-            bottom_edge,
-        ];
+        let edges = [left_edge, top_edge, right_edge, bottom_edge];
 
         // Use a simple rectangle case when all edges and corners are either
         // solid or none.
         let all_corners_simple = corners.iter().all(|c| {
             *c == BorderCornerKind::Solid || *c == BorderCornerKind::None
         });
         let all_edges_simple = edges.iter().all(|e| {
             *e == BorderEdgeKind::Solid || *e == BorderEdgeKind::None
@@ -359,96 +372,111 @@ impl FrameBuilder {
             let p1 = info.rect.bottom_right();
             let rect_width = info.rect.size.width;
             let rect_height = info.rect.size.height;
 
             // Add a solid rectangle for each visible edge/corner combination.
             if top_edge == BorderEdgeKind::Solid {
                 let mut info = info.clone();
                 info.rect = LayerRect::new(p0, LayerSize::new(rect_width, top_len));
-                self.add_solid_rectangle(clip_and_scroll,
-                                         &info,
-                                         &border.top.color,
-                                         PrimitiveFlags::None);
+                self.add_solid_rectangle(
+                    clip_and_scroll,
+                    &info,
+                    &border.top.color,
+                    PrimitiveFlags::None,
+                );
             }
             if left_edge == BorderEdgeKind::Solid {
                 let mut info = info.clone();
-                info.rect = LayerRect::new(LayerPoint::new(p0.x, p0.y + top_len),
-                                           LayerSize::new(left_len,
-                                                          rect_height - top_len - bottom_len));
-                self.add_solid_rectangle(clip_and_scroll,
-                                         &info,
-                                         &border.left.color,
-                                         PrimitiveFlags::None);
+                info.rect = LayerRect::new(
+                    LayerPoint::new(p0.x, p0.y + top_len),
+                    LayerSize::new(left_len, rect_height - top_len - bottom_len),
+                );
+                self.add_solid_rectangle(
+                    clip_and_scroll,
+                    &info,
+                    &border.left.color,
+                    PrimitiveFlags::None,
+                );
             }
             if right_edge == BorderEdgeKind::Solid {
                 let mut info = info.clone();
-                info.rect = LayerRect::new(LayerPoint::new(p1.x - right_len,
-                                                           p0.y + top_len),
-                                           LayerSize::new(right_len,
-                                                          rect_height - top_len - bottom_len));
-                self.add_solid_rectangle(clip_and_scroll,
-                                         &info,
-                                         &border.right.color,
-                                         PrimitiveFlags::None);
+                info.rect = LayerRect::new(
+                    LayerPoint::new(p1.x - right_len, p0.y + top_len),
+                    LayerSize::new(right_len, rect_height - top_len - bottom_len),
+                );
+                self.add_solid_rectangle(
+                    clip_and_scroll,
+                    &info,
+                    &border.right.color,
+                    PrimitiveFlags::None,
+                );
             }
             if bottom_edge == BorderEdgeKind::Solid {
                 let mut info = info.clone();
-                info.rect = LayerRect::new(LayerPoint::new(p0.x, p1.y - bottom_len),
-                                           LayerSize::new(rect_width, bottom_len));
-                self.add_solid_rectangle(clip_and_scroll,
-                                         &info,
-                                         &border.bottom.color,
-                                         PrimitiveFlags::None);
+                info.rect = LayerRect::new(
+                    LayerPoint::new(p0.x, p1.y - bottom_len),
+                    LayerSize::new(rect_width, bottom_len),
+                );
+                self.add_solid_rectangle(
+                    clip_and_scroll,
+                    &info,
+                    &border.bottom.color,
+                    PrimitiveFlags::None,
+                );
             }
         } else {
             // Create clip masks for border corners, if required.
             let mut extra_clips = Vec::new();
             let mut corner_instances = [BorderCornerInstance::Single; 4];
 
             for (i, corner) in corners.iter().enumerate() {
                 match corner {
                     &BorderCornerKind::Mask(corner_data, corner_radius, widths, kind) => {
-                        let clip_source = BorderCornerClipSource::new(corner_data,
-                                                                      corner_radius,
-                                                                      widths,
-                                                                      kind);
+                        let clip_source =
+                            BorderCornerClipSource::new(corner_data, corner_radius, widths, kind);
                         extra_clips.push(ClipSource::BorderCorner(clip_source));
                     }
                     &BorderCornerKind::Clip(instance_kind) => {
                         corner_instances[i] = instance_kind;
                     }
                     _ => {}
                 }
             }
 
-            self.add_normal_border_primitive(info,
-                                             border,
-                                             widths,
-                                             clip_and_scroll,
-                                             corner_instances,
-                                             extra_clips);
+            self.add_normal_border_primitive(
+                info,
+                border,
+                widths,
+                clip_and_scroll,
+                corner_instances,
+                extra_clips,
+            );
         }
     }
 }
 
 pub trait BorderSideHelpers {
-    fn border_color(&self,
-                    scale_factor_0: f32,
-                    scale_factor_1: f32,
-                    black_color_0: f32,
-                    black_color_1: f32) -> ColorF;
+    fn border_color(
+        &self,
+        scale_factor_0: f32,
+        scale_factor_1: f32,
+        black_color_0: f32,
+        black_color_1: f32,
+    ) -> ColorF;
 }
 
 impl BorderSideHelpers for BorderSide {
-    fn border_color(&self,
-                    scale_factor_0: f32,
-                    scale_factor_1: f32,
-                    black_color_0: f32,
-                    black_color_1: f32) -> ColorF {
+    fn border_color(
+        &self,
+        scale_factor_0: f32,
+        scale_factor_1: f32,
+        black_color_0: f32,
+        black_color_1: f32,
+    ) -> ColorF {
         match self.style {
             BorderStyle::Inset => {
                 if self.color.r != 0.0 || self.color.g != 0.0 || self.color.b != 0.0 {
                     self.color.scale_rgb(scale_factor_1)
                 } else {
                     ColorF::new(black_color_0, black_color_0, black_color_0, self.color.a)
                 }
             }
@@ -479,20 +507,22 @@ pub struct BorderCornerClipSource {
     pub max_clip_count: usize,
     pub actual_clip_count: usize,
     kind: BorderCornerClipKind,
     widths: LayerSize,
     ellipse: Ellipse,
 }
 
 impl BorderCornerClipSource {
-    pub fn new(corner_data: BorderCornerClipData,
-               corner_radius: LayerSize,
-               widths: LayerSize,
-               kind: BorderCornerClipKind) -> BorderCornerClipSource {
+    pub fn new(
+        corner_data: BorderCornerClipData,
+        corner_radius: LayerSize,
+        widths: LayerSize,
+        kind: BorderCornerClipKind,
+    ) -> BorderCornerClipSource {
         // Work out a dash length (and therefore dash count)
         // based on the width of the border edges. The "correct"
         // dash length is not mentioned in the CSS borders
         // spec. The calculation below is similar, but not exactly
         // the same as what Gecko uses.
         // TODO(gw): Iterate on this to get it closer to what Gecko
         //           uses for dash length.
 
@@ -547,56 +577,60 @@ impl BorderCornerClipSource {
 
     pub fn write(&mut self, mut request: GpuDataRequest) {
         self.corner_data.write(&mut request);
 
         match self.kind {
             BorderCornerClipKind::Dash => {
                 // Get the correct dash arc length.
                 self.actual_clip_count = self.max_clip_count;
-                let dash_arc_length = 0.5 * self.ellipse.total_arc_length / (self.actual_clip_count - 1) as f32;
+                let dash_arc_length =
+                    0.5 * self.ellipse.total_arc_length / (self.actual_clip_count - 1) as f32;
                 let mut current_arc_length = -0.5 * dash_arc_length;
-                for _ in 0..self.actual_clip_count {
+                for _ in 0 .. self.actual_clip_count {
                     let arc_length0 = current_arc_length;
                     current_arc_length += dash_arc_length;
 
                     let arc_length1 = current_arc_length;
                     current_arc_length += dash_arc_length;
 
-                    let dash_data = BorderCornerDashClipData::new(arc_length0,
-                                                                  arc_length1,
-                                                                  &self.ellipse);
+                    let dash_data =
+                        BorderCornerDashClipData::new(arc_length0, arc_length1, &self.ellipse);
                     dash_data.write(&mut request);
                 }
 
                 assert_eq!(request.close(), 2 + 2 * self.actual_clip_count);
             }
             BorderCornerClipKind::Dot => {
                 let mut forward_dots = Vec::new();
                 let mut back_dots = Vec::new();
                 let mut leftover_arc_length = 0.0;
 
                 // Alternate between adding dots at the start and end of the
                 // ellipse arc. This ensures that we always end up with an exact
                 // half dot at each end of the arc, to match up with the edges.
                 forward_dots.push(DotInfo::new(0.0, self.widths.width));
-                back_dots.push(DotInfo::new(self.ellipse.total_arc_length, self.widths.height));
+                back_dots.push(DotInfo::new(
+                    self.ellipse.total_arc_length,
+                    self.widths.height,
+                ));
 
-                for dot_index in 0..self.max_clip_count {
+                for dot_index in 0 .. self.max_clip_count {
                     let prev_forward_pos = *forward_dots.last().unwrap();
                     let prev_back_pos = *back_dots.last().unwrap();
 
                     // Select which end of the arc to place a dot from.
                     // This just alternates between the start and end of
                     // the arc, which ensures that there is always an
                     // exact half-dot at each end of the ellipse.
                     let going_forward = dot_index & 1 == 0;
 
                     let (next_dot_pos, leftover) = if going_forward {
-                        let next_dot_pos = prev_forward_pos.arc_pos + 2.0 * prev_forward_pos.diameter;
+                        let next_dot_pos =
+                            prev_forward_pos.arc_pos + 2.0 * prev_forward_pos.diameter;
                         (next_dot_pos, prev_back_pos.arc_pos - next_dot_pos)
                     } else {
                         let next_dot_pos = prev_back_pos.arc_pos - 2.0 * prev_back_pos.diameter;
                         (next_dot_pos, next_dot_pos - prev_forward_pos.arc_pos)
                     };
 
                     // Use a lerp between each edge's dot
                     // diameter, based on the linear distance
@@ -624,27 +658,31 @@ impl BorderCornerClipSource {
                 // leftover space on the arc between them evenly. Once
                 // the final arc position is determined, generate the correct
                 // arc positions and angles that get passed to the clip shader.
                 self.actual_clip_count = forward_dots.len() + back_dots.len();
                 let extra_space_per_dot = leftover_arc_length / (self.actual_clip_count - 1) as f32;
 
                 for (i, dot) in forward_dots.iter().enumerate() {
                     let extra_dist = i as f32 * extra_space_per_dot;
-                    let dot = BorderCornerDotClipData::new(dot.arc_pos + extra_dist,
-                                                           0.5 * dot.diameter,
-                                                           &self.ellipse);
+                    let dot = BorderCornerDotClipData::new(
+                        dot.arc_pos + extra_dist,
+                        0.5 * dot.diameter,
+                        &self.ellipse,
+                    );
                     dot.write(&mut request);
                 }
 
                 for (i, dot) in back_dots.iter().enumerate() {
                     let extra_dist = i as f32 * extra_space_per_dot;
-                    let dot = BorderCornerDotClipData::new(dot.arc_pos - extra_dist,
-                                                           0.5 * dot.diameter,
-                                                           &self.ellipse);
+                    let dot = BorderCornerDotClipData::new(
+                        dot.arc_pos - extra_dist,
+                        0.5 * dot.diameter,
+                        &self.ellipse,
+                    );
                     dot.write(&mut request);
                 }
 
                 assert_eq!(request.close(), 2 + self.actual_clip_count);
             }
         }
     }
 }
@@ -657,24 +695,29 @@ pub struct BorderCornerClipData {
     /// Local space rect of the border corner.
     corner_rect: LayerRect,
     /// Local space point that is the center of the
     /// circle or ellipse that we are clipping against.
     clip_center: LayerPoint,
     /// The shader needs to know which corner, to
     /// be able to flip the dash tangents to the
     /// right orientation.
-    corner: f32,        // Of type BorderCorner enum
-    kind: f32,          // Of type BorderCornerClipKind enum
+    corner: f32, // Of type BorderCorner enum
+    kind: f32, // Of type BorderCornerClipKind enum
 }
 
 impl BorderCornerClipData {
     fn write(&self, request: &mut GpuDataRequest) {
         request.push(self.corner_rect);
-        request.push([self.clip_center.x, self.clip_center.y, self.corner, self.kind]);
+        request.push([
+            self.clip_center.x,
+            self.clip_center.y,
+            self.corner,
+            self.kind,
+        ]);
     }
 }
 
 /// Represents the GPU data for drawing a single dash
 /// to a clip mask. A dash clip is defined by two lines.
 /// We store a point on the ellipse curve, and a tangent
 /// to that point, which allows for efficient line-distance
 /// calculations in the fragment shader.
@@ -683,74 +726,72 @@ impl BorderCornerClipData {
 pub struct BorderCornerDashClipData {
     pub point0: LayerPoint,
     pub tangent0: LayerPoint,
     pub point1: LayerPoint,
     pub tangent1: LayerPoint,
 }
 
 impl BorderCornerDashClipData {
-    pub fn new(arc_length0: f32,
-               arc_length1: f32,
-               ellipse: &Ellipse) -> BorderCornerDashClipData {
+    pub fn new(arc_length0: f32, arc_length1: f32, ellipse: &Ellipse) -> BorderCornerDashClipData {
         let alpha = ellipse.find_angle_for_arc_length(arc_length0);
         let beta = ellipse.find_angle_for_arc_length(arc_length1);
 
         let (p0, t0) = ellipse.get_point_and_tangent(alpha);
         let (p1, t1) = ellipse.get_point_and_tangent(beta);
 
         BorderCornerDashClipData {
             point0: p0,
             tangent0: t0,
             point1: p1,
             tangent1: t1,
         }
     }
 
     fn write(&self, request: &mut GpuDataRequest) {
-        request.push([self.point0.x, self.point0.y,
-                      self.tangent0.x, self.tangent0.y]);
-        request.push([self.point1.x, self.point1.y,
-                      self.tangent1.x, self.tangent1.y]);
+        request.push([
+            self.point0.x,
+            self.point0.y,
+            self.tangent0.x,
+            self.tangent0.y,
+        ]);
+        request.push([
+            self.point1.x,
+            self.point1.y,
+            self.tangent1.x,
+            self.tangent1.y,
+        ]);
     }
 }
 
 /// Represents the GPU data for drawing a single dot
 /// to a clip mask.
 #[derive(Debug, Clone)]
 #[repr(C)]
 pub struct BorderCornerDotClipData {
     pub center: LayerPoint,
     pub radius: f32,
 }
 
 impl BorderCornerDotClipData {
-    pub fn new(arc_length: f32,
-               radius: f32,
-               ellipse: &Ellipse) -> BorderCornerDotClipData {
+    pub fn new(arc_length: f32, radius: f32, ellipse: &Ellipse) -> BorderCornerDotClipData {
         let theta = ellipse.find_angle_for_arc_length(arc_length);
         let (center, _) = ellipse.get_point_and_tangent(theta);
 
-        BorderCornerDotClipData {
-            center,
-            radius,
-        }
+        BorderCornerDotClipData { center, radius }
     }
 
     fn write(&self, request: &mut GpuDataRequest) {
         request.push([self.center.x, self.center.y, self.radius, 0.0]);
     }
 }
 
 #[derive(Copy, Clone, Debug)]
 struct DotInfo {
     arc_pos: f32,
     diameter: f32,
 }
 
 impl DotInfo {
     fn new(arc_pos: f32, diameter: f32) -> DotInfo {
-        DotInfo {
-            arc_pos,
-            diameter,
-        }
+        DotInfo { arc_pos, diameter }
     }
 }
--- a/gfx/webrender/src/clip.rs
+++ b/gfx/webrender/src/clip.rs
@@ -22,20 +22,21 @@ pub type ClipSourcesWeakHandle = WeakFre
 pub struct ClipRegion {
     pub origin: LayerPoint,
     pub main: LayerRect,
     pub image_mask: Option<ImageMask>,
     pub complex_clips: Vec<ComplexClipRegion>,
 }
 
 impl ClipRegion {
-    pub fn create_for_clip_node(rect: LayerRect,
-                                mut complex_clips: Vec<ComplexClipRegion>,
-                                mut image_mask: Option<ImageMask>)
-                                -> ClipRegion {
+    pub fn create_for_clip_node(
+        rect: LayerRect,
+        mut complex_clips: Vec<ComplexClipRegion>,
+        mut image_mask: Option<ImageMask>,
+    ) -> ClipRegion {
         // All the coordinates we receive are relative to the stacking context, but we want
         // to convert them to something relative to the origin of the clip.
         let negative_origin = -rect.origin.to_vector();
         if let Some(ref mut image_mask) = image_mask {
             image_mask.rect = image_mask.rect.translate(&negative_origin);
         }
 
         for complex_clip in complex_clips.iter_mut() {
@@ -57,27 +58,27 @@ impl ClipRegion {
         };
         ClipRegion::create_for_clip_node(*local_clip.clip_rect(), complex_clips, None)
     }
 }
 
 #[repr(C)]
 #[derive(Copy, Clone, Debug, PartialEq)]
 pub enum ClipMode {
-    Clip,           // Pixels inside the region are visible.
-    ClipOut,        // Pixels outside the region are visible.
+    Clip,    // Pixels inside the region are visible.
+    ClipOut, // Pixels outside the region are visible.
 }
 
 impl Not for ClipMode {
     type Output = ClipMode;
 
     fn not(self) -> ClipMode {
         match self {
             ClipMode::Clip => ClipMode::ClipOut,
-            ClipMode::ClipOut => ClipMode::Clip
+            ClipMode::ClipOut => ClipMode::Clip,
         }
     }
 }
 
 #[derive(Debug)]
 pub enum ClipSource {
     Rectangle(LayerRect),
     RoundedRectangle(LayerRect, BorderRadius, ClipMode),
@@ -95,61 +96,70 @@ impl From<ClipRegion> for ClipSources {
 
         if let Some(info) = region.image_mask {
             clips.push(ClipSource::Image(info));
         }
 
         clips.push(ClipSource::Rectangle(region.main));
 
         for complex in region.complex_clips {
-            clips.push(ClipSource::RoundedRectangle(complex.rect, complex.radii, ClipMode::Clip));
+            clips.push(ClipSource::RoundedRectangle(
+                complex.rect,
+                complex.radii,
+                ClipMode::Clip,
+            ));
         }
 
         ClipSources::new(clips)
     }
 }
 
 #[derive(Debug)]
 pub struct ClipSources {
     pub clips: Vec<(ClipSource, GpuCacheHandle)>,
     pub bounds: MaskBounds,
 }
 
 impl ClipSources {
     pub fn new(clips: Vec<ClipSource>) -> ClipSources {
-        let clips = clips.into_iter()
-                         .map(|clip| (clip, GpuCacheHandle::new()))
-                         .collect();
+        let clips = clips
+            .into_iter()
+            .map(|clip| (clip, GpuCacheHandle::new()))
+            .collect();
 
         ClipSources {
             clips,
             bounds: MaskBounds {
                 inner: None,
                 outer: None,
             },
         }
     }
 
     pub fn clips(&self) -> &[(ClipSource, GpuCacheHandle)] {
         &self.clips
     }
 
-    pub fn update(&mut self,
-                  layer_transform: &LayerToWorldTransform,
-                  gpu_cache: &mut GpuCache,
-                  resource_cache: &mut ResourceCache,
-                  device_pixel_ratio: f32) {
+    pub fn update(
+        &mut self,
+        layer_transform: &LayerToWorldTransform,
+        gpu_cache: &mut GpuCache,
+        resource_cache: &mut ResourceCache,
+        device_pixel_ratio: f32,
+    ) {
         if self.clips.is_empty() {
             return;
         }
 
         // compute the local bounds
         if self.bounds.inner.is_none() {
-            let mut local_rect = Some(LayerRect::new(LayerPoint::new(-MAX_CLIP, -MAX_CLIP),
-                                                     LayerSize::new(2.0 * MAX_CLIP, 2.0 * MAX_CLIP)));
+            let mut local_rect = Some(LayerRect::new(
+                LayerPoint::new(-MAX_CLIP, -MAX_CLIP),
+                LayerSize::new(2.0 * MAX_CLIP, 2.0 * MAX_CLIP),
+            ));
             let mut local_inner = local_rect;
             let mut has_clip_out = false;
             let mut has_border_clip = false;
 
             for &(ref source, _) in &self.clips {
                 match *source {
                     ClipSource::Image(ref mask) => {
                         if !mask.repeat {
@@ -166,19 +176,20 @@ impl ClipSources {
                         // case clip mask size, for now.
                         if mode == ClipMode::ClipOut {
                             has_clip_out = true;
                         }
 
                         local_rect = local_rect.and_then(|r| r.intersection(rect));
 
                         let inner_rect = extract_inner_rect_safe(rect, radius);
-                        local_inner = local_inner.and_then(|r| inner_rect.and_then(|ref inner| r.intersection(inner)));
+                        local_inner = local_inner
+                            .and_then(|r| inner_rect.and_then(|ref inner| r.intersection(inner)));
                     }
-                    ClipSource::BorderCorner{..} => {
+                    ClipSource::BorderCorner { .. } => {
                         has_border_clip = true;
                     }
                 }
             }
 
             // Work out the type of mask geometry we have, based on the
             // list of clip sources above.
             self.bounds = if has_clip_out || has_border_clip {
@@ -219,20 +230,17 @@ impl ClipSources {
                         source.write(request);
                     }
                 }
             }
         }
 
         for &(ref clip, _) in &self.clips {
             if let ClipSource::Image(ref mask) = *clip {
-                resource_cache.request_image(mask.image,
-                                             ImageRendering::Auto,
-                                             None,
-                                             gpu_cache);
+                resource_cache.request_image(mask.image, ImageRendering::Auto, None, gpu_cache);
             }
         }
     }
 
     pub fn is_masking(&self) -> bool {
         !self.clips.is_empty()
     }
 }
@@ -264,21 +272,19 @@ impl From<LayerRect> for Geometry {
 pub struct MaskBounds {
     pub outer: Option<Geometry>,
     pub inner: Option<Geometry>,
 }
 
 impl MaskBounds {
     pub fn update(&mut self, transform: &LayerToWorldTransform, device_pixel_ratio: f32) {
         if let Some(ref mut outer) = self.outer {
-            let transformed = TransformedRect::new(&outer.local_rect,
-                                                   transform,
-                                                   device_pixel_ratio);
+            let transformed =
+                TransformedRect::new(&outer.local_rect, transform, device_pixel_ratio);
             outer.device_rect = transformed.bounding_rect;
         }
         if let Some(ref mut inner) = self.inner {
-            let transformed = TransformedRect::new(&inner.local_rect,
-                                                   transform,
-                                                   device_pixel_ratio);
+            let transformed =
+                TransformedRect::new(&inner.local_rect, transform, device_pixel_ratio);
             inner.device_rect = transformed.inner_rect;
         }
     }
 }
--- a/gfx/webrender/src/clip_scroll_node.rs
+++ b/gfx/webrender/src/clip_scroll_node.rs
@@ -4,17 +4,17 @@
 
 use api::{ClipId, DeviceIntRect, LayerPixel, LayerPoint, LayerRect, LayerSize};
 use api::{LayerToScrollTransform, LayerToWorldTransform, LayerVector2D, PipelineId};
 use api::{ScrollClamping, ScrollEventPhase, ScrollLocation, ScrollSensitivity, StickyFrameInfo};
 use api::WorldPoint;
 use clip::{ClipRegion, ClipSources, ClipSourcesHandle, ClipStore};
 use clip_scroll_tree::TransformUpdateState;
 use geometry::ray_intersects_rect;
-use spring::{DAMPING, STIFFNESS, Spring};
+use spring::{Spring, DAMPING, STIFFNESS};
 use tiling::PackedLayerIndex;
 use util::{MatrixHelpers, TransformedRectKind};
 
 #[cfg(target_os = "macos")]
 const CAN_OVERSCROLL: bool = true;
 
 #[cfg(not(target_os = "macos"))]
 const CAN_OVERSCROLL: bool = false;
@@ -34,19 +34,21 @@ pub struct ClipInfo {
     pub screen_bounding_rect: Option<(TransformedRectKind, DeviceIntRect)>,
 
     /// A rectangle which defines the rough boundaries of this clip in reference
     /// frame relative coordinates (with no scroll offsets).
     pub clip_rect: LayerRect,
 }
 
 impl ClipInfo {
-    pub fn new(clip_region: ClipRegion,
-               packed_layer_index: PackedLayerIndex,
-               clip_store: &mut ClipStore) -> ClipInfo {
+    pub fn new(
+        clip_region: ClipRegion,
+        packed_layer_index: PackedLayerIndex,
+        clip_store: &mut ClipStore,
+    ) -> ClipInfo {
         let clip_rect = LayerRect::new(clip_region.origin, clip_region.main.size);
         ClipInfo {
             clip_sources: clip_store.insert(ClipSources::from(clip_region)),
             packed_layer_index,
             screen_bounding_rect: None,
             clip_rect: clip_rect,
         }
     }
@@ -113,22 +115,23 @@ pub struct ClipScrollNode {
     /// Child layers
     pub children: Vec<ClipId>,
 
     /// Whether or not this node is a reference frame.
     pub node_type: NodeType,
 }
 
 impl ClipScrollNode {
-    pub fn new_scroll_frame(pipeline_id: PipelineId,
-                            parent_id: ClipId,
-                            frame_rect: &LayerRect,
-                            content_size: &LayerSize,
-                            scroll_sensitivity: ScrollSensitivity)
-                            -> ClipScrollNode {
+    pub fn new_scroll_frame(
+        pipeline_id: PipelineId,
+        parent_id: ClipId,
+        frame_rect: &LayerRect,
+        content_size: &LayerSize,
+        scroll_sensitivity: ScrollSensitivity,
+    ) -> ClipScrollNode {
         ClipScrollNode {
             content_size: *content_size,
             local_viewport_rect: *frame_rect,
             local_clip_rect: *frame_rect,
             combined_local_viewport_rect: LayerRect::zero(),
             world_viewport_transform: LayerToWorldTransform::identity(),
             world_content_transform: LayerToWorldTransform::identity(),
             reference_frame_relative_scroll_offset: LayerVector2D::zero(),
@@ -150,23 +153,24 @@ impl ClipScrollNode {
             reference_frame_relative_scroll_offset: LayerVector2D::zero(),
             parent: Some(parent_id),
             children: Vec::new(),
             pipeline_id,
             node_type: NodeType::Clip(clip_info),
         }
     }
 
-    pub fn new_reference_frame(parent_id: Option<ClipId>,
-                               local_viewport_rect: &LayerRect,
-                               content_size: LayerSize,
-                               transform: &LayerToScrollTransform,
-                               origin_in_parent_reference_frame: LayerVector2D,
-                               pipeline_id: PipelineId)
-                               -> ClipScrollNode {
+    pub fn new_reference_frame(
+        parent_id: Option<ClipId>,
+        local_viewport_rect: &LayerRect,
+        content_size: LayerSize,
+        transform: &LayerToScrollTransform,
+        origin_in_parent_reference_frame: LayerVector2D,
+        pipeline_id: PipelineId,
+    ) -> ClipScrollNode {
         let info = ReferenceFrameInfo {
             transform: *transform,
             origin_in_parent_reference_frame,
         };
 
         ClipScrollNode {
             content_size,
             local_viewport_rect: *local_viewport_rect,
@@ -177,21 +181,22 @@ impl ClipScrollNode {
             reference_frame_relative_scroll_offset: LayerVector2D::zero(),
             parent: parent_id,
             children: Vec::new(),
             pipeline_id,
             node_type: NodeType::ReferenceFrame(info),
         }
     }
 
-    pub fn new_sticky_frame(parent_id: ClipId,
-                            frame_rect: LayerRect,
-                            sticky_frame_info: StickyFrameInfo,
-                            pipeline_id: PipelineId)
-                            -> ClipScrollNode {
+    pub fn new_sticky_frame(
+        parent_id: ClipId,
+        frame_rect: LayerRect,
+        sticky_frame_info: StickyFrameInfo,
+        pipeline_id: PipelineId,
+    ) -> ClipScrollNode {
         ClipScrollNode {
             content_size: frame_rect.size,
             local_viewport_rect: frame_rect,
             local_clip_rect: frame_rect,
             combined_local_viewport_rect: LayerRect::zero(),
             world_viewport_transform: LayerToWorldTransform::identity(),
             world_content_transform: LayerToWorldTransform::identity(),
             reference_frame_relative_scroll_offset: LayerVector2D::zero(),
@@ -209,18 +214,19 @@ impl ClipScrollNode {
 
     pub fn apply_old_scrolling_state(&mut self, new_scrolling: &ScrollingState) {
         match self.node_type {
             NodeType::ScrollFrame(ref mut scrolling) => {
                 let scroll_sensitivity = scrolling.scroll_sensitivity;
                 *scrolling = *new_scrolling;
                 scrolling.scroll_sensitivity = scroll_sensitivity;
             }
-            _ if new_scrolling.offset != LayerVector2D::zero() =>
-                warn!("Tried to scroll a non-scroll node."),
+            _ if new_scrolling.offset != LayerVector2D::zero() => {
+                warn!("Tried to scroll a non-scroll node.")
+            }
             _ => {}
         }
     }
 
     pub fn set_scroll_origin(&mut self, origin: &LayerPoint, clamp: ScrollClamping) -> bool {
         let scrollable_height = self.scrollable_height();
         let scrollable_width = self.scrollable_width();
 
@@ -234,119 +240,130 @@ impl ClipScrollNode {
 
         let new_offset = match clamp {
             ScrollClamping::ToContentBounds => {
                 if scrollable_height <= 0. && scrollable_width <= 0. {
                     return false;
                 }
 
                 let origin = LayerPoint::new(origin.x.max(0.0), origin.y.max(0.0));
-                LayerVector2D::new((-origin.x).max(-scrollable_width).min(0.0).round(),
-                                   (-origin.y).max(-scrollable_height).min(0.0).round())
+                LayerVector2D::new(
+                    (-origin.x).max(-scrollable_width).min(0.0).round(),
+                    (-origin.y).max(-scrollable_height).min(0.0).round(),
+                )
             }
             ScrollClamping::NoClamping => LayerPoint::zero() - *origin,
         };
 
         if new_offset == scrolling.offset {
             return false;
         }
 
         scrolling.offset = new_offset;
         scrolling.bouncing_back = false;
         scrolling.started_bouncing_back = false;
         true
     }
 
     pub fn update_transform(&mut self, state: &TransformUpdateState) {
-        let scrolled_parent_combined_clip = state.parent_combined_viewport_rect
+        let scrolled_parent_combined_clip = state
+            .parent_combined_viewport_rect
             .translate(&-state.parent_scroll_offset);
 
         let (local_transform, accumulated_scroll_offset) = match self.node_type {
             NodeType::ReferenceFrame(ref info) => {
-                self.combined_local_viewport_rect =
-                    info.transform.with_destination::<LayerPixel>()
-                             .inverse_rect_footprint(&scrolled_parent_combined_clip);
+                self.combined_local_viewport_rect = info.transform
+                    .with_destination::<LayerPixel>()
+                    .inverse_rect_footprint(&scrolled_parent_combined_clip);
                 self.reference_frame_relative_scroll_offset = LayerVector2D::zero();
                 (info.transform, state.parent_accumulated_scroll_offset)
             }
             NodeType::Clip(_) | NodeType::ScrollFrame(_) => {
                 // Move the parent's viewport into the local space (of the node origin)
                 // and intersect with the local clip rectangle to get the local viewport.
-                self.combined_local_viewport_rect =
-                    scrolled_parent_combined_clip.intersection(&self.local_clip_rect)
-                                                 .unwrap_or(LayerRect::zero());
+                self.combined_local_viewport_rect = scrolled_parent_combined_clip
+                    .intersection(&self.local_clip_rect)
+                    .unwrap_or(LayerRect::zero());
                 self.reference_frame_relative_scroll_offset =
                     state.parent_accumulated_scroll_offset;
-                (LayerToScrollTransform::identity(), self.reference_frame_relative_scroll_offset)
+                (
+                    LayerToScrollTransform::identity(),
+                    self.reference_frame_relative_scroll_offset,
+                )
             }
             NodeType::StickyFrame(sticky_frame_info) => {
-                let sticky_offset =
-                    self.calculate_sticky_offset(&self.local_viewport_rect,
-                                                 &sticky_frame_info,
-                                                 &state.nearest_scrolling_ancestor_offset,
-                                                 &state.nearest_scrolling_ancestor_viewport);
+                let sticky_offset = self.calculate_sticky_offset(
+                    &self.local_viewport_rect,
+                    &sticky_frame_info,
+                    &state.nearest_scrolling_ancestor_offset,
+                    &state.nearest_scrolling_ancestor_viewport,
+                );
 
-                self.combined_local_viewport_rect =
-                    scrolled_parent_combined_clip.translate(&-sticky_offset)
-                                                 .intersection(&self.local_clip_rect)
-                                                 .unwrap_or(LayerRect::zero());
+                self.combined_local_viewport_rect = scrolled_parent_combined_clip
+                    .translate(&-sticky_offset)
+                    .intersection(&self.local_clip_rect)
+                    .unwrap_or(LayerRect::zero());
                 self.reference_frame_relative_scroll_offset =
                     state.parent_accumulated_scroll_offset + sticky_offset;
-                (LayerToScrollTransform::identity(), self.reference_frame_relative_scroll_offset)
+                (
+                    LayerToScrollTransform::identity(),
+                    self.reference_frame_relative_scroll_offset,
+                )
             }
         };
 
         // The transformation for this viewport in world coordinates is the transformation for
         // our parent reference frame, plus any accumulated scrolling offsets from nodes
         // between our reference frame and this node. For reference frames, we also include
         // whatever local transformation this reference frame provides. This can be combined
         // with the local_viewport_rect to get its position in world space.
-        self.world_viewport_transform =
-            state.parent_reference_frame_transform
-                .pre_translate(accumulated_scroll_offset.to_3d())
-                .pre_mul(&local_transform.with_destination::<LayerPixel>());
+        self.world_viewport_transform = state
+            .parent_reference_frame_transform
+            .pre_translate(accumulated_scroll_offset.to_3d())
+            .pre_mul(&local_transform.with_destination::<LayerPixel>());
 
         // The transformation for any content inside of us is the viewport transformation, plus
         // whatever scrolling offset we supply as well.
         let scroll_offset = self.scroll_offset();
-        self.world_content_transform =
-            self.world_viewport_transform.pre_translate(scroll_offset.to_3d());
+        self.world_content_transform = self.world_viewport_transform
+            .pre_translate(scroll_offset.to_3d());
     }
 
-    fn calculate_sticky_offset(&self,
-                               sticky_rect: &LayerRect,
-                               sticky_frame_info: &StickyFrameInfo,
-                               viewport_scroll_offset: &LayerVector2D,
-                               viewport_rect: &LayerRect)
-                               -> LayerVector2D {
+    fn calculate_sticky_offset(
+        &self,
+        sticky_rect: &LayerRect,
+        sticky_frame_info: &StickyFrameInfo,
+        viewport_scroll_offset: &LayerVector2D,
+        viewport_rect: &LayerRect,
+    ) -> LayerVector2D {
         let sticky_rect = sticky_rect.translate(viewport_scroll_offset);
         let mut sticky_offset = LayerVector2D::zero();
 
         if let Some(info) = sticky_frame_info.top {
             sticky_offset.y = viewport_rect.min_y() + info.margin - sticky_rect.min_y();
             sticky_offset.y = sticky_offset.y.max(0.0).min(info.max_offset);
         }
 
-        if sticky_offset.y == 0.0  {
+        if sticky_offset.y == 0.0 {
             if let Some(info) = sticky_frame_info.bottom {
                 sticky_offset.y = (viewport_rect.max_y() - info.margin) -
-                                  (sticky_offset.y + sticky_rect.min_y() + sticky_rect.size.height);
+                    (sticky_offset.y + sticky_rect.min_y() + sticky_rect.size.height);
                 sticky_offset.y = sticky_offset.y.min(0.0).max(info.max_offset);
             }
         }
 
         if let Some(info) = sticky_frame_info.left {
             sticky_offset.x = viewport_rect.min_x() + info.margin - sticky_rect.min_x();
             sticky_offset.x = sticky_offset.x.max(0.0).min(info.max_offset);
         }
 
-        if sticky_offset.x == 0.0  {
+        if sticky_offset.x == 0.0 {
             if let Some(info) = sticky_frame_info.right {
                 sticky_offset.x = (viewport_rect.max_x() - info.margin) -
-                                  (sticky_offset.x + sticky_rect.min_x() + sticky_rect.size.width);
+                    (sticky_offset.x + sticky_rect.min_x() + sticky_rect.size.width);
                 sticky_offset.x = sticky_offset.x.min(0.0).max(info.max_offset);
             }
         }
 
         sticky_offset
     }
 
     pub fn scrollable_height(&self) -> f32 {
@@ -375,33 +392,33 @@ impl ClipScrollNode {
             ScrollLocation::Start => {
                 if scrolling.offset.y.round() >= 0.0 {
                     // Nothing to do on this layer.
                     return false;
                 }
 
                 scrolling.offset.y = 0.0;
                 return true;
-            },
+            }
             ScrollLocation::End => {
                 let end_pos = self.local_viewport_rect.size.height - self.content_size.height;
 
                 if scrolling.offset.y.round() <= end_pos {
                     // Nothing to do on this layer.
                     return false;
                 }
 
                 scrolling.offset.y = end_pos;
                 return true;
             }
         };
 
         let overscroll_amount = scrolling.overscroll_amount(scrollable_width, scrollable_height);
-        let overscrolling = CAN_OVERSCROLL && (overscroll_amount.x != 0.0 ||
-                                               overscroll_amount.y != 0.0);
+        let overscrolling =
+            CAN_OVERSCROLL && (overscroll_amount.x != 0.0 || overscroll_amount.y != 0.0);
         if overscrolling {
             if overscroll_amount.x != 0.0 {
                 delta.x /= overscroll_amount.x.abs()
             }
             if overscroll_amount.y != 0.0 {
                 delta.y /= overscroll_amount.y.abs()
             }
         }
@@ -421,60 +438,65 @@ impl ClipScrollNode {
             if is_unscrollable || !CAN_OVERSCROLL {
                 scrolling.offset.y = scrolling.offset.y.min(0.0).max(-scrollable_height).round();
             }
         }
 
         if phase == ScrollEventPhase::Start || phase == ScrollEventPhase::Move(true) {
             scrolling.started_bouncing_back = false
         } else if overscrolling &&
-                ((delta.x < 1.0 && delta.y < 1.0) || phase == ScrollEventPhase::End) {
+            ((delta.x < 1.0 && delta.y < 1.0) || phase == ScrollEventPhase::End)
+        {
             scrolling.started_bouncing_back = true;
             scrolling.bouncing_back = true
         }
 
         if CAN_OVERSCROLL {
             scrolling.stretch_overscroll_spring(overscroll_amount);
         }
 
         scrolling.offset != original_layer_scroll_offset || scrolling.started_bouncing_back
     }
 
     pub fn tick_scrolling_bounce_animation(&mut self) {
-       if let NodeType::ScrollFrame(ref mut scrolling) = self.node_type {
-           scrolling.tick_scrolling_bounce_animation();
+        if let NodeType::ScrollFrame(ref mut scrolling) = self.node_type {
+            scrolling.tick_scrolling_bounce_animation();
         }
     }
 
     pub fn ray_intersects_node(&self, cursor: &WorldPoint) -> bool {
         let inv = self.world_viewport_transform.inverse().unwrap();
         let z0 = -10000.0;
-        let z1 =  10000.0;
+        let z1 = 10000.0;
 
         let p0 = inv.transform_point3d(&cursor.extend(z0));
         let p1 = inv.transform_point3d(&cursor.extend(z1));
 
         if self.scrollable_width() <= 0. && self.scrollable_height() <= 0. {
             return false;
         }
-        ray_intersects_rect(p0.to_untyped(), p1.to_untyped(), self.local_viewport_rect.to_untyped())
+        ray_intersects_rect(
+            p0.to_untyped(),
+            p1.to_untyped(),
+            self.local_viewport_rect.to_untyped(),
+        )
     }
 
     pub fn scroll_offset(&self) -> LayerVector2D {
         match self.node_type {
             NodeType::ScrollFrame(ref scrolling) => scrolling.offset,
             _ => LayerVector2D::zero(),
         }
     }
 
     pub fn is_overscrolling(&self) -> bool {
         match self.node_type {
             NodeType::ScrollFrame(ref scrolling) => {
-                let overscroll_amount = scrolling.overscroll_amount(self.scrollable_width(),
-                                                                    self.scrollable_height());
+                let overscroll_amount =
+                    scrolling.overscroll_amount(self.scrollable_width(), self.scrollable_height());
                 overscroll_amount.x != 0.0 || overscroll_amount.y != 0.0
             }
             _ => false,
         }
     }
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -504,31 +526,33 @@ impl ScrollingState {
         match self.scroll_sensitivity {
             ScrollSensitivity::ScriptAndInputEvents => true,
             ScrollSensitivity::Script => false,
         }
     }
 
     pub fn stretch_overscroll_spring(&mut self, overscroll_amount: LayerVector2D) {
         let offset = self.offset.to_point();
-        self.spring.coords(offset, offset, offset + overscroll_amount);
+        self.spring
+            .coords(offset, offset, offset + overscroll_amount);
     }
 
     pub fn tick_scrolling_bounce_animation(&mut self) {
         let finished = self.spring.animate();
         self.offset = self.spring.current().to_vector();
         if finished {
             self.bouncing_back = false
         }
     }
 
-    pub fn overscroll_amount(&self,
-                             scrollable_width: f32,
-                             scrollable_height: f32)
-                             -> LayerVector2D {
+    pub fn overscroll_amount(
+        &self,
+        scrollable_width: f32,
+        scrollable_height: f32,
+    ) -> LayerVector2D {
         let overscroll_x = if self.offset.x > 0.0 {
             -self.offset.x
         } else if self.offset.x < -scrollable_width {
             -scrollable_width - self.offset.x
         } else {
             0.0
         };
 
--- a/gfx/webrender/src/clip_scroll_tree.rs
+++ b/gfx/webrender/src/clip_scroll_tree.rs
@@ -1,19 +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/. */
 
-use clip::ClipStore;
-use clip_scroll_node::{ClipScrollNode, NodeType, ScrollingState};
-use internal_types::{FastHashSet, FastHashMap};
-use print_tree::{PrintTree, PrintTreePrinter};
 use api::{ClipId, LayerPoint, LayerRect, LayerToScrollTransform, LayerToWorldTransform};
 use api::{LayerVector2D, PipelineId, ScrollClamping, ScrollEventPhase, ScrollLayerState};
 use api::{ScrollLocation, StickyFrameInfo, WorldPoint};
+use clip::ClipStore;
+use clip_scroll_node::{ClipScrollNode, NodeType, ScrollingState};
+use internal_types::{FastHashMap, FastHashSet};
+use print_tree::{PrintTree, PrintTreePrinter};
 
 pub type ScrollStates = FastHashMap<ClipId, ScrollingState>;
 
 pub struct ClipScrollTree {
     pub nodes: FastHashMap<ClipId, ClipScrollNode>,
     pub pending_scroll_offsets: FastHashMap<ClipId, (LayerPoint, ScrollClamping)>,
 
     /// The ClipId of the currently scrolling node. Used to allow the same
@@ -70,43 +70,44 @@ impl ClipScrollTree {
 
     pub fn topmost_scrolling_node_id(&self) -> ClipId {
         // TODO(mrobinson): We should eventually make this impossible to misuse.
         debug_assert!(!self.nodes.is_empty());
         debug_assert!(self.nodes.contains_key(&self.topmost_scrolling_node_id));
         self.topmost_scrolling_node_id
     }
 
-    pub fn collect_nodes_bouncing_back(&self)
-                                       -> FastHashSet<ClipId> {
+    pub fn collect_nodes_bouncing_back(&self) -> FastHashSet<ClipId> {
         let mut nodes_bouncing_back = FastHashSet::default();
         for (clip_id, node) in self.nodes.iter() {
             if let NodeType::ScrollFrame(ref scrolling) = node.node_type {
                 if scrolling.bouncing_back {
                     nodes_bouncing_back.insert(*clip_id);
                 }
             }
         }
         nodes_bouncing_back
     }
 
-    fn find_scrolling_node_at_point_in_node(&self,
-                                            cursor: &WorldPoint,
-                                            clip_id: ClipId)
-                                            -> Option<ClipId> {
+    fn find_scrolling_node_at_point_in_node(
+        &self,
+        cursor: &WorldPoint,
+        clip_id: ClipId,
+    ) -> Option<ClipId> {
         self.nodes.get(&clip_id).and_then(|node| {
             for child_layer_id in node.children.iter().rev() {
                 if let Some(layer_id) =
-                   self.find_scrolling_node_at_point_in_node(cursor, *child_layer_id) {
+                    self.find_scrolling_node_at_point_in_node(cursor, *child_layer_id)
+                {
                     return Some(layer_id);
                 }
             }
 
             match node.node_type {
-                NodeType::ScrollFrame(state) if state.sensitive_to_input_events() => {},
+                NodeType::ScrollFrame(state) if state.sensitive_to_input_events() => {}
                 _ => return None,
             }
 
             if node.ray_intersects_node(cursor) {
                 Some(clip_id)
             } else {
                 None
             }
@@ -117,17 +118,20 @@ impl ClipScrollTree {
         self.find_scrolling_node_at_point_in_node(cursor, self.root_reference_frame_id())
             .unwrap_or(self.topmost_scrolling_node_id())
     }
 
     pub fn get_scroll_node_state(&self) -> Vec<ScrollLayerState> {
         let mut result = vec![];
         for (id, node) in self.nodes.iter() {
             if let NodeType::ScrollFrame(scrolling) = node.node_type {
-                result.push(ScrollLayerState { id: *id, scroll_offset: scrolling.offset })
+                result.push(ScrollLayerState {
+                    id: *id,
+                    scroll_offset: scrolling.offset,
+                })
             }
         }
         result
     }
 
     pub fn drain(&mut self) -> ScrollStates {
         self.current_new_node_item = 1;
 
@@ -155,43 +159,45 @@ impl ClipScrollTree {
         if let Some(node) = self.nodes.get_mut(&id) {
             return node.set_scroll_origin(&origin, clamp);
         }
 
         self.pending_scroll_offsets.insert(id, (origin, clamp));
         false
     }
 
-    pub fn scroll(&mut self,
-                  scroll_location: ScrollLocation,
-                  cursor: WorldPoint,
-                  phase: ScrollEventPhase)
-                  -> bool {
+    pub fn scroll(
+        &mut self,
+        scroll_location: ScrollLocation,
+        cursor: WorldPoint,
+        phase: ScrollEventPhase,
+    ) -> bool {
         if self.nodes.is_empty() {
             return false;
         }
 
         let clip_id = match (
             phase,
             self.find_scrolling_node_at_point(&cursor),
-            self.currently_scrolling_node_id) {
+            self.currently_scrolling_node_id,
+        ) {
             (ScrollEventPhase::Start, scroll_node_at_point_id, _) => {
                 self.currently_scrolling_node_id = Some(scroll_node_at_point_id);
                 scroll_node_at_point_id
-            },
+            }
             (_, scroll_node_at_point_id, Some(cached_clip_id)) => {
                 let clip_id = match self.nodes.get(&cached_clip_id) {
                     Some(_) => cached_clip_id,
                     None => {
                         self.currently_scrolling_node_id = Some(scroll_node_at_point_id);
                         scroll_node_at_point_id
-                    },
+                    }
                 };
                 clip_id
-            },
+            }
             (_, _, None) => return false,
         };
 
         let topmost_scrolling_node_id = self.topmost_scrolling_node_id();
         let non_root_overscroll = if clip_id != topmost_scrolling_node_id {
             self.nodes.get(&clip_id).unwrap().is_overscrolling()
         } else {
             false
@@ -201,49 +207,55 @@ impl ClipScrollTree {
         if let Some(node) = self.nodes.get_mut(&clip_id) {
             if let NodeType::ScrollFrame(ref mut scrolling) = node.node_type {
                 match phase {
                     ScrollEventPhase::Start => {
                         // if this is a new gesture, we do not switch node,
                         // however we do save the state of non_root_overscroll,
                         // for use in the subsequent Move phase.
                         scrolling.should_handoff_scroll = non_root_overscroll;
-                    },
+                    }
                     ScrollEventPhase::Move(_) => {
                         // Switch node if movement originated in a new gesture,
                         // from a non root node in overscroll.
                         switch_node = scrolling.should_handoff_scroll && non_root_overscroll
-                    },
+                    }
                     ScrollEventPhase::End => {
                         // clean-up when gesture ends.
                         scrolling.should_handoff_scroll = false;
                     }
                 }
             }
         }
 
         let clip_id = if switch_node {
             topmost_scrolling_node_id
         } else {
             clip_id
         };
 
-        self.nodes.get_mut(&clip_id).unwrap().scroll(scroll_location, phase)
+        self.nodes
+            .get_mut(&clip_id)
+            .unwrap()
+            .scroll(scroll_location, phase)
     }
 
     pub fn update_all_node_transforms(&mut self, pan: LayerPoint) {
         if self.nodes.is_empty() {
             return;
         }
 
         let root_reference_frame_id = self.root_reference_frame_id();
         let root_viewport = self.nodes[&root_reference_frame_id].local_clip_rect;
         let state = TransformUpdateState {
-            parent_reference_frame_transform:
-                LayerToWorldTransform::create_translation(pan.x, pan.y, 0.0),
+            parent_reference_frame_transform: LayerToWorldTransform::create_translation(
+                pan.x,
+                pan.y,
+                0.0,
+            ),
             parent_combined_viewport_rect: root_viewport,
             parent_scroll_offset: LayerVector2D::zero(),
             parent_accumulated_scroll_offset: LayerVector2D::zero(),
             nearest_scrolling_ancestor_offset: LayerVector2D::zero(),
             nearest_scrolling_ancestor_viewport: LayerRect::zero(),
         };
         self.update_node_transform(root_reference_frame_id, &state);
     }
@@ -263,29 +275,31 @@ impl ClipScrollTree {
             // between us and the parent reference frame. If we are a reference frame,
             // we need to reset both these values.
             let state = match node.node_type {
                 NodeType::ReferenceFrame(ref info) => TransformUpdateState {
                     parent_reference_frame_transform: node.world_viewport_transform,
                     parent_combined_viewport_rect: node.combined_local_viewport_rect,
                     parent_scroll_offset: LayerVector2D::zero(),
                     parent_accumulated_scroll_offset: LayerVector2D::zero(),
-                    nearest_scrolling_ancestor_viewport:
-                        state.nearest_scrolling_ancestor_viewport.translate(&info.origin_in_parent_reference_frame),
+                    nearest_scrolling_ancestor_viewport: state
+                        .nearest_scrolling_ancestor_viewport
+                        .translate(&info.origin_in_parent_reference_frame),
                     ..*state
                 },
                 NodeType::Clip(..) | NodeType::StickyFrame(..) => TransformUpdateState {
                     parent_combined_viewport_rect: node.combined_local_viewport_rect,
                     parent_scroll_offset: LayerVector2D::zero(),
                     ..*state
                 },
                 NodeType::ScrollFrame(ref scrolling) => TransformUpdateState {
                     parent_combined_viewport_rect: node.combined_local_viewport_rect,
                     parent_scroll_offset: scrolling.offset,
-                    parent_accumulated_scroll_offset: scrolling.offset + state.parent_accumulated_scroll_offset,
+                    parent_accumulated_scroll_offset: scrolling.offset +
+                        state.parent_accumulated_scroll_offset,
                     nearest_scrolling_ancestor_offset: scrolling.offset,
                     nearest_scrolling_ancestor_viewport: node.local_viewport_rect,
                     ..*state
                 },
             };
 
             (state, node.children.clone())
         };
@@ -316,43 +330,50 @@ impl ClipScrollTree {
     }
 
     pub fn generate_new_clip_id(&mut self, pipeline_id: PipelineId) -> ClipId {
         let new_id = ClipId::DynamicallyAddedNode(self.current_new_node_item, pipeline_id);
         self.current_new_node_item += 1;
         new_id
     }
 
-    pub fn add_reference_frame(&mut self,
-                               rect: &LayerRect,
-                               transform: &LayerToScrollTransform,
-                               origin_in_parent_reference_frame: LayerVector2D,
-                               pipeline_id: PipelineId,
-                               parent_id: Option<ClipId>)
-                               -> ClipId {
+    pub fn add_reference_frame(
+        &mut self,
+        rect: &LayerRect,
+        transform: &LayerToScrollTransform,
+        origin_in_parent_reference_frame: LayerVector2D,
+        pipeline_id: PipelineId,
+        parent_id: Option<ClipId>,
+    ) -> ClipId {
         let reference_frame_id = self.generate_new_clip_id(pipeline_id);
-        let node = ClipScrollNode::new_reference_frame(parent_id,
-                                                       rect,
-                                                       rect.size,
-                                                       transform,
-                                                       origin_in_parent_reference_frame,
-                                                       pipeline_id);
+        let node = ClipScrollNode::new_reference_frame(
+            parent_id,
+            rect,
+            rect.size,
+            transform,
+            origin_in_parent_reference_frame,
+            pipeline_id,
+        );
         self.add_node(node, reference_frame_id);
         reference_frame_id
     }
 
-    pub fn add_sticky_frame(&mut self,
-                            id: ClipId,
-                            parent_id: ClipId,
-                            frame_rect: LayerRect,
-                            sticky_frame_info: StickyFrameInfo) {
-        let node = ClipScrollNode::new_sticky_frame(parent_id,
-                                                    frame_rect,
-                                                    sticky_frame_info,
-                                                    id.pipeline_id());
+    pub fn add_sticky_frame(
+        &mut self,
+        id: ClipId,
+        parent_id: ClipId,
+        frame_rect: LayerRect,
+        sticky_frame_info: StickyFrameInfo,
+    ) {
+        let node = ClipScrollNode::new_sticky_frame(
+            parent_id,
+            frame_rect,
+            sticky_frame_info,
+            id.pipeline_id(),
+        );
         self.add_node(node, id);
     }
 
     pub fn add_node(&mut self, node: ClipScrollNode, id: ClipId) {
         // When the parent node is None this means we are adding the root.
         match node.parent {
             Some(parent_id) => self.nodes.get_mut(&parent_id).unwrap().add_child(id),
             None => self.root_reference_frame_id = id,
@@ -366,26 +387,26 @@ impl ClipScrollTree {
         self.pipelines_to_discard.insert(pipeline_id);
 
         match self.currently_scrolling_node_id {
             Some(id) if id.pipeline_id() == pipeline_id => self.currently_scrolling_node_id = None,
             _ => {}
         }
     }
 
-    fn print_node<T: PrintTreePrinter>(&self,
-                                       id: &ClipId,
-                                       pt: &mut T,
-                                       clip_store: &ClipStore) {
+    fn print_node<T: PrintTreePrinter>(&self, id: &ClipId, pt: &mut T, clip_store: &ClipStore) {
         let node = self.nodes.get(id).unwrap();
 
         match node.node_type {
             NodeType::Clip(ref info) => {
                 pt.new_level("Clip".to_owned());
-                pt.add_item(format!("screen_bounding_rect: {:?}", info.screen_bounding_rect));
+                pt.add_item(format!(
+                    "screen_bounding_rect: {:?}",
+                    info.screen_bounding_rect
+                ));
 
                 let clips = clip_store.get(&info.clip_sources).clips();
                 pt.new_level(format!("Clip Sources [{}]", clips.len()));
                 for source in clips {
                     pt.add_item(format!("{:?}", source));
                 }
                 pt.end_level();
             }
@@ -398,36 +419,47 @@ impl ClipScrollTree {
             }
             NodeType::StickyFrame(sticky_frame_info) => {
                 pt.new_level(format!("StickyFrame"));
                 pt.add_item(format!("sticky info: {:?}", sticky_frame_info));
             }
         }
 
         pt.add_item(format!("content_size: {:?}", node.content_size));
-        pt.add_item(format!("local_viewport_rect: {:?}", node.local_viewport_rect));
+        pt.add_item(format!(
+            "local_viewport_rect: {:?}",
+            node.local_viewport_rect
+        ));
         pt.add_item(format!("local_clip_rect: {:?}", node.local_clip_rect));
-        pt.add_item(format!("combined_local_viewport_rect: {:?}", node.combined_local_viewport_rect));
-        pt.add_item(format!("world_viewport_transform: {:?}", node.world_viewport_transform));
-        pt.add_item(format!("world_content_transform: {:?}", node.world_content_transform));
+        pt.add_item(format!(
+            "combined_local_viewport_rect: {:?}",
+            node.combined_local_viewport_rect
+        ));
+        pt.add_item(format!(
+            "world_viewport_transform: {:?}",
+            node.world_viewport_transform
+        ));
+        pt.add_item(format!(
+            "world_content_transform: {:?}",
+            node.world_content_transform
+        ));
 
         for child_id in &node.children {
             self.print_node(child_id, pt, clip_store);
         }
 
         pt.end_level();
     }
 
     #[allow(dead_code)]
     pub fn print(&self, clip_store: &ClipStore) {
         if !self.nodes.is_empty() {
             let mut pt = PrintTree::new("clip_scroll tree");
-            self.print_with(clip_store, &mut pt,);
+            self.print_with(clip_store, &mut pt);
         }
     }
 
     pub fn print_with<T: PrintTreePrinter>(&self, clip_store: &ClipStore, pt: &mut T) {
         if !self.nodes.is_empty() {
             self.print_node(&self.root_reference_frame_id, pt, clip_store);
         }
     }
 }
-
--- a/gfx/webrender/src/debug_render.rs
+++ b/gfx/webrender/src/debug_render.rs
@@ -1,86 +1,96 @@
 /* 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 api::{ColorU, DeviceIntRect, DeviceUintSize, ImageFormat};
 use debug_font_data;
-use device::{Device, GpuMarker, Program, VAO, Texture, TextureSlot, VertexDescriptor};
-use device::{TextureFilter, VertexAttribute, VertexUsageHint, VertexAttributeKind, TextureTarget};
-use euclid::{Transform3D, Point2D, Size2D, Rect};
-use internal_types::{ORTHO_NEAR_PLANE, ORTHO_FAR_PLANE};
+use device::{Device, GpuMarker, Program, Texture, TextureSlot, VertexDescriptor, VAO};
+use device::{TextureFilter, TextureTarget, VertexAttribute, VertexAttributeKind, VertexUsageHint};
+use euclid::{Point2D, Rect, Size2D, Transform3D};
+use internal_types::{ORTHO_FAR_PLANE, ORTHO_NEAR_PLANE};
 use internal_types::RenderTargetMode;
 use std::f32;
-use api::{ColorU, ImageFormat, DeviceUintSize, DeviceIntRect};
 
 #[derive(Debug, Copy, Clone)]
 enum DebugSampler {
     Font,
 }
 
 impl Into<TextureSlot> for DebugSampler {
     fn into(self) -> TextureSlot {
         match self {
             DebugSampler::Font => TextureSlot(0),
         }
     }
 }
 
 const DESC_FONT: VertexDescriptor = VertexDescriptor {
     vertex_attributes: &[
-        VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 },
-        VertexAttribute { name: "aColor", count: 4, kind: VertexAttributeKind::U8Norm },
-        VertexAttribute { name: "aColorTexCoord", count: 2, kind: VertexAttributeKind::F32 },
+        VertexAttribute {
+            name: "aPosition",
+            count: 2,
+            kind: VertexAttributeKind::F32,
+        },
+        VertexAttribute {
+            name: "aColor",
+            count: 4,
+            kind: VertexAttributeKind::U8Norm,
+        },
+        VertexAttribute {
+            name: "aColorTexCoord",
+            count: 2,
+            kind: VertexAttributeKind::F32,
+        },
     ],
-    instance_attributes: &[]
+    instance_attributes: &[],
 };
 
 const DESC_COLOR: VertexDescriptor = VertexDescriptor {
     vertex_attributes: &[
-        VertexAttribute { name: "aPosition", count: 2, kind: VertexAttributeKind::F32 },
-        VertexAttribute { name: "aColor", count: 4, kind: VertexAttributeKind::U8Norm },
+        VertexAttribute {
+            name: "aPosition",
+            count: 2,
+            kind: VertexAttributeKind::F32,
+        },
+        VertexAttribute {
+            name: "aColor",
+            count: 4,
+            kind: VertexAttributeKind::U8Norm,
+        },
     ],
-    instance_attributes: &[]
+    instance_attributes: &[],
 };
 
 #[repr(C)]
 pub struct DebugFontVertex {
     pub x: f32,
     pub y: f32,
     pub color: ColorU,
     pub u: f32,
     pub v: f32,
 }
 
 impl DebugFontVertex {
     pub fn new(x: f32, y: f32, u: f32, v: f32, color: ColorU) -> DebugFontVertex {
-        DebugFontVertex {
-            x,
-            y,
-            color,
-            u,
-            v,
-        }
+        DebugFontVertex { x, y, color, u, v }
     }
 }
 
 #[repr(C)]
 pub struct DebugColorVertex {
     pub x: f32,
     pub y: f32,
     pub color: ColorU,
 }
 
 impl DebugColorVertex {
     pub fn new(x: f32, y: f32, color: ColorU) -> DebugColorVertex {
-        DebugColorVertex {
-            x,
-            y,
-            color,
-        }
+        DebugColorVertex { x, y, color }
     }
 }
 
 pub struct DebugRenderer {
     font_vertices: Vec<DebugFontVertex>,
     font_indices: Vec<u32>,
     font_program: Program,
     font_vao: VAO,
@@ -91,40 +101,38 @@ pub struct DebugRenderer {
     tri_vao: VAO,
     line_vertices: Vec<DebugColorVertex>,
     line_vao: VAO,
     color_program: Program,
 }
 
 impl DebugRenderer {
     pub fn new(device: &mut Device) -> DebugRenderer {
-        let font_program = device.create_program("debug_font",
-                                                 "",
-                                                 &DESC_FONT).unwrap();
-        device.bind_shader_samplers(&font_program, &[
-            ("sColor0", DebugSampler::Font)
-        ]);
+        let font_program = device.create_program("debug_font", "", &DESC_FONT).unwrap();
+        device.bind_shader_samplers(&font_program, &[("sColor0", DebugSampler::Font)]);
 
-        let color_program = device.create_program("debug_color",
-                                                  "",
-                                                  &DESC_COLOR).unwrap();
+        let color_program = device
+            .create_program("debug_color", "", &DESC_COLOR)
+            .unwrap();
 
         let font_vao = device.create_vao(&DESC_FONT);
         let line_vao = device.create_vao(&DESC_COLOR);
         let tri_vao = device.create_vao(&DESC_COLOR);
 
         let mut font_texture = device.create_texture(TextureTarget::Array);
-        device.init_texture(&mut font_texture,
-                            debug_font_data::BMP_WIDTH,
-                            debug_font_data::BMP_HEIGHT,
-                            ImageFormat::A8,
-                            TextureFilter::Linear,
-                            RenderTargetMode::None,
-                            1,
-                            Some(&debug_font_data::FONT_BITMAP));
+        device.init_texture(
+            &mut font_texture,
+            debug_font_data::BMP_WIDTH,
+            debug_font_data::BMP_HEIGHT,
+            ImageFormat::A8,
+            TextureFilter::Linear,
+            RenderTargetMode::None,
+            1,
+            Some(&debug_font_data::FONT_BITMAP),
+        );
 
         DebugRenderer {
             font_vertices: Vec::new(),
             font_indices: Vec::new(),
             line_vertices: Vec::new(),
             tri_vao,
             tri_vertices: Vec::new(),
             tri_indices: Vec::new(),
@@ -144,21 +152,17 @@ impl DebugRenderer {
         device.delete_vao(self.line_vao);
         device.delete_vao(self.font_vao);
     }
 
     pub fn line_height(&self) -> f32 {
         debug_font_data::FONT_SIZE as f32 * 1.1
     }
 
-    pub fn add_text(&mut self,
-                    x: f32,
-                    y: f32,
-                    text: &str,
-                    color: ColorU) -> Rect<f32> {
+    pub fn add_text(&mut self, x: f32, y: f32, text: &str, color: ColorU) -> Rect<f32> {
         let mut x_start = x;
         let ipw = 1.0 / debug_font_data::BMP_WIDTH as f32;
         let iph = 1.0 / debug_font_data::BMP_HEIGHT as f32;
 
         let mut min_x = f32::MAX;
         let mut max_x = -f32::MAX;
         let mut min_y = f32::MAX;
         let mut max_y = -f32::MAX;
@@ -178,134 +182,145 @@ impl DebugRenderer {
                 let t0 = glyph.y0 as f32 * iph;
                 let s1 = glyph.x1 as f32 * ipw;
                 let t1 = glyph.y1 as f32 * iph;
 
                 x_start += glyph.xa;
 
                 let vertex_count = self.font_vertices.len() as u32;
 
-                self.font_vertices.push(DebugFontVertex::new(x0, y0, s0, t0, color));
-                self.font_vertices.push(DebugFontVertex::new(x1, y0, s1, t0, color));
-                self.font_vertices.push(DebugFontVertex::new(x0, y1, s0, t1, color));
-                self.font_vertices.push(DebugFontVertex::new(x1, y1, s1, t1, color));
+                self.font_vertices
+                    .push(DebugFontVertex::new(x0, y0, s0, t0, color));
+                self.font_vertices
+                    .push(DebugFontVertex::new(x1, y0, s1, t0, color));
+                self.font_vertices
+                    .push(DebugFontVertex::new(x0, y1, s0, t1, color));
+                self.font_vertices
+                    .push(DebugFontVertex::new(x1, y1, s1, t1, color));
 
                 self.font_indices.push(vertex_count + 0);
                 self.font_indices.push(vertex_count + 1);
                 self.font_indices.push(vertex_count + 2);
                 self.font_indices.push(vertex_count + 2);
                 self.font_indices.push(vertex_count + 1);
                 self.font_indices.push(vertex_count + 3);
 
                 min_x = min_x.min(x0);
                 max_x = max_x.max(x1);
                 min_y = min_y.min(y0);
                 max_y = max_y.max(y1);
             }
         }
 
-        Rect::new(Point2D::new(min_x, min_y), Size2D::new(max_x-min_x, max_y-min_y))
+        Rect::new(
+            Point2D::new(min_x, min_y),
+            Size2D::new(max_x - min_x, max_y - min_y),
+        )
     }
 
-    pub fn add_quad(&mut self,
-                    x0: f32,
-                    y0: f32,
-                    x1: f32,
-                    y1: f32,
-                    color_top: ColorU,
-                    color_bottom: ColorU) {
+    pub fn add_quad(
+        &mut self,
+        x0: f32,
+        y0: f32,
+        x1: f32,
+        y1: f32,
+        color_top: ColorU,
+        color_bottom: ColorU,
+    ) {
         let vertex_count = self.tri_vertices.len() as u32;
 
-        self.tri_vertices.push(DebugColorVertex::new(x0, y0, color_top));
-        self.tri_vertices.push(DebugColorVertex::new(x1, y0, color_top));
-        self.tri_vertices.push(DebugColorVertex::new(x0, y1, color_bottom));
-        self.tri_vertices.push(DebugColorVertex::new(x1, y1, color_bottom));
+        self.tri_vertices
+            .push(DebugColorVertex::new(x0, y0, color_top));
+        self.tri_vertices
+            .push(DebugColorVertex::new(x1, y0, color_top));
+        self.tri_vertices
+            .push(DebugColorVertex::new(x0, y1, color_bottom));
+        self.tri_vertices
+            .push(DebugColorVertex::new(x1, y1, color_bottom));
 
         self.tri_indices.push(vertex_count + 0);
         self.tri_indices.push(vertex_count + 1);
         self.tri_indices.push(vertex_count + 2);
         self.tri_indices.push(vertex_count + 2);
         self.tri_indices.push(vertex_count + 1);
         self.tri_indices.push(vertex_count + 3);
     }
 
     #[allow(dead_code)]
-    pub fn add_line(&mut self,
-                    x0: i32,
-                    y0: i32,
-                    color0: ColorU,
-                    x1: i32,
-                    y1: i32,
-                    color1: ColorU) {
-        self.line_vertices.push(DebugColorVertex::new(x0 as f32, y0 as f32, color0));
-        self.line_vertices.push(DebugColorVertex::new(x1 as f32, y1 as f32, color1));
+    pub fn add_line(&mut self, x0: i32, y0: i32, color0: ColorU, x1: i32, y1: i32, color1: ColorU) {
+        self.line_vertices
+            .push(DebugColorVertex::new(x0 as f32, y0 as f32, color0));
+        self.line_vertices
+            .push(DebugColorVertex::new(x1 as f32, y1 as f32, color1));
     }
 
 
     pub fn add_rect(&mut self, rect: &DeviceIntRect, color: ColorU) {
         let p0 = rect.origin;
         let p1 = p0 + rect.size;
         self.add_line(p0.x, p0.y, color, p1.x, p0.y, color);
         self.add_line(p1.x, p0.y, color, p1.x, p1.y, color);
         self.add_line(p1.x, p1.y, color, p0.x, p1.y, color);
         self.add_line(p0.x, p1.y, color, p0.x, p0.y, color);
     }
 
-    pub fn render(&mut self,
-                  device: &mut Device,
-                  viewport_size: &DeviceUintSize) {
+    pub fn render(&mut self, device: &mut Device, viewport_size: &DeviceUintSize) {
         let _gm = GpuMarker::new(device.rc_gl(), "debug");
         device.disable_depth();
         device.set_blend(true);
         device.set_blend_mode_alpha();
 
-        let projection = Transform3D::ortho(0.0,
-                                            viewport_size.width as f32,
-                                            viewport_size.height as f32,
-                                            0.0,
-                                            ORTHO_NEAR_PLANE,
-                                            ORTHO_FAR_PLANE);
+        let projection = Transform3D::ortho(
+            0.0,
+            viewport_size.width as f32,
+            viewport_size.height as f32,
+            0.0,
+            ORTHO_NEAR_PLANE,
+            ORTHO_FAR_PLANE,
+        );
 
         // Triangles
         if !self.tri_vertices.is_empty() {
             device.bind_program(&self.color_program);
             device.set_uniforms(&self.color_program, &projection);
             device.bind_vao(&self.tri_vao);
-            device.update_vao_indices(&self.tri_vao,
-                                      &self.tri_indices,
-                                      VertexUsageHint::Dynamic);
-            device.update_vao_main_vertices(&self.tri_vao,
-                                            &self.tri_vertices,
-                                            VertexUsageHint::Dynamic);
+            device.update_vao_indices(&self.tri_vao, &self.tri_indices, VertexUsageHint::Dynamic);
+            device.update_vao_main_vertices(
+                &self.tri_vao,
+                &self.tri_vertices,
+                VertexUsageHint::Dynamic,
+            );
             device.draw_triangles_u32(0, self.tri_indices.len() as i32);
         }
 
         // Lines
         if !self.line_vertices.is_empty() {
             device.bind_program(&self.color_program);
             device.set_uniforms(&self.color_program, &projection);
             device.bind_vao(&self.line_vao);
-            device.update_vao_main_vertices(&self.line_vao,
-                                            &self.line_vertices,
-                                            VertexUsageHint::Dynamic);
+            device.update_vao_main_vertices(
+                &self.line_vao,
+                &self.line_vertices,
+                VertexUsageHint::Dynamic,
+            );
             device.draw_nonindexed_lines(0, self.line_vertices.len() as i32);
         }
 
         // Glyph
         if !self.font_indices.is_empty() {
             device.bind_program(&self.font_program);
             device.set_uniforms(&self.font_program, &projection);
             device.bind_texture(DebugSampler::Font, &self.font_texture);
             device.bind_vao(&self.font_vao);
-            device.update_vao_indices(&self.font_vao,
-                                      &self.font_indices,
-                                      VertexUsageHint::Dynamic);
-            device.update_vao_main_vertices(&self.font_vao,
-                                            &self.font_vertices,
-                                            VertexUsageHint::Dynamic);
+            device.update_vao_indices(&self.font_vao, &self.font_indices, VertexUsageHint::Dynamic);
+            device.update_vao_main_vertices(
+                &self.font_vao,
+                &self.font_vertices,
+                VertexUsageHint::Dynamic,
+            );
             device.draw_triangles_u32(0, self.font_indices.len() as i32);
         }
 
         self.font_indices.clear();
         self.font_vertices.clear();
         self.line_vertices.clear();
         self.tri_vertices.clear();
         self.tri_indices.clear();
--- a/gfx/webrender/src/debug_server.rs
+++ b/gfx/webrender/src/debug_server.rs
@@ -1,19 +1,18 @@
 /* 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 api::{ApiMsg, DebugCommand};
 use api::channel::MsgSender;
+use print_tree::PrintTreePrinter;
 use std::sync::mpsc::{channel, Receiver};
-use std::thread;
 use std::sync::mpsc::Sender;
-
-use print_tree::PrintTreePrinter;
+use std::thread;
 use ws;
 
 // Messages that are sent from the render backend to the renderer
 // debug command queue. These are sent in a separate queue so
 // that none of these types are exposed to the RenderApi interfaces.
 // We can't use select!() as it's not stable...
 enum DebugMsg {
     AddSender(ws::Sender),
@@ -24,62 +23,44 @@ enum DebugMsg {
 struct Server {
     ws: ws::Sender,
     debug_tx: Sender<DebugMsg>,
     api_tx: MsgSender<ApiMsg>,
 }
 
 impl ws::Handler for Server {
     fn on_open(&mut self, _: ws::Handshake) -> ws::Result<()> {
-        self.debug_tx.send(DebugMsg::AddSender(self.ws.clone())).ok();
+        self.debug_tx
+            .send(DebugMsg::AddSender(self.ws.clone()))
+            .ok();
 
         Ok(())
     }
 
     fn on_close(&mut self, _: ws::CloseCode, _: &str) {
-        self.debug_tx.send(DebugMsg::RemoveSender(self.ws.token())).ok();
+        self.debug_tx
+            .send(DebugMsg::RemoveSender(self.ws.token()))
+            .ok();
     }
 
     fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> {
         match msg {
             ws::Message::Text(string) => {
                 let cmd = match string.as_str() {
-                    "enable_profiler" => {
-                        DebugCommand::EnableProfiler(true)
-                    }
-                    "disable_profiler" => {
-                        DebugCommand::EnableProfiler(false)
-                    }
-                    "enable_texture_cache_debug" => {
-                        DebugCommand::EnableTextureCacheDebug(true)
-                    }
-                    "disable_texture_cache_debug" => {
-                        DebugCommand::EnableTextureCacheDebug(false)
-                    }
-                    "enable_render_target_debug" => {
-                        DebugCommand::EnableRenderTargetDebug(true)
-                    }
-                    "disable_render_target_debug" => {
-                        DebugCommand::EnableRenderTargetDebug(false)
-                    }
-                    "enable_alpha_rects_debug" => {
-                        DebugCommand::EnableAlphaRectsDebug(true)
-                    }
-                    "disable_alpha_rects_debug" => {
-                        DebugCommand::EnableAlphaRectsDebug(false)
-                    }
-                    "fetch_passes" => {
-                        DebugCommand::FetchPasses
-                    }
-                    "fetch_documents" => {
-                        DebugCommand::FetchDocuments
-                    }
-                    "fetch_clipscrolltree" => {
-                        DebugCommand::FetchClipScrollTree
-                    }
+                    "enable_profiler" => DebugCommand::EnableProfiler(true),
+                    "disable_profiler" => DebugCommand::EnableProfiler(false),
+                    "enable_texture_cache_debug" => DebugCommand::EnableTextureCacheDebug(true),
+                    "disable_texture_cache_debug" => DebugCommand::EnableTextureCacheDebug(false),
+                    "enable_render_target_debug" => DebugCommand::EnableRenderTargetDebug(true),
+                    "disable_render_target_debug" => DebugCommand::EnableRenderTargetDebug(false),
+                    "enable_alpha_rects_debug" => DebugCommand::EnableAlphaRectsDebug(true),
+                    "disable_alpha_rects_debug" => DebugCommand::EnableAlphaRectsDebug(false),
+                    "fetch_passes" => DebugCommand::FetchPasses,
+                    "fetch_documents" => DebugCommand::FetchDocuments,
+                    "fetch_clipscrolltree" => DebugCommand::FetchClipScrollTree,
                     msg => {
                         println!("unknown msg {}", msg);
                         return Ok(());
                     }
                 };
 
                 let msg = ApiMsg::DebugCommand(cmd);
                 self.api_tx.send(msg).unwrap();
@@ -99,23 +80,25 @@ pub struct DebugServer {
     debug_rx: Receiver<DebugMsg>,
     senders: Vec<ws::Sender>,
 }
 
 impl DebugServer {
     pub fn new(api_tx: MsgSender<ApiMsg>) -> DebugServer {
         let (debug_tx, debug_rx) = channel();
 
-        let socket = ws::Builder::new().build(move |out| {
-            Server {
-                ws: out,
-                debug_tx: debug_tx.clone(),
-                api_tx: api_tx.clone(),
-            }
-        }).unwrap();
+        let socket = ws::Builder::new()
+            .build(move |out| {
+                Server {
+                    ws: out,
+                    debug_tx: debug_tx.clone(),
+                    api_tx: api_tx.clone(),
+                }
+            })
+            .unwrap();
 
         let broadcaster = socket.broadcaster();
 
         let join_handle = Some(thread::spawn(move || {
             let address = "127.0.0.1:3583";
             println!("WebRender debug server started: {}", address);
             if let Err(..) = socket.listen(address) {
                 println!("ERROR: Unable to bind debugger websocket (port may be in use).");
@@ -133,19 +116,17 @@ impl DebugServer {
     pub fn send(&mut self, message: String) {
         // Add any new connections that have been queued.
         while let Ok(msg) = self.debug_rx.try_recv() {
             match msg {
                 DebugMsg::AddSender(sender) => {
                     self.senders.push(sender);
                 }
                 DebugMsg::RemoveSender(token) => {
-                    self.senders.retain(|sender| {
-                        sender.token() != token
-                    });
+                    self.senders.retain(|sender| sender.token() != token);
                 }
             }
         }
 
         // Broadcast the message to all senders. Keep
         // track of the ones that failed, so they can
         // be removed from the active sender list.
         let mut disconnected_senders = Vec::new();
@@ -319,40 +300,38 @@ impl ClipScrollTreeList {
 // A TreeNode-based PrintTreePrinter to serialize pretty-printed
 // trees as json
 pub struct TreeNodeBuilder {
     levels: Vec<TreeNode>,
 }
 
 impl TreeNodeBuilder {
     pub fn new(root: TreeNode) -> TreeNodeBuilder {
-        TreeNodeBuilder {
-            levels: vec![root]
-        }
+        TreeNodeBuilder { levels: vec![root] }
     }
 
     fn current_level_mut(&mut self) -> &mut TreeNode {
         assert!(!self.levels.is_empty());
         self.levels.last_mut().unwrap()
     }
 
     pub fn build(mut self) -> TreeNode {
         assert!(self.levels.len() == 1);
         self.levels.pop().unwrap()
     }
 }
 
 impl PrintTreePrinter for TreeNodeBuilder {
     fn new_level(&mut self, title: String) {
-         let level = TreeNode::new(&title);
-         self.levels.push(level);
+        let level = TreeNode::new(&title);
+        self.levels.push(level);
     }
 
     fn end_level(&mut self) {
-         assert!(!self.levels.is_empty());
-         let last_level = self.levels.pop().unwrap();
-         self.current_level_mut().add_child(last_level);
+        assert!(!self.levels.is_empty());
+        let last_level = self.levels.pop().unwrap();
+        self.current_level_mut().add_child(last_level);
     }
 
     fn add_item(&mut self, text: String) {
-         self.current_level_mut().add_item(&text);
+        self.current_level_mut().add_item(&text);
     }
 }
--- a/gfx/webrender/src/device.rs
+++ b/gfx/webrender/src/device.rs
@@ -1,27 +1,27 @@
 /* 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 super::shader_source;
+use api::{ColorF, ImageFormat};
+use api::{DeviceIntRect, DeviceUintSize};
 use euclid::Transform3D;
 use gleam::gl;
 use internal_types::RenderTargetMode;
-use super::shader_source;
 use std::fs::File;
 use std::io::Read;
 use std::iter::repeat;
 use std::mem;
 use std::ops::Add;
 use std::path::PathBuf;
 use std::ptr;
 use std::rc::Rc;
 use std::thread;
-use api::{ColorF, ImageFormat};
-use api::{DeviceIntRect, DeviceUintSize};
 
 #[derive(Debug, Copy, Clone, PartialEq, Ord, Eq, PartialOrd)]
 pub struct FrameId(usize);
 
 impl FrameId {
     pub fn new(value: usize) -> FrameId {
         FrameId(value)
     }
@@ -112,75 +112,74 @@ pub struct VertexDescriptor {
 
 enum FBOTarget {
     Read,
     Draw,
 }
 
 pub fn get_gl_format_bgra(gl: &gl::Gl) -> gl::GLuint {
     match gl.get_type() {
-        gl::GlType::Gl => {
-            GL_FORMAT_BGRA_GL
-        }
-        gl::GlType::Gles => {
-            GL_FORMAT_BGRA_GLES
-        }
+        gl::GlType::Gl => GL_FORMAT_BGRA_GL,
+        gl::GlType::Gles => GL_FORMAT_BGRA_GLES,
     }
 }
 
 fn get_shader_version(gl: &gl::Gl) -> &'static str {
     match gl.get_type() {
-        gl::GlType::Gl => {
-            SHADER_VERSION_GL
-        }
-        gl::GlType::Gles => {
-            SHADER_VERSION_GLES
-        }
+        gl::GlType::Gl => SHADER_VERSION_GL,
+        gl::GlType::Gles => SHADER_VERSION_GLES,
     }
 }
 
 // Get a shader string by name, from the built in resources or
 // an override path, if supplied.
 fn get_shader_source(shader_name: &str, base_path: &Option<PathBuf>) -> Option<String> {
     if let Some(ref base) = *base_path {
         let shader_path = base.join(&format!("{}.glsl", shader_name));
         if shader_path.exists() {
             let mut source = String::new();
-            File::open(&shader_path).unwrap().read_to_string(&mut source).unwrap();
+            File::open(&shader_path)
+                .unwrap()
+                .read_to_string(&mut source)
+                .unwrap();
             return Some(source);
         }
     }
 
-    shader_source::SHADERS.get(shader_name).map(|s| s.to_string())
+    shader_source::SHADERS
+        .get(shader_name)
+        .map(|s| s.to_string())
 }
 
 // Parse a shader string for imports. Imports are recursively processed, and
 // prepended to the list of outputs.
 fn parse_shader_source(source: String, base_path: &Option<PathBuf>, output: &mut String) {
     for line in source.lines() {
         if line.starts_with(SHADER_IMPORT) {
-            let imports = line[SHADER_IMPORT.len()..].split(",");
+            let imports = line[SHADER_IMPORT.len() ..].split(",");
 
             // For each import, get the source, and recurse.
             for import in imports {
                 if let Some(include) = get_shader_source(import, base_path) {
                     parse_shader_source(include, base_path, output);
                 }
             }
         } else {
             output.push_str(line);
             output.push_str("\n");
         }
     }
 }
 
-pub fn build_shader_strings(gl_version_string: &str,
-                            features: &str,
-                            base_filename: &str,
-                            override_path: &Option<PathBuf>) -> (String, String) {
+pub fn build_shader_strings(
+    gl_version_string: &str,
+    features: &str,
+    base_filename: &str,
+    override_path: &Option<PathBuf>,
+) -> (String, String) {
     // Construct a list of strings to be passed to the shader compiler.
     let mut vs_source = String::new();
     let mut fs_source = String::new();
 
     // GLSL requires that the version number comes first.
     vs_source.push_str(gl_version_string);
     fs_source.push_str(gl_version_string);
 
@@ -191,19 +190,17 @@ pub fn build_shader_strings(gl_version_s
     // Add any defines that were passed by the caller.
     vs_source.push_str(features);
     fs_source.push_str(features);
 
     // Parse the main .glsl file, including any imports
     // and append them to the list of sources.
     let mut shared_result = String::new();
     if let Some(shared_source) = get_shader_source(base_filename, override_path) {
-        parse_shader_source(shared_source,
-            override_path,
-            &mut shared_result);
+        parse_shader_source(shared_source, override_path, &mut shared_result);
     }
 
     vs_source.push_str(SHADER_LINE_MARKER);
     vs_source.push_str(&shared_result);
     fs_source.push_str(SHADER_LINE_MARKER);
     fs_source.push_str(&shared_result);
 
     // Append legacy (.vs and .fs) files if they exist.
@@ -219,17 +216,17 @@ pub fn build_shader_strings(gl_version_s
     if let Some(old_fs_source) = get_shader_source(&fs_name, override_path) {
         fs_source.push_str(SHADER_LINE_MARKER);
         fs_source.push_str(&old_fs_source);
     }
 
     (vs_source, fs_source)
 }
 
-pub trait FileWatcherHandler : Send {
+pub trait FileWatcherHandler: Send {
     fn file_changed(&self, path: PathBuf);
 }
 
 impl VertexAttributeKind {
     fn size_in_bytes(&self) -> u32 {
         match *self {
             VertexAttributeKind::F32 => 4,
             VertexAttributeKind::U8Norm => 1,
@@ -239,102 +236,109 @@ impl VertexAttributeKind {
     }
 }
 
 impl VertexAttribute {
     fn size_in_bytes(&self) -> u32 {
         self.count * self.kind.size_in_bytes()
     }
 
-    fn bind_to_vao(&self,
-                   attr_index: gl::GLuint,
-                   divisor: gl::GLuint,
-                   stride: gl::GLint,
-                   offset: gl::GLuint,
-                   gl: &gl::Gl) {
+    fn bind_to_vao(
+        &self,
+        attr_index: gl::GLuint,
+        divisor: gl::GLuint,
+        stride: gl::GLint,
+        offset: gl::GLuint,
+        gl: &gl::Gl,
+    ) {
         gl.enable_vertex_attrib_array(attr_index);
         gl.vertex_attrib_divisor(attr_index, divisor);
 
         match self.kind {
             VertexAttributeKind::F32 => {
-                gl.vertex_attrib_pointer(attr_index,
-                                         self.count as gl::GLint,
-                                         gl::FLOAT,
-                                         false,
-                                         stride,
-                                         offset);
+                gl.vertex_attrib_pointer(
+                    attr_index,
+                    self.count as gl::GLint,
+                    gl::FLOAT,
+                    false,
+                    stride,
+                    offset,
+                );
             }
             VertexAttributeKind::U8Norm => {
-                gl.vertex_attrib_pointer(attr_index,
-                                         self.count as gl::GLint,
-                                         gl::UNSIGNED_BYTE,
-                                         true,
-                                         stride,
-                                         offset);
+                gl.vertex_attrib_pointer(
+                    attr_index,
+                    self.count as gl::GLint,
+                    gl::UNSIGNED_BYTE,
+                    true,
+                    stride,
+                    offset,
+                );
             }
             VertexAttributeKind::I32 => {
-                gl.vertex_attrib_i_pointer(attr_index,
-                                           self.count as gl::GLint,
-                                           gl::INT,
-                                           stride,
-                                           offset);
+                gl.vertex_attrib_i_pointer(
+                    attr_index,
+                    self.count as gl::GLint,
+                    gl::INT,
+                    stride,
+                    offset,
+                );
             }
             VertexAttributeKind::U16 => {
-                gl.vertex_attrib_i_pointer(attr_index,
-                                           self.count as gl::GLint,
-                                           gl::UNSIGNED_SHORT,
-                                           stride,
-                                           offset);
+                gl.vertex_attrib_i_pointer(
+                    attr_index,
+                    self.count as gl::GLint,
+                    gl::UNSIGNED_SHORT,
+                    stride,
+                    offset,
+                );
             }
         }
     }
 }
 
 impl VertexDescriptor {
     fn instance_stride(&self) -> u32 {
         self.instance_attributes
             .iter()
-            .map(|attr| attr.size_in_bytes()).sum()
+            .map(|attr| attr.size_in_bytes())
+            .sum()
     }
 
-    fn bind(&self,
-            gl: &gl::Gl,
-            main: VBOId,
-            instance: VBOId) {
+    fn bind(&self, gl: &gl::Gl, main: VBOId, instance: VBOId) {
         main.bind(gl);
 
         let vertex_stride: u32 = self.vertex_attributes
-                                    .iter()
-                                    .map(|attr| attr.size_in_bytes()).sum();
+            .iter()
+            .map(|attr| attr.size_in_bytes())
+            .sum();
         let mut vertex_offset = 0;
 
         for (i, attr) in self.vertex_attributes.iter().enumerate() {
             let attr_index = i as gl::GLuint;
-            attr.bind_to_vao(attr_index,
-                             0,
-                             vertex_stride as gl::GLint,
-                             vertex_offset,
-                             gl);
+            attr.bind_to_vao(attr_index, 0, vertex_stride as gl::GLint, vertex_offset, gl);
             vertex_offset += attr.size_in_bytes();
         }
 
         if !self.instance_attributes.is_empty() {
             instance.bind(gl);
             let instance_stride = self.instance_stride();
             let mut instance_offset = 0;
 
             let base_attr = self.vertex_attributes.len() as u32;
 
             for (i, attr) in self.instance_attributes.iter().enumerate() {
                 let attr_index = base_attr + i as u32;
-                attr.bind_to_vao(attr_index,
-                                 1,
-                                 instance_stride as gl::GLint,
-                                 instance_offset,
-                                 gl);
+                attr.bind_to_vao(
+                    attr_index,
+                    1,
+                    instance_stride as gl::GLint,
+                    instance_offset,
+                    gl,
+                );
                 instance_offset += attr.size_in_bytes();
             }
         }
     }
 }
 
 impl VBOId {
     fn bind(&self, gl: &gl::Gl) {
@@ -420,42 +424,51 @@ impl Drop for Texture {
 pub struct Program {
     id: gl::GLuint,
     u_transform: gl::GLint,
     u_device_pixel_ratio: gl::GLint,
 }
 
 impl Drop for Program {
     fn drop(&mut self) {
-        debug_assert!(thread::panicking() || self.id == 0, "renderer::deinit not called");
+        debug_assert!(
+            thread::panicking() || self.id == 0,
+            "renderer::deinit not called"
+        );
     }
 }
 
 pub struct VAO {
     id: gl::GLuint,
     ibo_id: IBOId,
     main_vbo_id: VBOId,
     instance_vbo_id: VBOId,
     instance_stride: usize,
     owns_vertices_and_indices: bool,
 }
 
 impl Drop for VAO {
     fn drop(&mut self) {
-        debug_assert!(thread::panicking() || self.id == 0, "renderer::deinit not called");
+        debug_assert!(
+            thread::panicking() || self.id == 0,
+            "renderer::deinit not called"
+        );
     }
 }
 
 pub struct PBO {
     id: gl::GLuint,
 }
 
 impl Drop for PBO {
     fn drop(&mut self) {
-        debug_assert!(thread::panicking() || self.id == 0, "renderer::deinit not called");
+        debug_assert!(
+            thread::panicking() || self.id == 0,
+            "renderer::deinit not called"
+        );
     }
 }
 
 #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
 pub struct FBOId(gl::GLuint);
 
 #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)]
 pub struct RBOId(gl::GLuint);
@@ -503,23 +516,21 @@ impl<T> QuerySet<T> {
 
     fn reset(&mut self) {
         self.data.clear();
         self.pending = 0;
     }
 
     fn add(&mut self, value: T) -> Option<gl::GLuint> {
         assert_eq!(self.pending, 0);
-        self.set.get(self.data.len())
-            .cloned()
-            .map(|query_id| {
-                self.data.push(value);
-                self.pending = query_id;
-                query_id
-            })
+        self.set.get(self.data.len()).cloned().map(|query_id| {
+            self.data.push(value);
+            self.pending = query_id;
+            query_id
+        })
     }
 
     fn take<F: Fn(&mut T, gl::GLuint)>(&mut self, fun: F) -> Vec<T> {
         let mut data = mem::replace(&mut self.data, Vec::new());
         for (value, &query) in data.iter_mut().zip(self.set.iter()) {
             fun(value, query)
         }
         data
@@ -569,17 +580,20 @@ impl<T> GpuFrameProfile<T> {
     fn done_marker(&mut self) {
         debug_assert!(self.inside_frame);
         if self.timers.pending != 0 {
             self.gl.end_query(gl::TIME_ELAPSED);
             self.timers.pending = 0;
         }
     }
 
-    fn add_marker(&mut self, tag: T) -> GpuMarker where T: NamedTag {
+    fn add_marker(&mut self, tag: T) -> GpuMarker
+    where
+        T: NamedTag,
+    {
         self.done_marker();
 
         let marker = GpuMarker::new(&self.gl, tag.get_label());
 
         if let Some(query) = self.timers.add(GpuTimer { tag, time_ns: 0 }) {
             self.gl.begin_query(gl::TIME_ELAPSED, query);
         }
 
@@ -591,17 +605,20 @@ impl<T> GpuFrameProfile<T> {
         debug_assert!(self.inside_frame);
         if self.samplers.pending != 0 {
             self.gl.end_query(gl::SAMPLES_PASSED);
             self.samplers.pending = 0;
         }
         */
     }
 
-    fn add_sampler(&mut self, _tag: T) where T: NamedTag {
+    fn add_sampler(&mut self, _tag: T)
+    where
+        T: NamedTag,
+    {
         /* FIXME: samplers crash on MacOS
         self.done_sampler();
 
         if let Some(query) = self.samplers.add(GpuSampler { tag, count: 0 }) {
             self.gl.begin_query(gl::SAMPLES_PASSED, query);
         }
         */
     }
@@ -609,34 +626,35 @@ impl<T> GpuFrameProfile<T> {
     fn is_valid(&self) -> bool {
         !self.timers.set.is_empty() || !self.samplers.set.is_empty()
     }
 
     fn build_samples(&mut self) -> (Vec<GpuTimer<T>>, Vec<GpuSampler<T>>) {
         debug_assert!(!self.inside_frame);
         let gl = &self.gl;
 
-        (self.timers.take(|timer, query| {
-            timer.time_ns = gl.get_query_object_ui64v(query, gl::QUERY_RESULT)
-         }),
-         self.samplers.take(|sampler, query| {
-            sampler.count = gl.get_query_object_ui64v(query, gl::QUERY_RESULT)
-         }),
+        (
+            self.timers.take(|timer, query| {
+                timer.time_ns = gl.get_query_object_ui64v(query, gl::QUERY_RESULT)
+            }),
+            self.samplers.take(|sampler, query| {
+                sampler.count = gl.get_query_object_ui64v(query, gl::QUERY_RESULT)
+            }),
         )
     }
 }
 
 impl<T> Drop for GpuFrameProfile<T> {
     fn drop(&mut self) {
         match self.gl.get_type() {
-            gl::GlType::Gl =>  {
+            gl::GlType::Gl => {
                 self.gl.delete_queries(&self.timers.set);
                 self.gl.delete_queries(&self.samplers.set);
             }
-            gl::GlType::Gles => {},
+            gl::GlType::Gles => {}
         }
     }
 }
 
 pub struct GpuProfiler<T> {
     frames: [GpuFrameProfile<T>; MAX_PROFILE_FRAMES],
     next_frame: usize,
 }
@@ -671,70 +689,68 @@ impl<T> GpuProfiler<T> {
 
     pub fn end_frame(&mut self) {
         let frame = &mut self.frames[self.next_frame];
         frame.end_frame();
         self.next_frame = (self.next_frame + 1) % MAX_PROFILE_FRAMES;
     }
 
     pub fn add_marker(&mut self, tag: T) -> GpuMarker
-    where T: NamedTag {
+    where
+        T: NamedTag,
+    {
         self.frames[self.next_frame].add_marker(tag)
     }
 
     pub fn add_sampler(&mut self, tag: T)
-    where T: NamedTag {
+    where
+        T: NamedTag,
+    {
         self.frames[self.next_frame].add_sampler(tag)
     }
 
     pub fn done_sampler(&mut self) {
         self.frames[self.next_frame].done_sampler()
     }
 }
 
 #[must_use]
-pub struct GpuMarker{
+pub struct GpuMarker {
     gl: Rc<gl::Gl>,
 }
 
 impl GpuMarker {
     pub fn new(gl: &Rc<gl::Gl>, message: &str) -> GpuMarker {
         match gl.get_type() {
-            gl::GlType::Gl =>  {
+            gl::GlType::Gl => {
                 gl.push_group_marker_ext(message);
-                GpuMarker{
-                    gl: Rc::clone(gl),
-                }
+                GpuMarker { gl: Rc::clone(gl) }
             }
-            gl::GlType::Gles => {
-                GpuMarker{
-                    gl: Rc::clone(gl),
-                }
-            }
+            gl::GlType::Gles => GpuMarker { gl: Rc::clone(gl) },
         }
     }
 
     pub fn fire(gl: &gl::Gl, message: &str) {
         match gl.get_type() {
-            gl::GlType::Gl =>  {
+            gl::GlType::Gl => {
                 gl.insert_event_marker_ext(message);
             }
-            gl::GlType::Gles => {},
+            gl::GlType::Gles => {}
         }
     }
 }
 
-#[cfg(not(any(target_arch="arm", target_arch="aarch64")))]
+#[cfg(not(any(target_arch = "arm", target_arch = "aarch64")))]
 impl Drop for GpuMarker {
     fn drop(&mut self) {
         match self.gl.get_type() {
-            gl::GlType::Gl =>  {
+            gl::GlType::Gl => {
                 self.gl.pop_group_marker_ext();
             }
-            gl::GlType::Gles => {},
+            gl::GlType::Gles => {}
         }
     }
 }
 
 
 #[derive(Debug, Copy, Clone)]
 pub enum VertexUsageHint {
     Static,
@@ -763,17 +779,17 @@ impl UniformLocation {
 
 pub struct Capabilities {
     pub supports_multisampling: bool,
 }
 
 #[derive(Clone, Debug)]
 pub enum ShaderError {
     Compilation(String, String), // name, error mssage
-    Link(String, String), // name, error message
+    Link(String, String),        // name, error message
 }
 
 pub struct Device {
     gl: Rc<gl::Gl>,
     // device state
     bound_textures: [gl::GLuint; 16],
     bound_program: gl::GLuint,
     bound_vao: gl::GLuint,
@@ -796,19 +812,21 @@ pub struct Device {
     max_texture_size: u32,
 
     // Frame counter. This is used to map between CPU
     // frames and GPU frames.
     frame_id: FrameId,
 }
 
 impl Device {
-    pub fn new(gl: Rc<gl::Gl>,
-               resource_override_path: Option<PathBuf>,
-               _file_changed_handler: Box<FileWatcherHandler>) -> Device {
+    pub fn new(
+        gl: Rc<gl::Gl>,
+        resource_override_path: Option<PathBuf>,
+        _file_changed_handler: Box<FileWatcherHandler>,
+    ) -> Device {
         let max_texture_size = gl.get_integer_v(gl::MAX_TEXTURE_SIZE) as u32;
 
         Device {
             gl,
             resource_override_path,
             // This is initialized to 1 by default, but it is set
             // every frame by the call to begin_frame().
             device_pixel_ratio: 1.0,
@@ -851,21 +869,22 @@ impl Device {
     pub fn reset_state(&mut self) {
         self.bound_textures = [0; 16];
         self.bound_vao = 0;
         self.bound_pbo = 0;
         self.bound_read_fbo = FBOId(0);
         self.bound_draw_fbo = FBOId(0);
     }
 
-    pub fn compile_shader(gl: &gl::Gl,
-                          name: &str,
-                          shader_type: gl::GLenum,
-                          source: String)
-                          -> Result<gl::GLuint, ShaderError> {
+    pub fn compile_shader(
+        gl: &gl::Gl,
+        name: &str,
+        shader_type: gl::GLenum,
+        source: String,
+    ) -> Result<gl::GLuint, ShaderError> {
         debug!("compile {:?}", name);
         let id = gl.create_shader(shader_type);
         gl.shader_source(id, &[source.as_bytes()]);
         gl.compile_shader(id);
         let log = gl.get_shader_info_log(id);
         if gl.get_shader_iv(id, gl::COMPILE_STATUS) == (0 as gl::GLint) {
             println!("Failed to compile shader: {:?}\n{}", name, log);
             Err(ShaderError::Compilation(name.to_string(), log))
@@ -884,17 +903,17 @@ impl Device {
 
         // Retrive the currently set FBO.
         let default_read_fbo = self.gl.get_integer_v(gl::READ_FRAMEBUFFER_BINDING);
         self.default_read_fbo = default_read_fbo as gl::GLuint;
         let default_draw_fbo = self.gl.get_integer_v(gl::DRAW_FRAMEBUFFER_BINDING);
         self.default_draw_fbo = default_draw_fbo as gl::GLuint;
 
         // Texture state
-        for i in 0..self.bound_textures.len() {
+        for i in 0 .. self.bound_textures.len() {
             self.bound_textures[i] = 0;
             self.gl.active_texture(gl::TEXTURE0 + i as gl::GLuint);
             self.gl.bind_texture(gl::TEXTURE_2D, 0);
         }
 
         // Shader state
         self.bound_program = 0;
         self.gl.use_program(0);
@@ -913,40 +932,45 @@ impl Device {
         self.gl.bind_buffer(gl::PIXEL_UNPACK_BUFFER, 0);
 
         // Default is sampler 0, always
         self.gl.active_texture(gl::TEXTURE0);
 
         self.frame_id
     }
 
-    pub fn bind_texture<S>(&mut self,
-                           sampler: S,
-                           texture: &Texture) where S: Into<TextureSlot> {
+    pub fn bind_texture<S>(&mut self, sampler: S, texture: &Texture)
+    where
+        S: Into<TextureSlot>,
+    {
         debug_assert!(self.inside_frame);
 
         let sampler_index = sampler.into().0;
         if self.bound_textures[sampler_index] != texture.id {
             self.bound_textures[sampler_index] = texture.id;
-            self.gl.active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint);
+            self.gl
+                .active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint);
             self.gl.bind_texture(texture.target, texture.id);
             self.gl.active_texture(gl::TEXTURE0);
         }
     }
 
-    pub fn bind_external_texture<S>(&mut self,
-                                    sampler: S,
-                                    external_texture: &ExternalTexture) where S: Into<TextureSlot> {
+    pub fn bind_external_texture<S>(&mut self, sampler: S, external_texture: &ExternalTexture)
+    where
+        S: Into<TextureSlot>,
+    {
         debug_assert!(self.inside_frame);
 
         let sampler_index = sampler.into().0;
         if self.bound_textures[sampler_index] != external_texture.id {
             self.bound_textures[sampler_index] = external_texture.id;
-            self.gl.active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint);
-            self.gl.bind_texture(external_texture.target, external_texture.id);
+            self.gl
+                .active_texture(gl::TEXTURE0 + sampler_index as gl::GLuint);
+            self.gl
+                .bind_texture(external_texture.target, external_texture.id);
             self.gl.active_texture(gl::TEXTURE0);
         }
     }
 
     pub fn bind_read_target(&mut self, texture_and_layer: Option<(&Texture, i32)>) {
         debug_assert!(self.inside_frame);
 
         let fbo_id = texture_and_layer.map_or(FBOId(self.default_read_fbo), |texture_and_layer| {
@@ -954,44 +978,53 @@ impl Device {
         });
 
         if self.bound_read_fbo != fbo_id {
             self.bound_read_fbo = fbo_id;
             fbo_id.bind(self.gl(), FBOTarget::Read);
         }
     }
 
-    pub fn bind_draw_target(&mut self,
-                            texture_and_layer: Option<(&Texture, i32)>,
-                            dimensions: Option<DeviceUintSize>) {
+    pub fn bind_draw_target(
+        &mut self,
+        texture_and_layer: Option<(&Texture, i32)>,
+        dimensions: Option<DeviceUintSize>,
+    ) {
         debug_assert!(self.inside_frame);
 
         let fbo_id = texture_and_layer.map_or(FBOId(self.default_draw_fbo), |texture_and_layer| {
             texture_and_layer.0.fbo_ids[texture_and_layer.1 as usize]
         });
 
         if self.bound_draw_fbo != fbo_id {
             self.bound_draw_fbo = fbo_id;
             fbo_id.bind(self.gl(), FBOTarget::Draw);
         }
 
         if let Some(dimensions) = dimensions {
-            self.gl.viewport(0, 0, dimensions.width as gl::GLint, dimensions.height as gl::GLint);
+            self.gl.viewport(
+                0,
+                0,
+                dimensions.width as gl::GLint,
+                dimensions.height as gl::GLint,
+            );
         }
     }
 
     pub fn create_fbo_for_external_texture(&mut self, texture_id: u32) -> FBOId {
         let fbo = FBOId(self.gl.gen_framebuffers(1)[0]);
         self.bind_external_draw_target(fbo);
         self.gl.bind_framebuffer(gl::FRAMEBUFFER, fbo.0);
-        self.gl.framebuffer_texture_2d(gl::FRAMEBUFFER,
-                                       gl::COLOR_ATTACHMENT0,
-                                       gl::TEXTURE_2D,
-                                       texture_id,
-                                       0);
+        self.gl.framebuffer_texture_2d(
+            gl::FRAMEBUFFER,
+            gl::COLOR_ATTACHMENT0,
+            gl::TEXTURE_2D,
+            texture_id,
+            0,
+        );
         fbo
     }
 
     pub fn delete_fbo(&mut self, fbo: FBOId) {
         self.gl.delete_framebuffers(&[fbo.0]);
     }
 
     pub fn bind_external_draw_target(&mut self, fbo_id: FBOId) {
@@ -1024,40 +1057,42 @@ impl Device {
             mode: RenderTargetMode::None,
             fbo_ids: vec![],
             depth_rb: None,
         }
     }
 
     fn set_texture_parameters(&mut self, target: gl::GLuint, filter: TextureFilter) {
         let filter = match filter {
-            TextureFilter::Nearest => {
-                gl::NEAREST
-            }
-            TextureFilter::Linear => {
-                gl::LINEAR
-            }
+            TextureFilter::Nearest => gl::NEAREST,
+            TextureFilter::Linear => gl::LINEAR,
         };
 
-        self.gl.tex_parameter_i(target, gl::TEXTURE_MAG_FILTER, filter as gl::GLint);
-        self.gl.tex_parameter_i(target, gl::TEXTURE_MIN_FILTER, filter as gl::GLint);
+        self.gl
+            .tex_parameter_i(target, gl::TEXTURE_MAG_FILTER, filter as gl::GLint);
+        self.gl
+            .tex_parameter_i(target, gl::TEXTURE_MIN_FILTER, filter as gl::GLint);
 
-        self.gl.tex_parameter_i(target, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint);
-        self.gl.tex_parameter_i(target, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint);
+        self.gl
+            .tex_parameter_i(target, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as gl::GLint);
+        self.gl
+            .tex_parameter_i(target, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as gl::GLint);
     }
 
-    pub fn init_texture(&mut self,
-                        texture: &mut Texture,
-                        width: u32,
-                        height: u32,
-                        format: ImageFormat,
-                        filter: TextureFilter,
-                        mode: RenderTargetMode,
-                        layer_count: i32,
-                        pixels: Option<&[u8]>) {
+    pub fn init_texture(
+        &mut self,
+        texture: &mut Texture,
+        width: u32,
+        height: u32,
+        format: ImageFormat,
+        filter: TextureFilter,
+        mode: RenderTargetMode,
+        layer_count: i32,
+        pixels: Option<&[u8]>,
+    ) {
         debug_assert!(self.inside_frame);
 
         let resized = texture.width != width || texture.height != height;
 
         texture.format = format;
         texture.width = width;
         texture.height = height;
         texture.filter = filter;
@@ -1072,191 +1107,217 @@ impl Device {
                 self.bind_texture(DEFAULT_TEXTURE, texture);
                 self.set_texture_parameters(texture.target, filter);
                 self.update_texture_storage(texture, layer_count, resized);
             }
             RenderTargetMode::None => {
                 self.bind_texture(DEFAULT_TEXTURE, texture);
                 self.set_texture_parameters(texture.target, filter);
                 let expanded_data: Vec<u8>;
-                let actual_pixels = if pixels.is_some() &&
-                                       format == ImageFormat::A8 &&
-                                       cfg!(any(target_arch="arm", target_arch="aarch64")) {
-                    expanded_data = pixels.unwrap().iter().flat_map(|&byte| repeat(byte).take(4)).collect();
+                let actual_pixels = if pixels.is_some() && format == ImageFormat::A8 &&
+                    cfg!(any(target_arch = "arm", target_arch = "aarch64"))
+                {
+                    expanded_data = pixels
+                        .unwrap()
+                        .iter()
+                        .flat_map(|&byte| repeat(byte).take(4))
+                        .collect();
                     Some(expanded_data.as_slice())
                 } else {
                     pixels
                 };
 
                 match texture.target {
                     gl::TEXTURE_2D_ARRAY => {
-                        self.gl.tex_image_3d(gl::TEXTURE_2D_ARRAY,
-                                             0,
-                                             internal_format as gl::GLint,
-                                             width as gl::GLint,
-                                             height as gl::GLint,
-                                             layer_count,
-                                             0,
-                                             gl_format,
-                                             type_,
-                                             actual_pixels);
+                        self.gl.tex_image_3d(
+                            gl::TEXTURE_2D_ARRAY,
+                            0,
+                            internal_format as gl::GLint,
+                            width as gl::GLint,
+                            height as gl::GLint,
+                            layer_count,
+                            0,
+                            gl_format,
+                            type_,
+                            actual_pixels,
+                        );
                     }
-                    gl::TEXTURE_2D |
-                    gl::TEXTURE_RECTANGLE |
-                    gl::TEXTURE_EXTERNAL_OES => {
-                        self.gl.tex_image_2d(texture.target,
-                                             0,
-                                             internal_format as gl::GLint,
-                                             width as gl::GLint, height as gl::GLint,
-                                             0,
-                                             gl_format,
-                                             type_,
-                                             actual_pixels);
+                    gl::TEXTURE_2D | gl::TEXTURE_RECTANGLE | gl::TEXTURE_EXTERNAL_OES => {
+                        self.gl.tex_image_2d(
+                            texture.target,
+                            0,
+                            internal_format as gl::GLint,
+                            width as gl::GLint,
+                            height as gl::GLint,
+                            0,
+                            gl_format,
+                            type_,
+                            actual_pixels,
+                        );
                     }
                     _ => panic!("BUG: Unexpected texture target!"),
                 }
             }
         }
     }
 
     /// Updates the texture storage for the texture, creating
     /// FBOs as required.
-    fn update_texture_storage(&mut self,
-                              texture: &mut Texture,
-                              layer_count: i32,
-                              resized: bool) {
+    fn update_texture_storage(&mut self, texture: &mut Texture, layer_count: i32, resized: bool) {
         assert!(layer_count > 0);
         assert_eq!(texture.target, gl::TEXTURE_2D_ARRAY);
 
         let current_layer_count = texture.fbo_ids.len() as i32;
         // If the texture is already the required size skip.
         if current_layer_count == layer_count && !resized {
             return;
         }
 
-        let (internal_format, gl_format) = gl_texture_formats_for_image_format(&*self.gl, texture.format);
+        let (internal_format, gl_format) =
+            gl_texture_formats_for_image_format(&*self.gl, texture.format);
         let type_ = gl_type_for_texture_format(texture.format);
 
-        self.gl.tex_image_3d(texture.target,
-                             0,
-                             internal_format as gl::GLint,
-                             texture.width as gl::GLint,
-                             texture.height as gl::GLint,
-                             layer_count,
-                             0,
-                             gl_format,
-                             type_,
-                             None);
+        self.gl.tex_image_3d(
+            texture.target,
+            0,
+            internal_format as gl::GLint,
+            texture.width as gl::GLint,
+            texture.height as gl::GLint,
+            layer_count,
+            0,
+            gl_format,
+            type_,
+            None,
+        );
 
         let needed_layer_count = layer_count - current_layer_count;
         if needed_layer_count > 0 {
             // Create more framebuffers to fill the gap
             let new_fbos = self.gl.gen_framebuffers(needed_layer_count);
-            texture.fbo_ids.extend(new_fbos.into_iter().map(|id| FBOId(id)));
+            texture
+                .fbo_ids
+                .extend(new_fbos.into_iter().map(|id| FBOId(id)));
         } else if needed_layer_count < 0 {
             // Remove extra framebuffers
             for old in texture.fbo_ids.drain(layer_count as usize ..) {
                 self.gl.delete_framebuffers(&[old.0]);
             }
         }
 
         let depth_rb = if let Some(rbo) = texture.depth_rb {
             rbo.0
         } else {
             let renderbuffer_ids = self.gl.gen_renderbuffers(1);
             let depth_rb = renderbuffer_ids[0];
             texture.depth_rb = Some(RBOId(depth_rb));
             depth_rb
         };
         self.gl.bind_renderbuffer(gl::RENDERBUFFER, depth_rb);
-        self.gl.renderbuffer_storage(gl::RENDERBUFFER,
-                                     gl::DEPTH_COMPONENT24,
-                                     texture.width as gl::GLsizei,
-                                     texture.height as gl::GLsizei);
+        self.gl.renderbuffer_storage(
+            gl::RENDERBUFFER,
+            gl::DEPTH_COMPONENT24,
+            texture.width as gl::GLsizei,
+            texture.height as gl::GLsizei,
+        );
 
         for (fbo_index, fbo_id) in texture.fbo_ids.iter().enumerate() {
             self.gl.bind_framebuffer(gl::FRAMEBUFFER, fbo_id.0);
-            self.gl.framebuffer_texture_layer(gl::FRAMEBUFFER,
-                                              gl::COLOR_ATTACHMENT0,
-                                              texture.id,
-                                              0,
-                                              fbo_index as gl::GLint);
-            self.gl.framebuffer_renderbuffer(gl::FRAMEBUFFER,
-                                             gl::DEPTH_ATTACHMENT,
-                                             gl::RENDERBUFFER,
-                                             depth_rb);
+            self.gl.framebuffer_texture_layer(
+                gl::FRAMEBUFFER,
+                gl::COLOR_ATTACHMENT0,
+                texture.id,
+                0,
+                fbo_index as gl::GLint,
+            );
+            self.gl.framebuffer_renderbuffer(
+                gl::FRAMEBUFFER,
+                gl::DEPTH_ATTACHMENT,
+                gl::RENDERBUFFER,
+                depth_rb,
+            );
         }
 
         // TODO(gw): Hack! Modify the code above to use the normal binding interfaces the device exposes.
-        self.gl.bind_framebuffer(gl::READ_FRAMEBUFFER, self.bound_read_fbo.0);
-        self.gl.bind_framebuffer(gl::DRAW_FRAMEBUFFER, self.bound_draw_fbo.0);
+        self.gl
+            .bind_framebuffer(gl::READ_FRAMEBUFFER, self.bound_read_fbo.0);
+        self.gl
+            .bind_framebuffer(gl::DRAW_FRAMEBUFFER, self.bound_draw_fbo.0);
     }
 
-    pub fn blit_render_target(&mut self,
-                              src_rect: DeviceIntRect,
-                              dest_rect: DeviceIntRect) {
+    pub fn blit_render_target(&mut self, src_rect: DeviceIntRect, dest_rect: DeviceIntRect) {
         debug_assert!(self.inside_frame);
 
-        self.gl.blit_framebuffer(src_rect.origin.x,
-                                  src_rect.origin.y,
-                                  src_rect.origin.x + src_rect.size.width,
-                                  src_rect.origin.y + src_rect.size.height,
-                                  dest_rect.origin.x,
-                                  dest_rect.origin.y,
-                                  dest_rect.origin.x + dest_rect.size.width,
-                                  dest_rect.origin.y + dest_rect.size.height,
-                                  gl::COLOR_BUFFER_BIT,
-                                  gl::LINEAR);
+        self.gl.blit_framebuffer(
+            src_rect.origin.x,
+            src_rect.origin.y,
+            src_rect.origin.x + src_rect.size.width,
+            src_rect.origin.y + src_rect.size.height,
+            dest_rect.origin.x,
+            dest_rect.origin.y,
+            dest_rect.origin.x + dest_rect.size.width,
+            dest_rect.origin.y + dest_rect.size.height,
+            gl::COLOR_BUFFER_BIT,
+            gl::LINEAR,
+        );
     }
 
     pub fn free_texture_storage(&mut self, texture: &mut Texture) {
         debug_assert!(self.inside_frame);
         debug_assert_eq!(self.bound_pbo, 0);
 
         if texture.format == ImageFormat::Invalid {
             return;
         }
 
         self.bind_texture(DEFAULT_TEXTURE, texture);
 
-        let (internal_format, gl_format) = gl_texture_formats_for_image_format(&*self.gl, texture.format);
+        let (internal_format, gl_format) =
+            gl_texture_formats_for_image_format(&*self.gl, texture.format);
         let type_ = gl_type_for_texture_format(texture.format);
 
         match texture.target {
             gl::TEXTURE_2D_ARRAY => {
-                self.gl.tex_image_3d(gl::TEXTURE_2D_ARRAY,
-                                     0,
-                                     internal_format as gl::GLint,
-                                     0,
-                                     0,
-                                     0,
-                                     0,
-                                     gl_format,
-                                     type_,
-                                     None);
+                self.gl.tex_image_3d(
+                    gl::TEXTURE_2D_ARRAY,
+                    0,
+                    internal_format as gl::GLint,
+                    0,
+                    0,
+                    0,
+                    0,
+                    gl_format,
+                    type_,
+                    None,
+                );
             }
             _ => {
-                self.gl.tex_image_2d(texture.target,
-                                     0,
-                                     internal_format,
-                                     0,
-                                     0,
-                                     0,
-                                     gl_format,
-                                     type_,
-                                     None);
+                self.gl.tex_image_2d(
+                    texture.target,
+                    0,
+                    internal_format,
+                    0,
+                    0,
+                    0,
+                    gl_format,
+                    type_,
+                    None,
+                );
             }
         }
 
         if let Some(RBOId(depth_rb)) = texture.depth_rb.take() {
             self.gl.delete_renderbuffers(&[depth_rb]);
         }
 
         if !texture.fbo_ids.is_empty() {
-            let fbo_ids: Vec<_> = texture.fbo_ids.drain(..).map(|FBOId(fbo_id)| fbo_id).collect();
+            let fbo_ids: Vec<_> = texture
+                .fbo_ids
+                .drain(..)
+                .map(|FBOId(fbo_id)| fbo_id)
+                .collect();
             self.gl.delete_framebuffers(&fbo_ids[..]);
         }
 
         texture.format = ImageFormat::Invalid;
         texture.width = 0;
         texture.height = 0;
         texture.layer_count = 0;
     }
@@ -1267,79 +1328,84 @@ impl Device {
         texture.id = 0;
     }
 
     pub fn delete_program(&mut self, mut program: Program) {
         self.gl.delete_program(program.id);
         program.id = 0;
     }
 
-    pub fn create_program(&mut self,
-                          base_filename: &str,
-                          features: &str,
-                          descriptor: &VertexDescriptor) -> Result<Program, ShaderError> {
+    pub fn create_program(
+        &mut self,
+        base_filename: &str,
+        features: &str,
+        descriptor: &VertexDescriptor,
+    ) -> Result<Program, ShaderError> {
         debug_assert!(self.inside_frame);
 
         let gl_version_string = get_shader_version(&*self.gl);
 
-        let (vs_source, fs_source) = build_shader_strings(gl_version_string,
-                                                          features,
-                                                          base_filename,
-                                                          &self.resource_override_path);
+        let (vs_source, fs_source) = build_shader_strings(
+            gl_version_string,
+            features,
+            base_filename,
+            &self.resource_override_path,
+        );
 
         // Compile the vertex shader
-        let vs_id = match Device::compile_shader(&*self.gl,
-                                                 base_filename,
-                                                 gl::VERTEX_SHADER,
-                                                 vs_source) {
-            Ok(vs_id) => vs_id,
-            Err(err) => return Err(err),
-        };
+        let vs_id =
+            match Device::compile_shader(&*self.gl, base_filename, gl::VERTEX_SHADER, vs_source) {
+                Ok(vs_id) => vs_id,
+                Err(err) => return Err(err),
+            };
 
         // Compiler the fragment shader
-        let fs_id = match Device::compile_shader(&*self.gl,
-                                                 base_filename,
-                                                 gl::FRAGMENT_SHADER,
-                                                 fs_source) {
-            Ok(fs_id) => fs_id,
-            Err(err) => {
-                self.gl.delete_shader(vs_id);
-                return Err(err);
-            }
-        };
+        let fs_id =
+            match Device::compile_shader(&*self.gl, base_filename, gl::FRAGMENT_SHADER, fs_source) {
+                Ok(fs_id) => fs_id,
+                Err(err) => {
+                    self.gl.delete_shader(vs_id);
+                    return Err(err);
+                }
+            };
 
         // Create program and attach shaders
         let pid = self.gl.create_program();
         self.gl.attach_shader(pid, vs_id);
         self.gl.attach_shader(pid, fs_id);
 
         // Bind vertex attributes
-        for (i, attr) in descriptor.vertex_attributes
-                                   .iter()
-                                   .chain(descriptor.instance_attributes.iter())
-                                   .enumerate() {
-            self.gl.bind_attrib_location(pid,
-                                         i as gl::GLuint,
-                                         attr.name);
+        for (i, attr) in descriptor
+            .vertex_attributes
+            .iter()
+            .chain(descriptor.instance_attributes.iter())
+            .enumerate()
+        {
+            self.gl
+                .bind_attrib_location(pid, i as gl::GLuint, attr.name);
         }
 
         // Link!
         self.gl.link_program(pid);
 
         // GL recommends detaching and deleting shaders once the link
         // is complete (whether successful or not). This allows the driver
         // to free any memory associated with the parsing and compilation.
         self.gl.detach_shader(pid, vs_id);
         self.gl.detach_shader(pid, fs_id);
         self.gl.delete_shader(vs_id);
         self.gl.delete_shader(fs_id);
 
         if self.gl.get_program_iv(pid, gl::LINK_STATUS) == (0 as gl::GLint) {
             let error_log = self.gl.get_program_info_log(pid);
-            println!("Failed to link shader program: {:?}\n{}", base_filename, error_log);
+            println!(
+                "Failed to link shader program: {:?}\n{}",
+                base_filename,
+                error_log
+            );
             self.gl.delete_program(pid);
             return Err(ShaderError::Link(base_filename.to_string(), error_log));
         }
 
         let u_transform = self.gl.get_uniform_location(pid, "uTransform");
         let u_device_pixel_ratio = self.gl.get_uniform_location(pid, "uDevicePixelRatio");
 
         let program = Program {
@@ -1348,53 +1414,51 @@ impl Device {
             u_device_pixel_ratio,
         };
 
         self.bind_program(&program);
 
         Ok(program)
     }
 
-    pub fn bind_shader_samplers<S>(&mut self,
-                                   program: &Program,
-                                   bindings: &[(&'static str, S)]) where S: Into<TextureSlot> + Copy {
+    pub fn bind_shader_samplers<S>(&mut self, program: &Program, bindings: &[(&'static str, S)])
+    where
+        S: Into<TextureSlot> + Copy,
+    {
         for binding in bindings {
             let u_location = self.gl.get_uniform_location(program.id, binding.0);
             if u_location != -1 {
                 self.bind_program(program);
-                self.gl.uniform_1i(u_location, binding.1.into().0 as gl::GLint);
+                self.gl
+                    .uniform_1i(u_location, binding.1.into().0 as gl::GLint);
             }
         }
     }
 
     pub fn get_uniform_location(&self, program: &Program, name: &str) -> UniformLocation {
         UniformLocation(self.gl.get_uniform_location(program.id, name))
     }
 
     pub fn set_uniform_2f(&self, uniform: UniformLocation, x: f32, y: f32) {
         debug_assert!(self.inside_frame);
         let UniformLocation(location) = uniform;
         self.gl.uniform_2f(location, x, y);
     }
 
-    pub fn set_uniforms(&self,
-                        program: &Program,
-                        transform: &Transform3D<f32>) {
+    pub fn set_uniforms(&self, program: &Program, transform: &Transform3D<f32>) {
         debug_assert!(self.inside_frame);
-        self.gl.uniform_matrix_4fv(program.u_transform,
-                                   false,
-                                   &transform.to_row_major_array());
-        self.gl.uniform_1f(program.u_device_pixel_ratio, self.device_pixel_ratio);
+        self.gl
+            .uniform_matrix_4fv(program.u_transform, false, &transform.to_row_major_array());
+        self.gl
+            .uniform_1f(program.u_device_pixel_ratio, self.device_pixel_ratio);
     }
 
     pub fn create_pbo(&mut self) -> PBO {
         let id = self.gl.gen_buffers(1)[0];
-        PBO {
-            id
-        }
+        PBO { id }
     }
 
     pub fn delete_pbo(&mut self, mut pbo: PBO) {
         self.gl.delete_buffers(&[pbo.id]);
         pbo.id = 0;
     }
 
     pub fn bind_pbo(&mut self, pbo: Option<&PBO>) {
@@ -1407,41 +1471,42 @@ impl Device {
             self.gl.bind_buffer(gl::PIXEL_UNPACK_BUFFER, pbo_id);
         }
     }
 
     pub fn update_pbo_data<T>(&mut self, data: &[T]) {
         debug_assert!(self.inside_frame);
         debug_assert_ne!(self.bound_pbo, 0);
 
-        gl::buffer_data(&*self.gl,
-                        gl::PIXEL_UNPACK_BUFFER,
-                        data,
-                        gl::STREAM_DRAW);
+        gl::buffer_data(&*self.gl, gl::PIXEL_UNPACK_BUFFER, data, gl::STREAM_DRAW);
     }
 
     pub fn orphan_pbo(&mut self, new_size: usize) {
         debug_assert!(self.inside_frame);
         debug_assert_ne!(self.bound_pbo, 0);
 
-        self.gl.buffer_data_untyped(gl::PIXEL_UNPACK_BUFFER,
-                                    new_size as isize,
-                                    ptr::null(),
-                                    gl::STREAM_DRAW);
+        self.gl.buffer_data_untyped(
+            gl::PIXEL_UNPACK_BUFFER,
+            new_size as isize,
+            ptr::null(),
+            gl::STREAM_DRAW,
+        );
     }
 
-    pub fn update_texture_from_pbo(&mut self,
-                                   texture: &Texture,
-                                   x0: u32,
-                                   y0: u32,
-                                   width: u32,
-                                   height: u32,
-                                   layer_index: i32,
-                                   stride: Option<u32>,
-                                   offset: usize) {
+    pub fn update_texture_from_pbo(
+        &mut self,
+        texture: &Texture,
+        x0: u32,
+        y0: u32,
+        width: u32,
+        height: u32,
+        layer_index: i32,
+        stride: Option<u32>,
+        offset: usize,
+    ) {
         debug_assert!(self.inside_frame);
 
         let (gl_format, bpp, data_type) = match texture.format {
             ImageFormat::A8 => (GL_FORMAT_A, 1, gl::UNSIGNED_BYTE),
             ImageFormat::RGB8 => (gl::RGB, 3, gl::UNSIGNED_BYTE),
             ImageFormat::BGRA8 => (get_gl_format_bgra(self.gl()), 4, gl::UNSIGNED_BYTE),
             ImageFormat::RG8 => (gl::RG, 2, gl::UNSIGNED_BYTE),
             ImageFormat::RGBAF32 => (gl::RGBA, 16, gl::FLOAT),
@@ -1449,47 +1514,50 @@ impl Device {
         };
 
         let row_length = match stride {
             Some(value) => value / bpp,
             None => width,
         };
 
         if let Some(..) = stride {
-            self.gl.pixel_store_i(gl::UNPACK_ROW_LENGTH, row_length as gl::GLint);
+            self.gl
+                .pixel_store_i(gl::UNPACK_ROW_LENGTH, row_length as gl::GLint);
         }
 
         self.bind_texture(DEFAULT_TEXTURE, texture);
 
         match texture.target {
             gl::TEXTURE_2D_ARRAY => {
-                self.gl.tex_sub_image_3d_pbo(texture.target,
-                                             0,
-                                             x0 as gl::GLint,
-                                             y0 as gl::GLint,
-                                             layer_index,
-                                             width as gl::GLint,
-                                             height as gl::GLint,
-                                             1,
-                                             gl_format,
-                                             data_type,
-                                             offset);
+                self.gl.tex_sub_image_3d_pbo(
+                    texture.target,
+                    0,
+                    x0 as gl::GLint,
+                    y0 as gl::GLint,
+                    layer_index,
+                    width as gl::GLint,
+                    height as gl::GLint,
+                    1,
+                    gl_format,
+                    data_type,
+                    offset,
+                );
             }
-            gl::TEXTURE_2D |
-            gl::TEXTURE_RECTANGLE |
-            gl::TEXTURE_EXTERNAL_OES => {
-                self.gl.tex_sub_image_2d_pbo(texture.target,
-                                             0,
-                                             x0 as gl::GLint,
-                                             y0 as gl::GLint,
-                                             width as gl::GLint,
-                                             height as gl::GLint,
-                                             gl_format,
-                                             data_type,
-                                             offset);
+            gl::TEXTURE_2D | gl::TEXTURE_RECTANGLE | gl::TEXTURE_EXTERNAL_OES => {
+                self.gl.tex_sub_image_2d_pbo(
+                    texture.target,
+                    0,
+                    x0 as gl::GLint,
+                    y0 as gl::GLint,
+                    width as gl::GLint,
+                    height as gl::GLint,
+                    gl_format,
+                    data_type,
+                    offset,
+                );
             }
             _ => panic!("BUG: Unexpected texture target!"),
         }
 
         // Reset row length to 0, otherwise the stride would apply to all texture uploads.
         if let Some(..) = stride {
             self.gl.pixel_store_i(gl::UNPACK_ROW_LENGTH, 0 as gl::GLint);
         }
@@ -1499,23 +1567,24 @@ impl Device {
         debug_assert!(self.inside_frame);
 
         if self.bound_vao != vao.id {
             self.bound_vao = vao.id;
             self.gl.bind_vertex_array(vao.id);
         }
     }
 
-    fn create_vao_with_vbos(&mut self,
-                            descriptor: &VertexDescriptor,
-                            main_vbo_id: VBOId,
-                            instance_vbo_id: VBOId,
-                            ibo_id: IBOId,
-                            owns_vertices_and_indices: bool)
-                            -> VAO {
+    fn create_vao_with_vbos(
+        &mut self,
+        descriptor: &VertexDescriptor,
+        main_vbo_id: VBOId,
+        instance_vbo_id: VBOId,
+        ibo_id: IBOId,
+        owns_vertices_and_indices: bool,
+    ) -> VAO {
         debug_assert!(self.inside_frame);
 
         let instance_stride = descriptor.instance_stride();
         let vao_id = self.gl.gen_vertex_arrays(1)[0];
 
         self.gl.bind_vertex_array(vao_id);
 
         descriptor.bind(self.gl(), main_vbo_id, instance_vbo_id);
@@ -1530,146 +1599,155 @@ impl Device {
             owns_vertices_and_indices,
         };
 
         self.gl.bind_vertex_array(0);
 
         vao
     }
 
-    pub fn create_vao(&mut self,
-                      descriptor: &VertexDescriptor) -> VAO {
+    pub fn create_vao(&mut self, descriptor: &VertexDescriptor) -> VAO {
         debug_assert!(self.inside_frame);
 
         let buffer_ids = self.gl.gen_buffers(3);
         let ibo_id = IBOId(buffer_ids[0]);
         let main_vbo_id = VBOId(buffer_ids[1]);
         let intance_vbo_id = VBOId(buffer_ids[2]);
 
-        self.create_vao_with_vbos(descriptor,
-                                  main_vbo_id,
-                                  intance_vbo_id,
-                                  ibo_id,
-                                  true)
+        self.create_vao_with_vbos(descriptor, main_vbo_id, intance_vbo_id, ibo_id, true)
     }
 
     pub fn delete_vao(&mut self, mut vao: VAO) {
         self.gl.delete_vertex_arrays(&[vao.id]);
         vao.id = 0;
 
         if vao.owns_vertices_and_indices {
             self.gl.delete_buffers(&[vao.ibo_id.0]);
             self.gl.delete_buffers(&[vao.main_vbo_id.0]);
         }
 
         self.gl.delete_buffers(&[vao.instance_vbo_id.0])
     }
 
-    pub fn create_vao_with_new_instances(&mut self,
-                                         descriptor: &VertexDescriptor,
-                                         base_vao: &VAO) -> VAO {
+    pub fn create_vao_with_new_instances(
+        &mut self,
+        descriptor: &VertexDescriptor,
+        base_vao: &VAO,
+    ) -> VAO {
         debug_assert!(self.inside_frame);
 
         let buffer_ids = self.gl.gen_buffers(1);
         let intance_vbo_id = VBOId(buffer_ids[0]);
 
-        self.create_vao_with_vbos(descriptor,
-                                  base_vao.main_vbo_id,
-                                  intance_vbo_id,
-                                  base_vao.ibo_id,
-                                  false)
+        self.create_vao_with_vbos(
+            descriptor,
+            base_vao.main_vbo_id,
+            intance_vbo_id,
+            base_vao.ibo_id,
+            false,
+        )
     }
 
-    pub fn update_vao_main_vertices<V>(&mut self,
-                                       vao: &VAO,
-                                       vertices: &[V],
-                                       usage_hint: VertexUsageHint) {
+    pub fn update_vao_main_vertices<V>(
+        &mut self,
+        vao: &VAO,
+        vertices: &[V],
+        usage_hint: VertexUsageHint,
+    ) {
         debug_assert!(self.inside_frame);
         debug_assert_eq!(self.bound_vao, vao.id);
 
         vao.main_vbo_id.bind(self.gl());
         gl::buffer_data(self.gl(), gl::ARRAY_BUFFER, vertices, usage_hint.to_gl());
     }
 
-    pub fn update_vao_instances<V>(&mut self,
-                                   vao: &VAO,
-                                   instances: &[V],
-                                   usage_hint: VertexUsageHint) {
+    pub fn update_vao_instances<V>(
+        &mut self,
+        vao: &VAO,
+        instances: &[V],
+        usage_hint: VertexUsageHint,
+    ) {
         debug_assert!(self.inside_frame);
         debug_assert_eq!(self.bound_vao, vao.id);
         debug_assert_eq!(vao.instance_stride as usize, mem::size_of::<V>());
 
         vao.instance_vbo_id.bind(self.gl());
         gl::buffer_data(self.gl(), gl::ARRAY_BUFFER, instances, usage_hint.to_gl());
     }
 
-    pub fn update_vao_indices<I>(&mut self,
-                                 vao: &VAO,
-                                 indices: &[I],
-                                 usage_hint: VertexUsageHint) {
+    pub fn update_vao_indices<I>(&mut self, vao: &VAO, indices: &[I], usage_hint: VertexUsageHint) {
         debug_assert!(self.inside_frame);
         debug_assert_eq!(self.bound_vao, vao.id);
 
         vao.ibo_id.bind(self.gl());
-        gl::buffer_data(self.gl(), gl::ELEMENT_ARRAY_BUFFER, indices, usage_hint.to_gl());
+        gl::buffer_data(
+            self.gl(),
+            gl::ELEMENT_ARRAY_BUFFER,
+            indices,
+            usage_hint.to_gl(),
+        );
     }
 
     pub fn draw_triangles_u16(&mut self, first_vertex: i32, index_count: i32) {
         debug_assert!(self.inside_frame);
-        self.gl.draw_elements(gl::TRIANGLES,
-                               index_count,
-                               gl::UNSIGNED_SHORT,
-                               first_vertex as u32 * 2);
+        self.gl.draw_elements(
+            gl::TRIANGLES,
+            index_count,
+            gl::UNSIGNED_SHORT,
+            first_vertex as u32 * 2,
+        );
     }
 
     pub fn draw_triangles_u32(&mut self, first_vertex: i32, index_count: i32) {
         debug_assert!(self.inside_frame);
-        self.gl.draw_elements(gl::TRIANGLES,
-                               index_count,
-                               gl::UNSIGNED_INT,
-                               first_vertex as u32 * 4);
+        self.gl.draw_elements(
+            gl::TRIANGLES,
+            index_count,
+            gl::UNSIGNED_INT,
+            first_vertex as u32 * 4,
+        );
     }
 
     pub fn draw_nonindexed_lines(&mut self, first_vertex: i32, vertex_count: i32) {
         debug_assert!(self.inside_frame);
-        self.gl.draw_arrays(gl::LINES,
-                             first_vertex,
-                             vertex_count);
+        self.gl.draw_arrays(gl::LINES, first_vertex, vertex_count);
     }
 
-    pub fn draw_indexed_triangles_instanced_u16(&mut self,
-                                                index_count: i32,
-                                                instance_count: i32) {
+    pub fn draw_indexed_triangles_instanced_u16(&mut self, index_count: i32, instance_count: i32) {
         debug_assert!(self.inside_frame);
-        self.gl.draw_elements_instanced(gl::TRIANGLES, index_count, gl::UNSIGNED_SHORT, 0, instance_count);
+        self.gl.draw_elements_instanced(
+            gl::TRIANGLES,
+            index_count,
+            gl::UNSIGNED_SHORT,
+            0,
+            instance_count,
+        );
     }
 
     pub fn end_frame(&mut self) {
         self.bind_draw_target(None, None);
         self.bind_read_target(None);
 
         debug_assert!(self.inside_frame);
         self.inside_frame = false;
 
         self.gl.bind_texture(gl::TEXTURE_2D, 0);
         self.gl.use_program(0);
 
-        for i in 0..self.bound_textures.len() {
+        for i in 0 .. self.bound_textures.len() {
             self.gl.active_texture(gl::TEXTURE0 + i as gl::GLuint);
             self.gl.bind_texture(gl::TEXTURE_2D, 0);
         }
 
         self.gl.active_texture(gl::TEXTURE0);
 
         self.frame_id.0 += 1;
     }
 
-    pub fn clear_target(&self,
-                        color: Option<[f32; 4]>,
-                        depth: Option<f32>) {
+    pub fn clear_target(&self, color: Option<[f32; 4]>, depth: Option<f32>) {
         let mut clear_bits = 0;
 
         if let Some(color) = color {
             self.gl.clear_color(color[0], color[1], color[2], color[3]);
             clear_bits |= gl::COLOR_BUFFER_BIT;
         }
 
         if let Some(depth) = depth {
@@ -1677,35 +1755,42 @@ impl Device {
             clear_bits |= gl::DEPTH_BUFFER_BIT;
         }
 
         if clear_bits != 0 {
             self.gl.clear(clear_bits);
         }
     }
 
-    pub fn clear_target_rect(&self,
-                             color: Option<[f32; 4]>,
-                             depth: Option<f32>,
-                             rect: DeviceIntRect) {
+    pub fn clear_target_rect(
+        &self,
+        color: Option<[f32; 4]>,
+        depth: Option<f32>,
+        rect: DeviceIntRect,
+    ) {
         let mut clear_bits = 0;
 
         if let Some(color) = color {
             self.gl.clear_color(color[0], color[1], color[2], color[3]);
             clear_bits |= gl::COLOR_BUFFER_BIT;
         }
 
         if let Some(depth) = depth {
             self.gl.clear_depth(depth as f64);
             clear_bits |= gl::DEPTH_BUFFER_BIT;
         }
 
         if clear_bits != 0 {
             self.gl.enable(gl::SCISSOR_TEST);
-            self.gl.scissor(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
+            self.gl.scissor(
+                rect.origin.x,
+                rect.origin.y,
+                rect.size.width,
+                rect.size.height,
+            );
             self.gl.clear(clear_bits);
             self.gl.disable(gl::SCISSOR_TEST);
         }
     }
 
     pub fn enable_depth(&self) {
         self.gl.enable(gl::DEPTH_TEST);
     }
@@ -1743,69 +1828,68 @@ impl Device {
     }
 
     pub fn set_blend_mode_premultiplied_alpha(&self) {
         self.gl.blend_func(gl::ONE, gl::ONE_MINUS_SRC_ALPHA);
         self.gl.blend_equation(gl::FUNC_ADD);
     }
 
     pub fn set_blend_mode_alpha(&self) {
-        self.gl.blend_func_separate(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA,
-                                    gl::ONE, gl::ONE_MINUS_SRC_ALPHA);
+        self.gl.blend_func_separate(
+            gl::SRC_ALPHA,
+            gl::ONE_MINUS_SRC_ALPHA,
+            gl::ONE,
+            gl::ONE_MINUS_SRC_ALPHA,
+        );
         self.gl.blend_equation(gl::FUNC_ADD);
     }
 
     pub fn set_blend_mode_subpixel(&self, color: ColorF) {
         self.gl.blend_color(color.r, color.g, color.b, color.a);
-        self.gl.blend_func(gl::CONSTANT_COLOR, gl::ONE_MINUS_SRC_COLOR);
+        self.gl
+            .blend_func(gl::CONSTANT_COLOR, gl::ONE_MINUS_SRC_COLOR);
     }
 
     pub fn set_blend_mode_multiply(&self) {
-        self.gl.blend_func_separate(gl::ZERO, gl::SRC_COLOR,
-                                     gl::ZERO, gl::SRC_ALPHA);
+        self.gl
+            .blend_func_separate(gl::ZERO, gl::SRC_COLOR, gl::ZERO, gl::SRC_ALPHA);
         self.gl.blend_equation(gl::FUNC_ADD);
     }
     pub fn set_blend_mode_max(&self) {
-        self.gl.blend_func_separate(gl::ONE, gl::ONE,
-                                     gl::ONE, gl::ONE);
+        self.gl
+            .blend_func_separate(gl::ONE, gl::ONE, gl::ONE, gl::ONE);
         self.gl.blend_equation_separate(gl::MAX, gl::FUNC_ADD);
     }
     pub fn set_blend_mode_min(&self) {
-        self.gl.blend_func_separate(gl::ONE, gl::ONE,
-                                     gl::ONE, gl::ONE);
+        self.gl
+            .blend_func_separate(gl::ONE, gl::ONE, gl::ONE, gl::ONE);
         self.gl.blend_equation_separate(gl::MIN, gl::FUNC_ADD);
     }
 }
 
 /// return (gl_internal_format, gl_format)
-fn gl_texture_formats_for_image_format(gl: &gl::Gl, format: ImageFormat) -> (gl::GLint, gl::GLuint) {
+fn gl_texture_formats_for_image_format(
+    gl: &gl::Gl,
+    format: ImageFormat,
+) -> (gl::GLint, gl::GLuint) {
     match format {
-        ImageFormat::A8 => {
-            if cfg!(any(target_arch="arm", target_arch="aarch64")) {
-                (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl))
-            } else {
-                (GL_FORMAT_A as gl::GLint, GL_FORMAT_A)
-            }
+        ImageFormat::A8 => if cfg!(any(target_arch = "arm", target_arch = "aarch64")) {
+            (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl))
+        } else {
+            (GL_FORMAT_A as gl::GLint, GL_FORMAT_A)
         },
         ImageFormat::RGB8 => (gl::RGB as gl::GLint, gl::RGB),
-        ImageFormat::BGRA8 => {
-            match gl.get_type() {
-                gl::GlType::Gl =>  {
-                    (gl::RGBA as gl::GLint, get_gl_format_bgra(gl))
-                }
-                gl::GlType::Gles => {
-                    (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl))
-                }
-            }
-        }
+        ImageFormat::BGRA8 => match gl.get_type() {
+            gl::GlType::Gl => (gl::RGBA as gl::GLint, get_gl_format_bgra(gl)),
+            gl::GlType::Gles => (get_gl_format_bgra(gl) as gl::GLint, get_gl_format_bgra(gl)),
+        },
         ImageFormat::RGBAF32 => (gl::RGBA32F as gl::GLint, gl::RGBA),
         ImageFormat::RG8 => (gl::RG8 as gl::GLint, gl::RG),
         ImageFormat::Invalid => unreachable!(),
     }
 }
 
 fn gl_type_for_texture_format(format: ImageFormat) -> gl::GLuint {
     match format {
         ImageFormat::RGBAF32 => gl::FLOAT,
         _ => gl::UNSIGNED_BYTE,
     }
 }
-
--- a/gfx/webrender/src/ellipse.rs
+++ b/gfx/webrender/src/ellipse.rs
@@ -13,19 +13,17 @@ const STEP_COUNT: usize = 20;
 pub struct Ellipse {
     pub radius: LayerSize,
     pub total_arc_length: f32,
 }
 
 impl Ellipse {
     pub fn new(radius: LayerSize) -> Ellipse {
         // Approximate the total length of the first quadrant of this ellipse.
-        let total_arc_length = get_simpson_length(FRAC_PI_2,
-                                                  radius.width,
-                                                  radius.height);
+        let total_arc_length = get_simpson_length(FRAC_PI_2, radius.width, radius.height);
 
         Ellipse {
             radius,
             total_arc_length,
         }
     }
 
     /// Binary search to estimate the angle of an ellipse
@@ -37,19 +35,17 @@ impl Ellipse {
 
         let epsilon = 0.01;
         let mut low = 0.0;
         let mut high = FRAC_PI_2;
         let mut theta = 0.0;
 
         while low <= high {
             theta = 0.5 * (low + high);
-            let length = get_simpson_length(theta,
-                                            self.radius.width,
-                                            self.radius.height);
+            let length = get_simpson_length(theta, self.radius.width, self.radius.height);
 
             if (length - arc_length).abs() < epsilon {
                 break;
             } else if length < arc_length {
                 low = theta;
             } else {
                 high = theta;
             }
@@ -57,39 +53,43 @@ impl Ellipse {
 
         theta
     }
 
     /// Get a point and tangent on this ellipse from a given angle.
     /// This only works for the first quadrant of the ellipse.
     pub fn get_point_and_tangent(&self, theta: f32) -> (LayerPoint, LayerPoint) {
         let (sin_theta, cos_theta) = theta.sin_cos();
-        let point = LayerPoint::new(self.radius.width * cos_theta,
-                                    self.radius.height * sin_theta);
-        let tangent = LayerPoint::new(-self.radius.width * sin_theta,
-                                       self.radius.height * cos_theta);
+        let point = LayerPoint::new(
+            self.radius.width * cos_theta,
+            self.radius.height * sin_theta,
+        );
+        let tangent = LayerPoint::new(
+            -self.radius.width * sin_theta,
+            self.radius.height * cos_theta,
+        );
         (point, tangent)
     }
 }
 
 /// Use Simpsons rule to approximate the arc length of
 /// part of an ellipse. Note that this only works over
 /// the range of [0, pi/2].
 // TODO(gw): This is a simplistic way to estimate the
 // arc length of an ellipse segment. We can probably use
 // a faster / more accurate method!
 fn get_simpson_length(theta: f32, rx: f32, ry: f32) -> f32 {
     let df = theta / STEP_COUNT as f32;
     let mut sum = 0.0;
 
-    for i in 0..(STEP_COUNT+1) {
+    for i in 0 .. (STEP_COUNT + 1) {
         let (sin_theta, cos_theta) = (i as f32 * df).sin_cos();
         let a = rx * sin_theta;
         let b = ry * cos_theta;
-        let y = (a*a + b*b).sqrt();
+        let y = (a * a + b * b).sqrt();
         let q = if i == 0 || i == STEP_COUNT {
             1.0
         } else if i % 2 == 0 {
             2.0
         } else {
             4.0
         };
 
--- a/gfx/webrender/src/frame.rs
+++ b/gfx/webrender/src/frame.rs
@@ -1,35 +1,41 @@
 /* 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 api::{BuiltDisplayList, BuiltDisplayListIter, ClipAndScrollInfo, ClipId, ColorF};
 use api::{ComplexClipRegion, DeviceUintRect, DeviceUintSize, DisplayItemRef, Epoch, FilterOp};
-use api::{ImageDisplayItem, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize, LayerToScrollTransform};
+use api::{ImageDisplayItem, ItemRange, LayerPoint, LayerPrimitiveInfo, LayerRect, LayerSize,
+          LayerToScrollTransform};
 use api::{LayerVector2D, LayoutSize, LayoutTransform, LocalClip, MixBlendMode, PipelineId};
 use api::{PropertyBinding, ScrollClamping, ScrollEventPhase, ScrollLayerState, ScrollLocation};
 use api::{ScrollPolicy, ScrollSensitivity, SpecificDisplayItem, StackingContext, TileOffset};
 use api::{TransformStyle, WorldPoint};
 use clip::ClipRegion;
 use clip_scroll_tree::{ClipScrollTree, ScrollStates};
 use euclid::rect;
+use frame_builder::{FrameBuilder, FrameBuilderConfig};
 use gpu_cache::GpuCache;
 use internal_types::{FastHashMap, FastHashSet, RendererFrame};
-use frame_builder::{FrameBuilder, FrameBuilderConfig};
 use profiler::{GpuCacheProfileCounters, TextureCacheProfileCounters};
 use resource_cache::{ResourceCache, TiledImageMap};
 use scene::{Scene, SceneProperties};
 use tiling::{CompositeOps, DisplayListMap, PrimitiveFlags};
-use util::{ComplexClipRegionHelpers, subtract_rect};
+use util::{subtract_rect, ComplexClipRegionHelpers};
 
 #[derive(Copy, Clone, PartialEq, PartialOrd, Debug, Eq, Ord)]
 pub struct FrameId(pub u32);
 
-static DEFAULT_SCROLLBAR_COLOR: ColorF = ColorF { r: 0.3, g: 0.3, b: 0.3, a: 0.6 };
+static DEFAULT_SCROLLBAR_COLOR: ColorF = ColorF {
+    r: 0.3,
+    g: 0.3,
+    b: 0.3,
+    a: 0.6,
+};
 
 /// Nested display lists cause two types of replacements to ClipIds inside the nesting:
 ///     1. References to the root scroll frame are replaced by the ClipIds that
 ///        contained the nested display list.
 ///     2. Other ClipIds (that aren't custom or reference frames) are assumed to be
 ///        local to the nested display list and are converted to an id that is unique
 ///        outside of the nested display list as well.
 ///
@@ -98,20 +104,21 @@ struct FlattenContext<'a> {
     resource_cache: &'a ResourceCache,
     tiled_image_map: TiledImageMap,
     replacements: Vec<(ClipId, ClipId)>,
     nested_display_list_info: Vec<NestedDisplayListInfo>,
     current_nested_display_list_index: u64,
 }
 
 impl<'a> FlattenContext<'a> {
-    fn new(scene: &'a Scene,
-           builder: &'a mut FrameBuilder,
-           resource_cache: &'a ResourceCache)
-           -> FlattenContext<'a> {
+    fn new(
+        scene: &'a Scene,
+        builder: &'a mut FrameBuilder,
+        resource_cache: &'a ResourceCache,
+    ) -> FlattenContext<'a> {
         FlattenContext {
             scene,
             builder,
             resource_cache,
             tiled_image_map: resource_cache.get_tiled_image_map(),
             replacements: Vec::new(),
             nested_display_list_info: Vec::new(),
             current_nested_display_list_index: 0,
@@ -137,51 +144,56 @@ impl<'a> FlattenContext<'a> {
         } else {
             *id
         }
     }
 
     fn convert_clip_scroll_info_to_nested(&self, info: &mut ClipAndScrollInfo) {
         if let Some(nested_info) = self.nested_display_list_info.last() {
             info.scroll_node_id = nested_info.convert_scroll_id_to_nested(&info.scroll_node_id);
-            info.clip_node_id =
-                info.clip_node_id.map(|ref id| nested_info.convert_clip_id_to_nested(id));
+            info.clip_node_id = info.clip_node_id
+                .map(|ref id| nested_info.convert_clip_id_to_nested(id));
         }
 
         // We only want to produce nested ClipIds if we are in a nested display
         // list situation.
-        debug_assert!(!info.scroll_node_id.is_nested() ||
-                      !self.nested_display_list_info.is_empty());
-        debug_assert!(!info.clip_node_id().is_nested() ||
-                      !self.nested_display_list_info.is_empty());
+        debug_assert!(
+            !info.scroll_node_id.is_nested() || !self.nested_display_list_info.is_empty()
+        );
+        debug_assert!(
+            !info.clip_node_id().is_nested() || !self.nested_display_list_info.is_empty()
+        );
     }
 
     /// Since WebRender still handles fixed position and reference frame content internally
     /// we need to apply this table of id replacements only to the id that affects the
     /// position of a node. We can eventually remove this when clients start handling
     /// reference frames themselves. This method applies these replacements.
     fn apply_scroll_frame_id_replacement(&self, id: ClipId) -> ClipId {
         match self.replacements.last() {
             Some(&(to_replace, replacement)) if to_replace == id => replacement,
             _ => id,
         }
     }
 
-    fn get_complex_clips(&self,
-                         pipeline_id: PipelineId,
-                         complex_clips: ItemRange<ComplexClipRegion>)
-                         -> Vec<ComplexClipRegion> {
+    fn get_complex_clips(
+        &self,
+        pipeline_id: PipelineId,
+        complex_clips: ItemRange<ComplexClipRegion>,
+    ) -> Vec<ComplexClipRegion> {
         if complex_clips.is_empty() {
             return vec![];
         }
 
-        self.scene.display_lists.get(&pipeline_id)
-                                .expect("No display list?")
-                                .get(complex_clips)
-                                .collect()
+        self.scene
+            .display_lists
+            .get(&pipeline_id)
+            .expect("No display list?")
+            .get(complex_clips)
+            .collect()
     }
 }
 
 // TODO: doc
 pub struct Frame {
     pub clip_scroll_tree: ClipScrollTree,
     pub pipeline_epoch_map: FastHashMap<PipelineId, Epoch>,
     id: FrameId,
@@ -196,64 +208,64 @@ trait FilterOpHelpers {
 
 impl FilterOpHelpers for FilterOp {
     fn resolve(self, properties: &SceneProperties) -> FilterOp {
         match self {
             FilterOp::Opacity(ref value) => {
                 let amount = properties.resolve_float(value, 1.0);
                 FilterOp::Opacity(PropertyBinding::Value(amount))
             }
-            _ => self
+            _ => self,
         }
     }
 
     fn is_noop(&self) -> bool {
         match *self {
             FilterOp::Blur(length) => length == 0.0,
             FilterOp::Brightness(amount) => amount == 1.0,
             FilterOp::Contrast(amount) => amount == 1.0,
             FilterOp::Grayscale(amount) => amount == 0.0,
             FilterOp::HueRotate(amount) => amount == 0.0,
             FilterOp::Invert(amount) => amount == 0.0,
-            FilterOp::Opacity(value) => {
-                match value {
-                    PropertyBinding::Value(amount) => {
-                        amount == 1.0
-                    }
-                    PropertyBinding::Binding(..) => {
-                        panic!("bug: binding value should be resolved");
-                    }
+            FilterOp::Opacity(value) => match value {
+                PropertyBinding::Value(amount) => amount == 1.0,
+                PropertyBinding::Binding(..) => {
+                    panic!("bug: binding value should be resolved");
                 }
-            }
+            },
             FilterOp::Saturate(amount) => amount == 1.0,
             FilterOp::Sepia(amount) => amount == 0.0,
         }
     }
 }
 
 trait StackingContextHelpers {
     fn mix_blend_mode_for_compositing(&self) -> Option<MixBlendMode>;
-    fn filter_ops_for_compositing(&self,
-                                  display_list: &BuiltDisplayList,
-                                  input_filters: ItemRange<FilterOp>,
-                                  properties: &SceneProperties) -> Vec<FilterOp>;
+    fn filter_ops_for_compositing(
+        &self,
+        display_list: &BuiltDisplayList,
+        input_filters: ItemRange<FilterOp>,
+        properties: &SceneProperties,
+    ) -> Vec<FilterOp>;
 }
 
 impl StackingContextHelpers for StackingContext {
     fn mix_blend_mode_for_compositing(&self) -> Option<MixBlendMode> {
         match self.mix_blend_mode {
             MixBlendMode::Normal => None,
             _ => Some(self.mix_blend_mode),
         }
     }
 
-    fn filter_ops_for_compositing(&self,
-                                  display_list: &BuiltDisplayList,
-                                  input_filters: ItemRange<FilterOp>,
-                                  properties: &SceneProperties) -> Vec<FilterOp> {
+    fn filter_ops_for_compositing(
+        &self,
+        display_list: &BuiltDisplayList,
+        input_filters: ItemRange<FilterOp>,
+        properties: &SceneProperties,
+    ) -> Vec<FilterOp> {
         let mut filters = vec![];
         for filter in display_list.get(input_filters) {
             let filter = filter.resolve(properties);
             if filter.is_noop() {
                 continue;
             }
             filters.push(filter);
         }
@@ -286,38 +298,42 @@ impl Frame {
     }
 
     /// Returns true if the node actually changed position or false otherwise.
     pub fn scroll_node(&mut self, origin: LayerPoint, id: ClipId, clamp: ScrollClamping) -> bool {
         self.clip_scroll_tree.scroll_node(origin, id, clamp)
     }
 
     /// Returns true if any nodes actually changed position or false otherwise.
-    pub fn scroll(&mut self,
-                  scroll_location: ScrollLocation,
-                  cursor: WorldPoint,
-                  phase: ScrollEventPhase)
-                  -> bool {
-        self.clip_scroll_tree.scroll(scroll_location, cursor, phase,)
+    pub fn scroll(
+        &mut self,
+        scroll_location: ScrollLocation,
+        cursor: WorldPoint,
+        phase: ScrollEventPhase,
+    ) -> bool {
+        self.clip_scroll_tree.scroll(scroll_location, cursor, phase)
     }
 
     pub fn tick_scrolling_bounce_animations(&mut self) {
         self.clip_scroll_tree.tick_scrolling_bounce_animations();
     }
 
     pub fn discard_frame_state_for_pipeline(&mut self, pipeline_id: PipelineId) {
-        self.clip_scroll_tree.discard_frame_state_for_pipeline(pipeline_id);
+        self.clip_scroll_tree
+            .discard_frame_state_for_pipeline(pipeline_id);
     }
 
-    pub fn create(&mut self,
-                  scene: &Scene,
-                  resource_cache: &mut ResourceCache,
-                  window_size: DeviceUintSize,
-                  inner_rect: DeviceUintRect,
-                  device_pixel_ratio: f32) {
+    pub fn create(
+        &mut self,
+        scene: &Scene,
+        resource_cache: &mut ResourceCache,
+        window_size: DeviceUintSize,
+        inner_rect: DeviceUintRect,
+        device_pixel_ratio: f32,
+    ) {
         let root_pipeline_id = match scene.root_pipeline_id {
             Some(root_pipeline_id) => root_pipeline_id,
             None => return,
         };
 
         let root_pipeline = match scene.pipeline_map.get(&root_pipeline_id) {
             Some(root_pipeline) => root_pipeline,
             None => return,
@@ -329,578 +345,670 @@ impl Frame {
         };
 
         if window_size.width == 0 || window_size.height == 0 {
             error!("ERROR: Invalid window dimensions! Please call api.set_window_size()");
         }
 
         let old_scrolling_states = self.reset();
 
-        self.pipeline_epoch_map.insert(root_pipeline_id, root_pipeline.epoch);
+        self.pipeline_epoch_map
+            .insert(root_pipeline_id, root_pipeline.epoch);
+
+        let background_color = root_pipeline
+            .background_color
+            .and_then(|color| if color.a > 0.0 { Some(color) } else { None });
 
-        let background_color = root_pipeline.background_color.and_then(|color| {
-            if color.a > 0.0 {
-                Some(color)
-            } else {
-                None
-            }
-        });
-
-        let mut frame_builder = FrameBuilder::new(self.frame_builder.take(),
-                                                  window_size,
-                                                  background_color,
-                                                  self.frame_builder_config);
+        let mut frame_builder = FrameBuilder::new(
+            self.frame_builder.take(),
+            window_size,
+            background_color,
+            self.frame_builder_config,
+        );
 
         {
             let mut context = FlattenContext::new(scene, &mut frame_builder, resource_cache);
 
-            context.builder.push_root(root_pipeline_id,
-                                      &root_pipeline.viewport_size,
-                                      &root_pipeline.content_size,
-                                      &mut self.clip_scroll_tree);
+            context.builder.push_root(
+                root_pipeline_id,
+                &root_pipeline.viewport_size,
+                &root_pipeline.content_size,
+                &mut self.clip_scroll_tree,
+            );
 
-            context.builder.setup_viewport_offset(window_size,
-                                                  inner_rect,
-                                                  device_pixel_ratio,
-                                                  &mut self.clip_scroll_tree);
+            context.builder.setup_viewport_offset(
+                window_size,
+                inner_rect,
+                device_pixel_ratio,
+                &mut self.clip_scroll_tree,
+            );
 
-            self.flatten_root(&mut display_list.iter(),
-                              root_pipeline_id,
-                              &mut context,
-                              &root_pipeline.content_size);
+            self.flatten_root(
+                &mut display_list.iter(),
+                root_pipeline_id,
+                &mut context,
+                &root_pipeline.content_size,
+            );
         }
 
         self.frame_builder = Some(frame_builder);
-        self.clip_scroll_tree.finalize_and_apply_pending_scroll_offsets(old_scrolling_states);
+        self.clip_scroll_tree
+            .finalize_and_apply_pending_scroll_offsets(old_scrolling_states);
     }
 
-    fn flatten_clip<'a>(&mut self,
-                        context: &mut FlattenContext,
-                        pipeline_id: PipelineId,
-                        parent_id: &ClipId,
-                        new_clip_id: &ClipId,
-                        clip_region: ClipRegion) {
+    fn flatten_clip<'a>(
+        &mut self,
+        context: &mut FlattenContext,
+        pipeline_id: PipelineId,
+        parent_id: &ClipId,
+        new_clip_id: &ClipId,
+        clip_region: ClipRegion,
+    ) {
         let new_clip_id = context.convert_new_id_to_nested(new_clip_id);
-        context.builder.add_clip_node(new_clip_id,
-                                      *parent_id,
-                                      pipeline_id,
-                                      clip_region,
-                                      &mut self.clip_scroll_tree);
+        context.builder.add_clip_node(
+            new_clip_id,
+            *parent_id,
+            pipeline_id,
+            clip_region,
+            &mut self.clip_scroll_tree,
+        );
     }
 
-    fn flatten_scroll_frame<'a>(&mut self,
-                                context: &mut FlattenContext,
-                                pipeline_id: PipelineId,
-                                parent_id: &ClipId,
-                                new_scroll_frame_id: &ClipId,
-                                frame_rect: &LayerRect,
-                                content_rect: &LayerRect,
-                                clip_region: ClipRegion,
-                                scroll_sensitivity: ScrollSensitivity) {
+    fn flatten_scroll_frame<'a>(
+        &mut self,
+        context: &mut FlattenContext,
+        pipeline_id: PipelineId,
+        parent_id: &ClipId,
+        new_scroll_frame_id: &ClipId,
+        frame_rect: &LayerRect,
+        content_rect: &LayerRect,
+        clip_region: ClipRegion,
+        scroll_sensitivity: ScrollSensitivity,
+    ) {
         let clip_id = self.clip_scroll_tree.generate_new_clip_id(pipeline_id);
-        context.builder.add_clip_node(clip_id,
-                                      *parent_id,
-                                      pipeline_id,
-                                      clip_region,
-                                      &mut self.clip_scroll_tree);
+        context.builder.add_clip_node(
+            clip_id,
+            *parent_id,
+            pipeline_id,
+            clip_region,
+            &mut self.clip_scroll_tree,
+        );
 
         let new_scroll_frame_id = context.convert_new_id_to_nested(new_scroll_frame_id);
-        context.builder.add_scroll_frame(new_scroll_frame_id,
-                                         clip_id,
-                                         pipeline_id,
-                                         &frame_rect,
-                                         &content_rect.size,
-                                         scroll_sensitivity,
-                                         &mut self.clip_scroll_tree);
+        context.builder.add_scroll_frame(
+            new_scroll_frame_id,
+            clip_id,
+            pipeline_id,
+            &frame_rect,
+            &content_rect.size,
+            scroll_sensitivity,
+            &mut self.clip_scroll_tree,
+        );
     }
 
-    fn flatten_stacking_context<'a>(&mut self,
-                                    traversal: &mut BuiltDisplayListIter<'a>,
-                                    pipeline_id: PipelineId,
-                                    context: &mut FlattenContext,
-                                    context_scroll_node_id: ClipId,
-                                    mut reference_frame_relative_offset: LayerVector2D,
-                                    bounds: &LayerRect,
-                                    stacking_context: &StackingContext,
-                                    filters: ItemRange<FilterOp>,
-                                    is_backface_visible: bool) {
+    fn flatten_stacking_context<'a>(
+        &mut self,
+        traversal: &mut BuiltDisplayListIter<'a>,
+        pipeline_id: PipelineId,
+        context: &mut FlattenContext,
+        context_scroll_node_id: ClipId,
+        mut reference_frame_relative_offset: LayerVector2D,
+        bounds: &LayerRect,
+        stacking_context: &StackingContext,
+        filters: ItemRange<FilterOp>,
+        is_backface_visible: bool,
+    ) {
         // Avoid doing unnecessary work for empty stacking contexts.
         if traversal.current_stacking_context_empty() {
             traversal.skip_current_stacking_context();
             return;
         }
 
         let composition_operations = {
             // TODO(optimization?): self.traversal.display_list()
-            let display_list = context.scene.display_lists
-                                      .get(&pipeline_id)
-                                      .expect("No display list?!");
+            let display_list = context
+                .scene
+                .display_lists
+                .get(&pipeline_id)
+                .expect("No display list?!");
             CompositeOps::new(
-                stacking_context.filter_ops_for_compositing(display_list, filters, &context.scene.properties),
-                stacking_context.mix_blend_mode_for_compositing())
+                stacking_context.filter_ops_for_compositing(
+                    display_list,
+                    filters,
+                    &context.scene.properties,
+                ),
+                stacking_context.mix_blend_mode_for_compositing(),
+            )
         };
 
         if stacking_context.scroll_policy == ScrollPolicy::Fixed {
-            context.replacements.push((context_scroll_node_id,
-                                       context.builder.current_reference_frame_id()));
+            context.replacements.push((
+                context_scroll_node_id,
+                context.builder.current_reference_frame_id(),
+            ));
         }
 
         // If we have a transformation, we establish a new reference frame. This means
         // that fixed position stacking contexts are positioned relative to us.
-        let is_reference_frame = stacking_context.transform.is_some() ||
-                                 stacking_context.perspective.is_some();
+        let is_reference_frame =
+            stacking_context.transform.is_some() || stacking_context.perspective.is_some();
         if is_reference_frame {
             let transform = stacking_context.transform.as_ref();
             let transform = context.scene.properties.resolve_layout_transform(transform);
-            let perspective =
-                stacking_context.perspective.unwrap_or_else(LayoutTransform::identity);
+            let perspective = stacking_context
+                .perspective
+                .unwrap_or_else(LayoutTransform::identity);
             let origin = reference_frame_relative_offset + bounds.origin.to_vector();
-            let transform =
-                LayerToScrollTransform::create_translation(origin.x, origin.y, 0.0)
-                                        .pre_mul(&transform)
-                                        .pre_mul(&perspective);
+            let transform = LayerToScrollTransform::create_translation(origin.x, origin.y, 0.0)
+                .pre_mul(&transform)
+                .pre_mul(&perspective);
 
             let reference_frame_bounds = LayerRect::new(LayerPoint::zero(), bounds.size);
             let mut clip_id = context.apply_scroll_frame_id_replacement(context_scroll_node_id);
-            clip_id = context.builder.push_reference_frame(Some(clip_id),
-                                                           pipeline_id,
-                                                           &reference_frame_bounds,
-                                                           &transform,
-                                                           origin,
-                                                           &mut self.clip_scroll_tree);
+            clip_id = context.builder.push_reference_frame(
+                Some(clip_id),
+                pipeline_id,
+                &reference_frame_bounds,
+                &transform,
+                origin,
+                &mut self.clip_scroll_tree,
+            );
             context.replacements.push((context_scroll_node_id, clip_id));
             reference_frame_relative_offset = LayerVector2D::zero();
         } else {
             reference_frame_relative_offset = LayerVector2D::new(
                 reference_frame_relative_offset.x + bounds.origin.x,
-                reference_frame_relative_offset.y + bounds.origin.y);
+                reference_frame_relative_offset.y + bounds.origin.y,
+            );
         }
 
-        context.builder.push_stacking_context(&reference_frame_relative_offset,
-                                              pipeline_id,
-                                              composition_operations,
-                                              stacking_context.transform_style,
-                                              is_backface_visible,
-                                              false);
+        context.builder.push_stacking_context(
+            &reference_frame_relative_offset,
+            pipeline_id,
+            composition_operations,
+            stacking_context.transform_style,
+            is_backface_visible,
+            false,
+        );
 
-        self.flatten_items(traversal,
-                           pipeline_id,
-                           context,
-                           reference_frame_relative_offset);
+        self.flatten_items(
+            traversal,
+            pipeline_id,
+            context,
+            reference_frame_relative_offset,
+        );
 
         if stacking_context.scroll_policy == ScrollPolicy::Fixed {
             context.replacements.pop();
         }
 
         if is_reference_frame {
             context.replacements.pop();
             context.builder.pop_reference_frame();
         }
 
         context.builder.pop_stacking_context();
     }
 
-    fn flatten_iframe<'a>(&mut self,
-                          pipeline_id: PipelineId,
-                          parent_id: ClipId,
-                          bounds: &LayerRect,
-                          local_clip: &LocalClip,
-                          context: &mut FlattenContext,
-                          reference_frame_relative_offset: LayerVector2D) {
+    fn flatten_iframe<'a>(
+        &mut self,
+        pipeline_id: PipelineId,
+        parent_id: ClipId,
+        bounds: &LayerRect,
+        local_clip: &LocalClip,
+        context: &mut FlattenContext,
+        reference_frame_relative_offset: LayerVector2D,
+    ) {
         let pipeline = match context.scene.pipeline_map.get(&pipeline_id) {
             Some(pipeline) => pipeline,
             None => return,
         };
 
         let display_list = match context.scene.display_lists.get(&pipeline_id) {
             Some(display_list) => display_list,
             None => return,
         };
 
         let mut clip_region = ClipRegion::create_for_clip_node_with_local_clip(local_clip);
         clip_region.origin += reference_frame_relative_offset;
         let parent_pipeline_id = parent_id.pipeline_id();
-        let clip_id = self.clip_scroll_tree.generate_new_clip_id(parent_pipeline_id);
-        context.builder.add_clip_node(clip_id,
-                                      parent_id,
-                                      parent_pipeline_id,
-                                      clip_region,
-                                      &mut self.clip_scroll_tree);
+        let clip_id = self.clip_scroll_tree
+            .generate_new_clip_id(parent_pipeline_id);
+        context.builder.add_clip_node(
+            clip_id,
+            parent_id,
+            parent_pipeline_id,
+            clip_region,
+            &mut self.clip_scroll_tree,
+        );
 
         self.pipeline_epoch_map.insert(pipeline_id, pipeline.epoch);
 
         let iframe_rect = LayerRect::new(LayerPoint::zero(), bounds.size);
         let origin = reference_frame_relative_offset + bounds.origin.to_vector();
         let transform = LayerToScrollTransform::create_translation(origin.x, origin.y, 0.0);
-        let iframe_reference_frame_id =
-            context.builder.push_reference_frame(Some(clip_id),
-                                                 pipeline_id,
-                                                 &iframe_rect,
-                                                 &transform,
-                                                 origin,
-                                                 &mut self.clip_scroll_tree);
+        let iframe_reference_frame_id = context.builder.push_reference_frame(
+            Some(clip_id),
+            pipeline_id,
+            &iframe_rect,
+            &transform,
+            origin,
+            &mut self.clip_scroll_tree,
+        );
 
         context.builder.add_scroll_frame(
             ClipId::root_scroll_node(pipeline_id),
             iframe_reference_frame_id,
             pipeline_id,
             &iframe_rect,
             &pipeline.content_size,
             ScrollSensitivity::ScriptAndInputEvents,
-            &mut self.clip_scroll_tree);
+            &mut self.clip_scroll_tree,
+        );
 
-        self.flatten_root(&mut display_list.iter(), pipeline_id, context, &pipeline.content_size);
+        self.flatten_root(
+            &mut display_list.iter(),
+            pipeline_id,
+            context,
+            &pipeline.content_size,
+        );
 
         context.builder.pop_reference_frame();
     }
 
-    fn flatten_item<'a, 'b>(&mut self,
-                            item: DisplayItemRef<'a, 'b>,
-                            pipeline_id: PipelineId,
-                            context: &mut FlattenContext,
-                            reference_frame_relative_offset: LayerVector2D)
-                            -> Option<BuiltDisplayListIter<'a>> {
+    fn flatten_item<'a, 'b>(
+        &mut self,
+        item: DisplayItemRef<'a, 'b>,
+        pipeline_id: PipelineId,
+        context: &mut FlattenContext,
+        reference_frame_relative_offset: LayerVector2D,
+    ) -> Option<BuiltDisplayListIter<'a>> {
         let mut clip_and_scroll = item.clip_and_scroll();
         context.convert_clip_scroll_info_to_nested(&mut clip_and_scroll);
 
         let unreplaced_scroll_id = clip_and_scroll.scroll_node_id;
         clip_and_scroll.scroll_node_id =
             context.apply_scroll_frame_id_replacement(clip_and_scroll.scroll_node_id);
 
         let prim_info = item.get_layer_primitive_info(&reference_frame_relative_offset);
         match *item.item() {
             SpecificDisplayItem::Image(ref info) => {
                 if let Some(tiling) = context.tiled_image_map.get(&info.image_key) {
                     // The image resource is tiled. We have to generate an image primitive
                     // for each tile.
-                    self.decompose_image(clip_and_scroll,
-                                         &mut context.builder,
-                                         &prim_info,
-                                         info,
-                                         tiling.image_size,
-                                         tiling.tile_size as u32);
+                    self.decompose_image(
+                        clip_and_scroll,
+                        &mut context.builder,
+                        &prim_info,
+                        info,
+                        tiling.image_size,
+                        tiling.tile_size as u32,
+                    );
                 } else {
-                    context.builder.add_image(clip_and_scroll,
-                                              &prim_info,
-                                              &info.stretch_size,
-                                              &info.tile_spacing,
-                                              None,
-                                              info.image_key,
-                                              info.image_rendering,
-                                              None);
+                    context.builder.add_image(
+                        clip_and_scroll,
+                        &prim_info,
+                        &info.stretch_size,
+                        &info.tile_spacing,
+                        None,
+                        info.image_key,
+                        info.image_rendering,
+                        None,
<