servo: Merge #15804 - Update WR (reference frames for fixed position elements) (from glennw:update-wr-transforms); r=pcwalton
authorGlenn Watson <github@intuitionlibrary.com>
Thu, 02 Mar 2017 17:02:26 -0800
changeset 345694 605fd6c8ee11674bda8d1848c41da3557323b2e5
parent 345693 830a13c24b225b54e0bdf0b2585c0f7943f88a7d
child 345695 9c1478a17bf621217bf082281705af5c270764dd
push id31443
push usercbook@mozilla.com
push dateFri, 03 Mar 2017 12:01:25 +0000
treeherdermozilla-central@31c09bb63b69 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspcwalton
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
servo: Merge #15804 - Update WR (reference frames for fixed position elements) (from glennw:update-wr-transforms); r=pcwalton Source-Repo: https://github.com/servo/servo Source-Revision: 0f6b5c3b521686f79a18da64364eed5a03262605
servo/Cargo.lock
servo/components/gfx/display_list/mod.rs
servo/components/layout/block.rs
servo/components/layout/flow.rs
servo/components/layout/fragment.rs
servo/components/layout/webrender_helpers.rs
--- a/servo/Cargo.lock
+++ b/servo/Cargo.lock
@@ -278,31 +278,31 @@ dependencies = [
  "cssparser 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "canvas_traits"
 version = "0.0.1"
 dependencies = [
  "cssparser 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "caseless"
 version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -413,18 +413,18 @@ dependencies = [
  "net_traits 0.0.1",
  "profile_traits 0.0.1",
  "script_traits 0.0.1",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender 0.21.0 (git+https://github.com/servo/webrender)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender 0.22.1 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "constellation"
 version = "0.0.1"
 dependencies = [
  "backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bluetooth_traits 0.0.1",
@@ -447,17 +447,17 @@ dependencies = [
  "script_traits 0.0.1",
  "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
  "servo_rand 0.0.1",
  "servo_remutex 0.0.1",
  "servo_url 0.0.1",
  "style_traits 0.0.1",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
  "webvr_traits 0.0.1",
 ]
 
 [[package]]
 name = "content-blocker"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -702,17 +702,17 @@ dependencies = [
  "msg 0.0.1",
  "net_traits 0.0.1",
  "objc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "script_traits 0.0.1",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style_traits 0.0.1",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
  "x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "encoding"
 version = "0.2.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
@@ -989,17 +989,17 @@ dependencies = [
  "servo_url 0.0.1",
  "simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "truetype 0.26.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
  "xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "gfx_tests"
 version = "0.0.1"
 dependencies = [
  "gfx 0.0.1",
@@ -1068,17 +1068,17 @@ dependencies = [
  "script_traits 0.0.1",
  "servo-egl 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo-glutin 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style_traits 0.0.1",
  "user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "glx"
 version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1370,17 +1370,17 @@ dependencies = [
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
  "unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-script 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "layout_tests"
 version = "0.0.1"
 dependencies = [
  "layout 0.0.1",
 ]
@@ -1410,31 +1410,31 @@ dependencies = [
  "script_traits 0.0.1",
  "selectors 0.18.0",
  "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style 0.0.1",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "layout_traits"
 version = "0.0.1"
 dependencies = [
  "gfx 0.0.1",
  "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "net_traits 0.0.1",
  "profile_traits 0.0.1",
  "script_traits 0.0.1",
  "servo_url 0.0.1",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "lazy_static"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -1509,18 +1509,18 @@ dependencies = [
  "script_layout_interface 0.0.1",
  "script_traits 0.0.1",
  "servo_config 0.0.1",
  "servo_geometry 0.0.1",
  "servo_url 0.0.1",
  "style 0.0.1",
  "style_traits 0.0.1",
  "webdriver_server 0.0.1",
- "webrender 0.21.0 (git+https://github.com/servo/webrender)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender 0.22.1 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
  "webvr 0.0.1",
  "webvr_traits 0.0.1",
 ]
 
 [[package]]
 name = "libz-sys"
 version = "1.0.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1657,17 +1657,17 @@ name = "msg"
 version = "0.0.1"
 dependencies = [
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "cssparser 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize_derive 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "net"
 version = "0.0.1"
 dependencies = [
  "brotli 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "content-blocker 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1696,17 +1696,17 @@ dependencies = [
  "servo_config 0.0.1",
  "servo_url 0.0.1",
  "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "tinyfiledialogs 2.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "net2"
 version = "0.2.26"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1755,17 +1755,17 @@ dependencies = [
  "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo-websocket 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "servo_config 0.0.1",
  "servo_url 0.0.1",
  "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "net_traits_tests"
 version = "0.0.1"
 dependencies = [
  "net_traits 0.0.1",
 ]
@@ -2293,17 +2293,17 @@ dependencies = [
  "servo_url 0.0.1",
  "smallvec 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "style 0.0.1",
  "style_traits 0.0.1",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "tinyfiledialogs 2.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
  "webvr 0.0.1",
  "webvr_traits 0.0.1",
  "xml5ever 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "script_layout_interface"
 version = "0.0.1"
@@ -3170,18 +3170,18 @@ dependencies = [
  "servo_url 0.0.1",
  "url 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "webdriver 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "webrender"
-version = "0.21.0"
-source = "git+https://github.com/servo/webrender#040805f31650527311c0a0d58ccf9620b0f3eca9"
+version = "0.22.1"
+source = "git+https://github.com/servo/webrender#68f5b72fb3f871f6930c772c7e2705412512dde2"
 dependencies = [
  "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bincode 1.0.0-alpha2 (registry+https://github.com/rust-lang/crates.io-index)",
  "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-text 4.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3193,23 +3193,23 @@ dependencies = [
  "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazy_static 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "offscreen_gl_context 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "threadpool 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
 ]
 
 [[package]]
 name = "webrender_traits"
-version = "0.22.0"
-source = "git+https://github.com/servo/webrender#040805f31650527311c0a0d58ccf9620b0f3eca9"
+version = "0.23.1"
+source = "git+https://github.com/servo/webrender#68f5b72fb3f871f6930c772c7e2705412512dde2"
 dependencies = [
  "app_units 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-graphics 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "dwrote 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "euclid 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "gleam 0.2.32 (registry+https://github.com/rust-lang/crates.io-index)",
  "heapsize 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3223,17 +3223,17 @@ dependencies = [
 name = "webvr"
 version = "0.0.1"
 dependencies = [
  "ipc-channel 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "msg 0.0.1",
  "script_traits 0.0.1",
  "servo_config 0.0.1",
- "webrender_traits 0.22.0 (git+https://github.com/servo/webrender)",
+ "webrender_traits 0.23.1 (git+https://github.com/servo/webrender)",
  "webvr_traits 0.0.1",
 ]
 
 [[package]]
 name = "winapi"
 version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
@@ -3563,18 +3563,18 @@ dependencies = [
 "checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47"
 "checksum utf-8 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9aee9ba280438b56d1ebc5329f2094f0ff457f811eeeff0b278d75aa99db400"
 "checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
 "checksum uuid 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7cfec50b0842181ba6e713151b72f4ec84a6a7e2c9c8a8a3ffc37bb1cd16b231"
 "checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f"
 "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
 "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff"
 "checksum webdriver 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cdc28802daddee94267a657ffeac2593a33881fb7a3a44fedd320b1319efcaf6"
-"checksum webrender 0.21.0 (git+https://github.com/servo/webrender)" = "<none>"
-"checksum webrender_traits 0.22.0 (git+https://github.com/servo/webrender)" = "<none>"
+"checksum webrender 0.22.1 (git+https://github.com/servo/webrender)" = "<none>"
+"checksum webrender_traits 0.23.1 (git+https://github.com/servo/webrender)" = "<none>"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
 "checksum ws 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "04614a58714f3fd4a8b1da4bcae9f031c532d35988c3d39627619248113f8be8"
 "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
 "checksum x11 2.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "124eb405bf0262a54e1a982d4ffe4cd1c24261bdb306e49996e2ce7d492284a8"
 "checksum x11-dl 2.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bf1f9986368c9bbdd8191a783a7ceb42e0c9c6d3348616c873f829b3288a139c"
 "checksum xdg 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "77b831a5ba77110f438f0ac5583aafeb087f70432998ba6b7dcb1d32185db453"
 "checksum xi-unicode 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "12ea8eda4b1eb72f02d148402e23832d56a33f55d8c1b2d5bcdde91d79d47cb1"
--- a/servo/components/gfx/display_list/mod.rs
+++ b/servo/components/gfx/display_list/mod.rs
@@ -177,27 +177,35 @@ impl DisplayList {
         // Convert the parent translated point into stacking context local transform space if the
         // stacking context isn't fixed.  If it's fixed, we need to use the client point anyway.
         debug_assert!(stacking_context.context_type == StackingContextType::Real);
         let is_fixed = stacking_context.scroll_policy == ScrollPolicy::Fixed;
         *translated_point = if is_fixed {
             *client_point
         } else {
             let point = *translated_point - stacking_context.bounds.origin;
-            let inv_transform = match stacking_context.transform.inverse() {
-                Some(transform) => transform,
+
+            match stacking_context.transform {
+                Some(transform) => {
+                    let inv_transform = match transform.inverse() {
+                        Some(transform) => transform,
+                        None => {
+                            // If a transform function causes the current transformation matrix of an object
+                            // to be non-invertible, the object and its content do not get displayed.
+                            return;
+                        }
+                    };
+                    let frac_point = inv_transform.transform_point(&Point2D::new(point.x.to_f32_px(),
+                                                                                 point.y.to_f32_px()));
+                    Point2D::new(Au::from_f32_px(frac_point.x), Au::from_f32_px(frac_point.y))
+                }
                 None => {
-                    // If a transform function causes the current transformation matrix of an object
-                    // to be non-invertible, the object and its content do not get displayed.
-                    return;
+                    point
                 }
-            };
-            let frac_point = inv_transform.transform_point(&Point2D::new(point.x.to_f32_px(),
-                                                                         point.y.to_f32_px()));
-            Point2D::new(Au::from_f32_px(frac_point.x), Au::from_f32_px(frac_point.y))
+            }
         };
     }
 
     #[inline]
     fn scroll_root<'a>(scroll_root: &ScrollRoot,
                        translated_point: &mut Point2D<Au>,
                        scroll_offsets: &ScrollOffsetMap) {
         // Adjust the translated point to account for the scroll offset if necessary.
@@ -355,20 +363,20 @@ pub struct StackingContext {
 
     /// CSS filters to be applied to this stacking context (including opacity).
     pub filters: filter::T,
 
     /// The blend mode with which this stacking context blends with its backdrop.
     pub blend_mode: mix_blend_mode::T,
 
     /// A transform to be applied to this stacking context.
-    pub transform: Matrix4D<f32>,
+    pub transform: Option<Matrix4D<f32>>,
 
     /// The perspective matrix to be applied to children.
-    pub perspective: Matrix4D<f32>,
+    pub perspective: Option<Matrix4D<f32>>,
 
     /// Whether this stacking context creates a new 3d rendering context.
     pub establishes_3d_context: bool,
 
     /// The scroll policy of this layer.
     pub scroll_policy: ScrollPolicy,
 
     /// The id of the parent scrolling area that contains this StackingContext.
@@ -380,18 +388,18 @@ impl StackingContext {
     #[inline]
     pub fn new(id: StackingContextId,
                context_type: StackingContextType,
                bounds: &Rect<Au>,
                overflow: &Rect<Au>,
                z_index: i32,
                filters: filter::T,
                blend_mode: mix_blend_mode::T,
-               transform: Matrix4D<f32>,
-               perspective: Matrix4D<f32>,
+               transform: Option<Matrix4D<f32>>,
+               perspective: Option<Matrix4D<f32>>,
                establishes_3d_context: bool,
                scroll_policy: ScrollPolicy,
                parent_scroll_id: ScrollRootId)
                -> StackingContext {
         StackingContext {
             id: id,
             context_type: context_type,
             bounds: *bounds,
@@ -411,18 +419,18 @@ impl StackingContext {
     pub fn root() -> StackingContext {
         StackingContext::new(StackingContextId::new(0),
                              StackingContextType::Real,
                              &Rect::zero(),
                              &Rect::zero(),
                              0,
                              filter::T::new(Vec::new()),
                              mix_blend_mode::T::normal,
-                             Matrix4D::identity(),
-                             Matrix4D::identity(),
+                             None,
+                             None,
                              true,
                              ScrollPolicy::Scrollable,
                              ScrollRootId::root())
     }
 
     pub fn to_display_list_items(self) -> (DisplayItem, DisplayItem) {
         let mut base_item = BaseDisplayItem::empty();
         base_item.stacking_context_id = self.id;
--- a/servo/components/layout/block.rs
+++ b/servo/components/layout/block.rs
@@ -26,17 +26,17 @@
 //!   http://dev.w3.org/csswg/css-sizing/
 
 #![deny(unsafe_code)]
 
 use app_units::{Au, MAX_AU};
 use context::LayoutContext;
 use display_list_builder::{BorderPaintingMode, DisplayListBuildState, FragmentDisplayListBuilding};
 use display_list_builder::BlockFlowDisplayListBuilding;
-use euclid::{Point2D, Rect, Size2D};
+use euclid::{Matrix4D, Point2D, Rect, Size2D};
 use floats::{ClearType, FloatKind, Floats, PlacementInfo};
 use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag};
 use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT};
 use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, INLINE_POSITION_IS_STATIC};
 use flow::{FragmentationContext, MARGINS_CANNOT_COLLAPSE, PreorderFlowTraversal};
 use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, MutableFlowUtils, OpaqueFlow};
 use flow::IS_ABSOLUTELY_POSITIONED;
 use flow_list::FlowList;
@@ -1806,16 +1806,17 @@ impl BlockFlow {
         self.base.clip = self.base.clip.translate(&-stacking_relative_border_box.origin);
 
         // Account for `transform`, if applicable.
         if self.fragment.style.get_box().transform.0.is_none() {
             return
         }
         let transform = match self.fragment
                                   .transform_matrix(&stacking_relative_border_box)
+                                  .unwrap_or(Matrix4D::identity())
                                   .inverse() {
             Some(transform) => transform,
             None => {
                 // Singular matrix. Ignore it.
                 return
             }
         };
 
--- a/servo/components/layout/flow.rs
+++ b/servo/components/layout/flow.rs
@@ -24,17 +24,17 @@
 //!   fragments/flows that are subject to inline layout and line breaking and structs to represent
 //!   line breaks and mapping to CSS boxes, for the purpose of handling `getClientRects()` and
 //!   similar methods.
 
 use app_units::Au;
 use block::{BlockFlow, FormattingContextType};
 use context::LayoutContext;
 use display_list_builder::DisplayListBuildState;
-use euclid::{Point2D, Size2D};
+use euclid::{Matrix4D, Point2D, Size2D};
 use flex::FlexFlow;
 use floats::{Floats, SpeculatedFloatPlacement};
 use flow_list::{FlowList, MutFlowListIterator};
 use flow_ref::{FlowRef, WeakFlowRef};
 use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
 use gfx::display_list::ClippingRegion;
 use gfx_traits::{ScrollRootId, StackingContextId};
 use gfx_traits::print_tree::PrintTree;
@@ -267,17 +267,21 @@ pub trait Flow: fmt::Debug + Sync + Send
         if !self.as_block().fragment.establishes_stacking_context() ||
            self.as_block().fragment.style.get_box().transform.0.is_none() {
             overflow.translate(&position.origin);
             return overflow;
         }
 
         // TODO: Take into account 3d transforms, even though it's a fairly
         // uncommon case.
-        let transform_2d = self.as_block().fragment.transform_matrix(&position).to_2d();
+        let transform_2d = self.as_block()
+                               .fragment
+                               .transform_matrix(&position)
+                               .unwrap_or(Matrix4D::identity())
+                               .to_2d();
         let transformed_overflow = Overflow {
             paint: f32_rect_to_au_rect(transform_2d.transform_rect(
                                        &au_rect_to_f32_rect(overflow.paint))),
             scroll: f32_rect_to_au_rect(transform_2d.transform_rect(
                                        &au_rect_to_f32_rect(overflow.scroll))),
         };
 
         // TODO: We are taking the union of the overflow and transformed overflow here, which
--- a/servo/components/layout/fragment.rs
+++ b/servo/components/layout/fragment.rs
@@ -2868,23 +2868,23 @@ impl Fragment {
             SpecificFragmentInfo::ScannedText(_) |
             SpecificFragmentInfo::TruncatedFragment(_) |
             SpecificFragmentInfo::Svg(_) |
             SpecificFragmentInfo::UnscannedText(_) => true
         }
     }
 
     /// Returns the 4D matrix representing this fragment's transform.
-    pub fn transform_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Matrix4D<f32> {
-        let mut transform = Matrix4D::identity();
+    pub fn transform_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Option<Matrix4D<f32>> {
         let operations = match self.style.get_box().transform.0 {
-            None => return transform,
+            None => return None,
             Some(ref operations) => operations,
         };
 
+        let mut transform = Matrix4D::identity();
         let transform_origin = &self.style.get_box().transform_origin;
         let transform_origin_x = model::specified(transform_origin.horizontal,
                                                   stacking_relative_border_box.size
                                                                               .width).to_f32_px();
         let transform_origin_y = model::specified(transform_origin.vertical,
                                                   stacking_relative_border_box.size
                                                                               .height).to_f32_px();
         let transform_origin_z = transform_origin.depth.to_f32_px();
@@ -2923,21 +2923,21 @@ impl Fragment {
                     Matrix4D::create_skew(Radians::new(theta_x.radians()),
                                           Radians::new(theta_y.radians()))
                 }
             };
 
             transform = transform.pre_mul(&matrix);
         }
 
-        pre_transform.pre_mul(&transform).pre_mul(&post_transform)
+        Some(pre_transform.pre_mul(&transform).pre_mul(&post_transform))
     }
 
     /// Returns the 4D matrix representing this fragment's perspective.
-    pub fn perspective_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Matrix4D<f32> {
+    pub fn perspective_matrix(&self, stacking_relative_border_box: &Rect<Au>) -> Option<Matrix4D<f32>> {
         match self.style().get_box().perspective {
             Either::First(length) => {
                 let perspective_origin = self.style().get_box().perspective_origin;
                 let perspective_origin =
                     Point2D::new(model::specified(perspective_origin.horizontal,
                                                   stacking_relative_border_box.size.width).to_f32_px(),
                                  model::specified(perspective_origin.vertical,
                                                   stacking_relative_border_box.size.height).to_f32_px());
@@ -2946,20 +2946,20 @@ impl Fragment {
                                                                  perspective_origin.y,
                                                                  0.0);
                 let post_transform = Matrix4D::create_translation(-perspective_origin.x,
                                                                   -perspective_origin.y,
                                                                   0.0);
 
                 let perspective_matrix = create_perspective_matrix(length);
 
-                pre_transform.pre_mul(&perspective_matrix).pre_mul(&post_transform)
+                Some(pre_transform.pre_mul(&perspective_matrix).pre_mul(&post_transform))
             }
             Either::Second(values::None_) => {
-                Matrix4D::identity()
+                None
             }
         }
     }
 }
 
 impl fmt::Debug for Fragment {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         let border_padding_string = if !self.border_padding.is_zero() {
--- a/servo/components/layout/webrender_helpers.rs
+++ b/servo/components/layout/webrender_helpers.rs
@@ -376,22 +376,29 @@ impl WebRenderDisplayItemConverter for D
             DisplayItem::PushStackingContext(ref item) => {
                 let stacking_context = &item.stacking_context;
                 debug_assert!(stacking_context.context_type == StackingContextType::Real);
 
                 let clip = builder.new_clip_region(&stacking_context.overflow.to_rectf(),
                                                    vec![],
                                                    None);
 
+                let transform = stacking_context.transform.map(|transform| {
+                    LayoutTransform::from_untyped(&transform).into()
+                });
+                let perspective = stacking_context.perspective.map(|perspective| {
+                    LayoutTransform::from_untyped(&perspective)
+                });
+
                 builder.push_stacking_context(stacking_context.scroll_policy,
                                               stacking_context.bounds.to_rectf(),
                                               clip,
                                               stacking_context.z_index,
-                                              LayoutTransform::from_untyped(&stacking_context.transform).into(),
-                                              LayoutTransform::from_untyped(&stacking_context.perspective),
+                                              transform,
+                                              perspective,
                                               stacking_context.blend_mode.to_blend_mode(),
                                               stacking_context.filters.to_filter_ops());
             }
             DisplayItem::PopStackingContext(_) => builder.pop_stacking_context(),
             DisplayItem::PushScrollRoot(ref item) => {
                 let clip = builder.new_clip_region(&item.scroll_root.clip.to_rectf(),
                                                    vec![],
                                                    None);