Merge m-c to fx-team a=merge
authorWes Kocher <wkocher@mozilla.com>
Wed, 01 Apr 2015 18:21:27 -0700
changeset 237255 52979d819dc2ff7b5253043aeaad4955d0dd66a3
parent 237254 283d8666043ff4bd723315be266fe3e288982008 (current diff)
parent 237167 702abe76d6a24ff8e20315277ff9d83098f7438c (diff)
child 237256 a1e2aa2e30b2dce33c9b89f3e595ddee41be6070
push id57898
push usercbook@mozilla.com
push dateThu, 02 Apr 2015 12:14:17 +0000
treeherdermozilla-inbound@63c87250946e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone40.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
Merge m-c to fx-team a=merge
gfx/thebes/gfxVR.cpp
gfx/thebes/gfxVR.h
gfx/thebes/ovr_capi_dynamic.h
toolkit/components/aboutcompartments/content/aboutCompartments.js
toolkit/components/aboutcompartments/content/aboutCompartments.xhtml
toolkit/components/aboutcompartments/jar.mn
toolkit/components/aboutcompartments/moz.build
toolkit/components/aboutcompartments/nsCompartmentInfo.cpp
toolkit/components/aboutcompartments/nsCompartmentInfo.h
toolkit/components/aboutcompartments/nsICompartmentInfo.idl
toolkit/modules/moz.build
--- a/.gitignore
+++ b/.gitignore
@@ -3,16 +3,17 @@
 # Filenames that should be ignored wherever they appear
 *~
 *.pyc
 *.pyo
 TAGS
 tags
 ID
 .DS_Store*
+*.pdb
 
 # Vim swap files.
 .*.sw[a-z]
 
 # Emacs directory variable files.
 **/.dir-locals.el
 
 # User files that may appear at the root
--- a/b2g/config/dolphin/sources.xml
+++ b/b2g/config/dolphin/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="d99ab92d0b829a6c78b5284481d5b236d3901f11"/>
--- a/b2g/config/emulator-ics/sources.xml
+++ b/b2g/config/emulator-ics/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3b3407510d6e2c60242e8b9b5f2bc1783ca0a0e4"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/emulator-jb/sources.xml
+++ b/b2g/config/emulator-jb/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="d99ab92d0b829a6c78b5284481d5b236d3901f11"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/emulator-kk/sources.xml
+++ b/b2g/config/emulator-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="d99ab92d0b829a6c78b5284481d5b236d3901f11"/>
--- a/b2g/config/emulator-l/sources.xml
+++ b/b2g/config/emulator-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="d99ab92d0b829a6c78b5284481d5b236d3901f11"/>
--- a/b2g/config/emulator/sources.xml
+++ b/b2g/config/emulator/sources.xml
@@ -14,17 +14,17 @@
   <!--original fetch url was git://github.com/apitrace/-->
   <remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
   <default remote="caf" revision="refs/tags/android-4.0.4_r2.1" sync-j="4"/>
   <!-- Gonk specific things and forks -->
   <project name="platform_build" path="build" remote="b2g" revision="173b3104bfcbd23fc9dccd4b0035fc49aae3d444">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
-  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia.git" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="93f9ba577f68d772093987c2f1c0a4ae293e1802"/>
   <project name="platform_external_qemu" path="external/qemu" remote="b2g" revision="3b3407510d6e2c60242e8b9b5f2bc1783ca0a0e4"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="34ea6163f9f0e0122fb0bb03607eccdca31ced7a"/>
   <!-- Stock Android things -->
   <project name="platform/abi/cpp" path="abi/cpp" revision="dd924f92906085b831bf1cbbc7484d3c043d613c"/>
--- a/b2g/config/flame-kk/sources.xml
+++ b/b2g/config/flame-kk/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="ef937d1aca7c4cf89ecb5cc43ae8c21c2000a9db">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="d99ab92d0b829a6c78b5284481d5b236d3901f11"/>
--- a/b2g/config/flame/sources.xml
+++ b/b2g/config/flame/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="d99ab92d0b829a6c78b5284481d5b236d3901f11"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="e95b4ce22c825da44d14299e1190ea39a5260bde"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="471afab478649078ad7c75ec6b252481a59e19b8"/>
--- a/b2g/config/gaia.json
+++ b/b2g/config/gaia.json
@@ -1,9 +1,9 @@
 {
     "git": {
-        "git_revision": "4bb3a933bd805e8df1e11827cb247754c3565b0b", 
+        "git_revision": "fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054", 
         "remote": "https://git.mozilla.org/releases/gaia.git", 
         "branch": ""
     }, 
-    "revision": "00266dd4a8170bfe9208338a1ecafbef0bb53306", 
+    "revision": "800a7cc9e5d11f54a98b891b9f083d419255734e", 
     "repo_path": "integration/gaia-central"
 }
--- a/b2g/config/nexus-4/sources.xml
+++ b/b2g/config/nexus-4/sources.xml
@@ -12,17 +12,17 @@
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="4efd19d199ae52656604f794c5a77518400220fd">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="d99ab92d0b829a6c78b5284481d5b236d3901f11"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <!-- Stock Android things -->
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.1" path="prebuilts/clang/linux-x86/3.1" revision="5c45f43419d5582949284eee9cef0c43d866e03b"/>
   <project groups="linux" name="platform/prebuilts/clang/linux-x86/3.2" path="prebuilts/clang/linux-x86/3.2" revision="3748b4168e7bd8d46457d4b6786003bc6a5223ce"/>
--- a/b2g/config/nexus-5-l/sources.xml
+++ b/b2g/config/nexus-5-l/sources.xml
@@ -10,17 +10,17 @@
   <!--original fetch url was git://codeaurora.org/-->
   <remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
   <!--original fetch url was https://git.mozilla.org/releases-->
   <remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
   <!-- B2G specific things. -->
   <project name="platform_build" path="build" remote="b2g" revision="52775e03a2d8532429dff579cb2cd56718e488c3">
     <copyfile dest="Makefile" src="core/root.mk"/>
   </project>
-  <project name="gaia" path="gaia" remote="mozillaorg" revision="4bb3a933bd805e8df1e11827cb247754c3565b0b"/>
+  <project name="gaia" path="gaia" remote="mozillaorg" revision="fb7414fa6f5dbb898adc5bd2bbd9fb75df0d0054"/>
   <project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
   <project name="gonk-misc" path="gonk-misc" remote="b2g" revision="2aa4a75c63cd6e93870a8bddbba45f863cbfd9a3"/>
   <project name="librecovery" path="librecovery" remote="b2g" revision="1b3591a50ed352fc6ddb77462b7b35d0bfa555a3"/>
   <project name="moztt" path="external/moztt" remote="b2g" revision="ed2cf97a6c37a4bbd0bbbbffe06ec7136d8c79ff"/>
   <project name="rilproxy" path="rilproxy" remote="b2g" revision="5ef30994f4778b4052e58a4383dbe7890048c87e"/>
   <project name="valgrind" path="external/valgrind" remote="b2g" revision="daa61633c32b9606f58799a3186395fd2bbb8d8c"/>
   <project name="vex" path="external/VEX" remote="b2g" revision="47f031c320888fe9f3e656602588565b52d43010"/>
   <project name="apitrace" path="external/apitrace" remote="apitrace" revision="d99ab92d0b829a6c78b5284481d5b236d3901f11"/>
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -140,44 +140,43 @@
 @RESPATH@/components/components.manifest
 @RESPATH@/components/alerts.xpt
 #ifdef ACCESSIBILITY
 #ifdef XP_WIN32
 @BINPATH@/AccessibleMarshal.dll
 #endif
 @RESPATH@/components/accessibility.xpt
 #endif
-@RESPATH@/components/appshell.xpt
-@RESPATH@/components/appstartup.xpt
-@RESPATH@/components/autocomplete.xpt
-@RESPATH@/components/autoconfig.xpt
-@RESPATH@/components/browsercompsbase.xpt
-@RESPATH@/components/browser-element.xpt
-@RESPATH@/components/browser-feeds.xpt
-@RESPATH@/components/caps.xpt
-@RESPATH@/components/chardet.xpt
-@RESPATH@/components/chrome.xpt
-@RESPATH@/components/commandhandler.xpt
-@RESPATH@/components/commandlines.xpt
-@RESPATH@/components/compartments.xpt
-@RESPATH@/components/composer.xpt
-@RESPATH@/components/content_events.xpt
-@RESPATH@/components/content_html.xpt
-@RESPATH@/components/content_xslt.xpt
-@RESPATH@/components/cookie.xpt
-@RESPATH@/components/devtools_security.xpt
-@RESPATH@/components/directory.xpt
-@RESPATH@/components/diskspacewatcher.xpt
-@RESPATH@/components/docshell.xpt
-@RESPATH@/components/dom.xpt
-@RESPATH@/components/dom_activities.xpt
-@RESPATH@/components/dom_apps.xpt
-@RESPATH@/components/dom_audiochannel.xpt
-@RESPATH@/components/dom_base.xpt
-@RESPATH@/components/dom_system.xpt
+@BINPATH@/components/appshell.xpt
+@BINPATH@/components/appstartup.xpt
+@BINPATH@/components/autocomplete.xpt
+@BINPATH@/components/autoconfig.xpt
+@BINPATH@/components/browsercompsbase.xpt
+@BINPATH@/components/browser-element.xpt
+@BINPATH@/components/browser-feeds.xpt
+@BINPATH@/components/caps.xpt
+@BINPATH@/components/chardet.xpt
+@BINPATH@/components/chrome.xpt
+@BINPATH@/components/commandhandler.xpt
+@BINPATH@/components/commandlines.xpt
+@BINPATH@/components/composer.xpt
+@BINPATH@/components/content_events.xpt
+@BINPATH@/components/content_html.xpt
+@BINPATH@/components/content_xslt.xpt
+@BINPATH@/components/cookie.xpt
+@BINPATH@/components/devtools_security.xpt
+@BINPATH@/components/directory.xpt
+@BINPATH@/components/diskspacewatcher.xpt
+@BINPATH@/components/docshell.xpt
+@BINPATH@/components/dom.xpt
+@BINPATH@/components/dom_activities.xpt
+@BINPATH@/components/dom_apps.xpt
+@BINPATH@/components/dom_audiochannel.xpt
+@BINPATH@/components/dom_base.xpt
+@BINPATH@/components/dom_system.xpt
 #ifdef MOZ_WIDGET_GONK
 @RESPATH@/components/dom_wifi.xpt
 @RESPATH@/components/dom_system_gonk.xpt
 #endif
 #ifdef MOZ_B2G_RIL
 @RESPATH@/components/dom_wappush.xpt
 @RESPATH@/components/dom_mobileconnection.xpt
 #endif
@@ -321,16 +320,17 @@
 @RESPATH@/components/spellchecker.xpt
 @RESPATH@/components/storage.xpt
 @RESPATH@/components/telemetry.xpt
 @RESPATH@/components/toolkit_asyncshutdown.xpt
 @RESPATH@/components/toolkit_filewatcher.xpt
 @RESPATH@/components/toolkit_finalizationwitness.xpt
 @RESPATH@/components/toolkit_formautofill.xpt
 @RESPATH@/components/toolkit_osfile.xpt
+@RESPATH@/components/toolkit_perfmonitoring.xpt
 @RESPATH@/components/toolkit_xulstore.xpt
 @RESPATH@/components/toolkitprofile.xpt
 #ifdef MOZ_ENABLE_XREMOTE
 @RESPATH@/components/toolkitremote.xpt
 #endif
 @RESPATH@/components/txtsvc.xpt
 @RESPATH@/components/txmgr.xpt
 #ifdef MOZ_USE_NATIVE_UCONV
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -3774,18 +3774,17 @@
                                           charSet: aMessage.data.charSet,
                                           referrer: aMessage.data.referrer,
                                           referrerPolicy: aMessage.data.referrerPolicy,
                                           contentType: aMessage.data.contentType,
                                           contentDisposition: aMessage.data.contentDisposition,
                                         };
               let popup = browser.ownerDocument.getElementById("contentAreaContextMenu");
               let event = gContextMenuContentData.event;
-              let pos = browser.mapScreenCoordinatesFromContent(event.screenX, event.screenY);
-              popup.openPopupAtScreen(pos.x, pos.y, true);
+              popup.openPopupAtScreen(event.screenX, event.screenY, true);
               break;
             }
             case "DOMWebNotificationClicked": {
               let tab = this.getTabForBrowser(browser);
               if (!tab)
                 return;
               this.selectedTab = tab;
               window.focus();
--- a/browser/base/content/test/general/test_contextmenu_input.html
+++ b/browser/base/content/test/general/test_contextmenu_input.html
@@ -322,17 +322,17 @@ function waitForEvents(event)
 {
   if (event.type == "MozAfterPaint")
     painted = true;
   else if (event.type == "load")
     loaded = true;
   if (painted && loaded) {
     subwindow.removeEventListener("MozAfterPaint", waitForEvents, false);
     subwindow.onload = null;
-    startTest();
+    SimpleTest.waitForFocus(startTest, subwindow);
   }
 }
 
 var subwindow = window.open("data:text/html,<!DOCTYPE html><input><input spellcheck='true' value='prodkjfgigrty'><input spellcheck='true' value='foo'><input readonly spellcheck='false'>", "contextmenu-subtext", "width=600,height=700");
 subwindow.addEventListener("MozAfterPaint", waitForEvents, false);
 subwindow.onload = waitForEvents;
 
 SimpleTest.waitForExplicitFinish();
--- a/browser/base/content/test/social/browser_addons.js
+++ b/browser/base/content/test/social/browser_addons.js
@@ -1,12 +1,13 @@
 
 
 let AddonManager = Cu.import("resource://gre/modules/AddonManager.jsm", {}).AddonManager;
 let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
+let AddonWatcher = Cu.import("resource://gre/modules/AddonWatcher.jsm", {}).AddonWatcher;
 
 const ADDON_TYPE_SERVICE     = "service";
 const ID_SUFFIX              = "@services.mozilla.org";
 const STRING_TYPE_NAME       = "type.%ID%.name";
 const XPINSTALL_URL = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
 
 let manifest = {
   name: "provider 1",
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -175,17 +175,16 @@
 @RESPATH@/components/browser-element.xpt
 @RESPATH@/browser/components/browsercompsbase.xpt
 @RESPATH@/browser/components/browser-feeds.xpt
 @RESPATH@/browser/components/browsermodules.manifest
 @RESPATH@/components/caps.xpt
 @RESPATH@/components/chrome.xpt
 @RESPATH@/components/commandhandler.xpt
 @RESPATH@/components/commandlines.xpt
-@RESPATH@/components/compartments.xpt
 @RESPATH@/components/composer.xpt
 @RESPATH@/components/content_events.xpt
 @RESPATH@/components/content_html.xpt
 @RESPATH@/components/content_geckomediaplugins.xpt
 #ifdef MOZ_WEBRTC
 @RESPATH@/components/content_webrtc.xpt
 #endif
 @RESPATH@/components/content_xslt.xpt
@@ -323,16 +322,17 @@
 @RESPATH@/components/shistory.xpt
 @RESPATH@/components/spellchecker.xpt
 @RESPATH@/components/storage.xpt
 @RESPATH@/components/toolkit_asyncshutdown.xpt
 @RESPATH@/components/toolkit_filewatcher.xpt
 @RESPATH@/components/toolkit_finalizationwitness.xpt
 @RESPATH@/components/toolkit_formautofill.xpt
 @RESPATH@/components/toolkit_osfile.xpt
+@RESPATH@/components/toolkit_perfmonitoring.xpt
 @RESPATH@/components/toolkit_xulstore.xpt
 @RESPATH@/components/toolkitprofile.xpt
 #ifdef MOZ_ENABLE_XREMOTE
 @RESPATH@/components/toolkitremote.xpt
 #endif
 @RESPATH@/components/txtsvc.xpt
 @RESPATH@/components/txmgr.xpt
 @RESPATH@/components/uconv.xpt
--- a/docshell/base/nsAboutRedirector.cpp
+++ b/docshell/base/nsAboutRedirector.cpp
@@ -70,17 +70,17 @@ static RedirEntry kRedirMap[] = {
       nsIAboutModule::ALLOW_SCRIPT |
       nsIAboutModule::HIDE_FROM_ABOUTABOUT
   },
   {
     "memory", "chrome://global/content/aboutMemory.xhtml",
     nsIAboutModule::ALLOW_SCRIPT
   },
   {
-    "compartments", "chrome://global/content/aboutCompartments.xhtml",
+    "performance", "chrome://global/content/aboutPerformance.xhtml",
     nsIAboutModule::ALLOW_SCRIPT
   },
   {
     "addons", "chrome://mozapps/content/extensions/extensions.xul",
     nsIAboutModule::ALLOW_SCRIPT
   },
   {
     "newaddon", "chrome://mozapps/content/extensions/newaddon.xul",
--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -161,19 +161,18 @@ const mozilla::Module::ContractIDEntry k
 #endif
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "credits", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "plugins", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "mozilla", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "logo", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "buildconfig", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "license", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "neterror", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
-  { NS_ABOUT_MODULE_CONTRACTID_PREFIX "compartments", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "memory", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
-  { NS_ABOUT_MODULE_CONTRACTID_PREFIX "compartments", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
+  { NS_ABOUT_MODULE_CONTRACTID_PREFIX "performance", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "addons", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "newaddon", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "support", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "telemetry", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "networking", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "webrtc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_ABOUT_MODULE_CONTRACTID_PREFIX "srcdoc", &kNS_ABOUT_REDIRECTOR_MODULE_CID },
   { NS_URI_LOADER_CONTRACTID, &kNS_URI_LOADER_CID },
--- a/dom/alarm/AlarmsManager.js
+++ b/dom/alarm/AlarmsManager.js
@@ -1,30 +1,38 @@
 /* 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 strict";
 
 /* static functions */
 const DEBUG = false;
+const REQUEST_CPU_LOCK_TIMEOUT = 10 * 1000; // 10 seconds.
 
 function debug(aStr) {
   if (DEBUG)
     dump("AlarmsManager: " + aStr + "\n");
 }
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
 
+XPCOMUtils.defineLazyServiceGetter(this, "gPowerManagerService",
+                                   "@mozilla.org/power/powermanagerservice;1",
+                                   "nsIPowerManagerService");
+
 function AlarmsManager() {
   debug("Constructor");
+
+  // A <requestId, {cpuLock, timer}> map.
+  this._cpuLockDict = new Map();
 }
 
 AlarmsManager.prototype = {
   __proto__: DOMRequestIpcHelper.prototype,
 
   contractID : "@mozilla.org/alarmsManager;1",
 
   classID : Components.ID("{fea1e884-9b05-11e1-9b64-87a7016c3860}"),
@@ -66,18 +74,20 @@ AlarmsManager.prototype = {
       // Run JSON.stringify() in the sand box with the principal of the calling
       // web page to ensure no cross-origin object is involved. A "Permission
       // Denied" error will be thrown in case of privilege violation.
       let sandbox = new Cu.Sandbox(Cu.getWebIDLCallerPrincipal());
       sandbox.data = aData;
       data = JSON.parse(Cu.evalInSandbox("JSON.stringify(data)", sandbox));
     }
     let request = this.createRequest();
+    let requestId = this.getRequestId(request);
+    this._lockCpuForRequest(requestId);
     this._cpmm.sendAsyncMessage("AlarmsManager:Add",
-                                { requestId: this.getRequestId(request),
+                                { requestId: requestId,
                                   date: aDate,
                                   ignoreTimezone: isIgnoreTimezone,
                                   data: data,
                                   pageURL: this._pageURL,
                                   manifestURL: this._manifestURL });
     return request;
   },
 
@@ -106,16 +116,17 @@ AlarmsManager.prototype = {
 
     if (!request) {
       debug("No request stored! " + json.requestId);
       return;
     }
 
     switch (aMessage.name) {
       case "AlarmsManager:Add:Return:OK":
+        this._unlockCpuForRequest(json.requestId);
         Services.DOMRequest.fireSuccess(request, json.id);
         break;
 
       case "AlarmsManager:GetAll:Return:OK":
         // We don't need to expose everything to the web content.
         let alarms = [];
         json.alarms.forEach(function trimAlarmInfo(aAlarm) {
           let alarm = { "id": aAlarm.id,
@@ -126,16 +137,17 @@ AlarmsManager.prototype = {
           alarms.push(alarm);
         });
 
         Services.DOMRequest.fireSuccess(request,
                                         Cu.cloneInto(alarms, this._window));
         break;
 
       case "AlarmsManager:Add:Return:KO":
+        this._unlockCpuForRequest(json.requestId);
         Services.DOMRequest.fireError(request, json.errorMsg);
         break;
 
       case "AlarmsManager:GetAll:Return:KO":
         Services.DOMRequest.fireError(request, json.errorMsg);
         break;
 
       default:
@@ -167,11 +179,49 @@ AlarmsManager.prototype = {
     this._manifestURL = appsService.getManifestURLByLocalId(principal.appId);
     this._window = aWindow;
   },
 
   // Called from DOMRequestIpcHelper.
   uninit: function uninit() {
     debug("uninit()");
   },
+
+  _lockCpuForRequest: function (aRequestId) {
+    if (this._cpuLockDict.has(aRequestId)) {
+      debug('Cpu wakelock for request ' + aRequestId + ' has been acquired. ' +
+            'You may call this function repeatedly or requestId is collision.');
+      return;
+    }
+
+    // Acquire a lock for given request and save for lookup lately.
+    debug('Acquire cpu lock for request ' + aRequestId);
+    let cpuLockInfo = {
+      cpuLock: gPowerManagerService.newWakeLock("cpu"),
+      timer: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer)
+    };
+    this._cpuLockDict.set(aRequestId, cpuLockInfo);
+
+    // Start a timer to prevent from non-responding request.
+    cpuLockInfo.timer.initWithCallback(() => {
+      debug('Request timeout! Release the cpu lock');
+      this._unlockCpuForRequest(aRequestId);
+    }, REQUEST_CPU_LOCK_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT);
+  },
+
+  _unlockCpuForRequest: function(aRequestId) {
+    let cpuLockInfo = this._cpuLockDict.get(aRequestId);
+    if (!cpuLockInfo) {
+      debug('The cpu lock for requestId ' + aRequestId + ' is either invalid ' +
+            'or has been released.');
+      return;
+    }
+
+    // Release the cpu lock and cancel the timer.
+    debug('Release the cpu lock for ' + aRequestId);
+    cpuLockInfo.cpuLock.unlock();
+    cpuLockInfo.timer.cancel();
+    this._cpuLockDict.delete(aRequestId);
+  },
+
 }
 
 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([AlarmsManager])
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -879,18 +879,17 @@ nsFrameLoader::ShowRemoteFrame(const Scr
                           "remote-browser-shown", nullptr);
     }
   } else {
     nsIntRect dimensions;
     NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), false);
 
     // Don't show remote iframe if we are waiting for the completion of reflow.
     if (!aFrame || !(aFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
-      nsIntPoint chromeDisp = aFrame->GetChromeDisplacement();
-      mRemoteBrowser->UpdateDimensions(dimensions, size, chromeDisp);
+      mRemoteBrowser->UpdateDimensions(dimensions, size);
     }
   }
 
   return true;
 }
 
 void
 nsFrameLoader::Hide()
@@ -1378,16 +1377,22 @@ nsFrameLoader::StartDestroy()
   // references are dropped in DestroyComplete.
   if (mChildMessageManager || mRemoteBrowser) {
     mOwnerContentStrong = mOwnerContent;
     if (mRemoteBrowser) {
       mRemoteBrowser->CacheFrameLoader(this);
     }
   }
 
+  // If the TabParent has installed any event listeners on the window, this is
+  // its last chance to remove them while we're still in the document.
+  if (mRemoteBrowser) {
+    mRemoteBrowser->RemoveWindowListeners();
+  }
+
   nsCOMPtr<nsIDocument> doc;
   bool dynamicSubframeRemoval = false;
   if (mOwnerContent) {
     doc = mOwnerContent->OwnerDoc();
     dynamicSubframeRemoval = !mIsTopLevelContent && !doc->InUnlinkOrDeletion();
     doc->SetSubDocumentFor(mOwnerContent, nullptr);
 
     SetOwnerContent(nullptr);
@@ -2053,18 +2058,17 @@ nsFrameLoader::GetWindowDimensions(nsInt
 NS_IMETHODIMP
 nsFrameLoader::UpdatePositionAndSize(nsSubDocumentFrame *aIFrame)
 {
   if (mRemoteFrame) {
     if (mRemoteBrowser) {
       ScreenIntSize size = aIFrame->GetSubdocumentSize();
       nsIntRect dimensions;
       NS_ENSURE_SUCCESS(GetWindowDimensions(dimensions), NS_ERROR_FAILURE);
-      nsIntPoint chromeDisp = aIFrame->GetChromeDisplacement();
-      mRemoteBrowser->UpdateDimensions(dimensions, size, chromeDisp);
+      mRemoteBrowser->UpdateDimensions(dimensions, size);
     }
     return NS_OK;
   }
   UpdateBaseWindowPositionAndSize(aIFrame);
   return NS_OK;
 }
 
 void
--- a/dom/base/nsFrameLoader.h
+++ b/dom/base/nsFrameLoader.h
@@ -224,16 +224,19 @@ public:
    */
   void ApplySandboxFlags(uint32_t sandboxFlags);
 
   void GetURL(nsString& aURL);
 
   void ActivateUpdateHitRegion();
   void DeactivateUpdateHitRegion();
 
+  // Properly retrieves documentSize of any subdocument type.
+  nsresult GetWindowDimensions(nsIntRect& aRect);
+
 private:
 
   void SetOwnerContent(mozilla::dom::Element* aContent);
 
   bool ShouldUseRemoteProcess();
 
   /**
    * Is this a frameloader for a bona fide <iframe mozbrowser> or
@@ -279,19 +282,16 @@ private:
 
   /**
    * If we are an IPC frame, set mRemoteFrame. Otherwise, create and
    * initialize mDocShell.
    */
   nsresult MaybeCreateDocShell();
   nsresult EnsureMessageManager();
 
-  // Properly retrieves documentSize of any subdocument type.
-  nsresult GetWindowDimensions(nsIntRect& aRect);
-
   // Updates the subdocument position and size. This gets called only
   // when we have our own in-process DocShell.
   void UpdateBaseWindowPositionAndSize(nsSubDocumentFrame *aIFrame);
   nsresult CheckURILoad(nsIURI* aURI);
   void FireErrorEvent();
   nsresult ReallyStartLoadingInternal();
 
   // Return true if remote browser created; nothing else to do
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1260,25 +1260,16 @@ DOMInterfaces = {
 'URL' : [{
     'wrapperCache': False,
 },
 {
     'workers': True,
     'wrapperCache': False,
 }],
 
-'VRFieldOfView': {
-    'wrapperCache': False,
-},
-
-'VRFieldOfViewReadOnly': {
-    'concrete': False,
-    'wrapperCache': False,
-},
-
 'VRDevice': {
     'concrete': False
 },
 
 'VTTCue': {
     'nativeType': 'mozilla::dom::TextTrackCue'
 },
 
--- a/dom/html/HTMLMediaElement.cpp
+++ b/dom/html/HTMLMediaElement.cpp
@@ -689,16 +689,20 @@ void HTMLMediaElement::AbortExistingLoad
   mAutoplaying = true;
   mIsLoadingFromSourceChildren = false;
   mSuspendedAfterFirstFrame = false;
   mAllowSuspendAfterFirstFrame = true;
   mHaveQueuedSelectResource = false;
   mSuspendedForPreloadNone = false;
   mDownloadSuspendedByCache = false;
   mMediaInfo = MediaInfo();
+  mIsEncrypted = false;
+#ifdef MOZ_EME
+  mPendingEncryptedInitData.mInitDatas.Clear();
+#endif // MOZ_EME
   mSourcePointer = nullptr;
   mLastNextFrameStatus = NEXT_FRAME_UNINITIALIZED;
 
   mTags = nullptr;
 
   if (mNetworkState != nsIDOMHTMLMediaElement::NETWORK_EMPTY) {
     NS_ASSERTION(!mDecoder && !mSrcStream, "How did someone setup a new stream/decoder already?");
     // ChangeNetworkState() will call UpdateAudioChannelPlayingState()
@@ -3083,17 +3087,21 @@ void HTMLMediaElement::ProcessMediaFragm
     mFragmentStart = parser.GetStartTime();
   }
 }
 
 void HTMLMediaElement::MetadataLoaded(const MediaInfo* aInfo,
                                       nsAutoPtr<const MetadataTags> aTags)
 {
   mMediaInfo = *aInfo;
-  mIsEncrypted = aInfo->IsEncrypted();
+  mIsEncrypted = aInfo->IsEncrypted()
+#ifdef MOZ_EME
+                 || mPendingEncryptedInitData.IsEncrypted()
+#endif // MOZ_EME
+                 ;
   mTags = aTags.forget();
   mLoadedDataFired = false;
   ChangeReadyState(nsIDOMHTMLMediaElement::HAVE_METADATA);
 
   if (mIsEncrypted) {
     nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
     obs->NotifyObservers(static_cast<nsIContent*>(this), "media-eme-metadataloaded", nullptr);
   }
@@ -3110,18 +3118,22 @@ void HTMLMediaElement::MetadataLoaded(co
   }
   if (mIsEncrypted) {
     if (!mMediaSource && Preferences::GetBool("media.eme.mse-only", true)) {
       DecodeError();
       return;
     }
 
 #ifdef MOZ_EME
-    DispatchEncrypted(aInfo->mCrypto.mInitData, aInfo->mCrypto.mType);
-#endif
+    // Dispatch a distinct 'encrypted' event for each initData we have.
+    for (const auto& initData : mPendingEncryptedInitData.mInitDatas) {
+      DispatchEncrypted(initData.mInitData, initData.mType);
+    }
+    mPendingEncryptedInitData.mInitDatas.Clear();
+#endif // MOZ_EME
   }
 
   // Expose the tracks to JS directly.
   for (OutputMediaStream& out : mOutputStreams) {
     if (aInfo->HasAudio()) {
       TrackID audioTrackId = aInfo->mAudio.mTrackInfo.mOutputId;
       out.mStream->CreateDOMTrack(audioTrackId, MediaSegment::AUDIO);
     }
@@ -4474,16 +4486,23 @@ HTMLMediaElement::SetOnencrypted(EventHa
     elm->SetEventHandler(nsGkAtoms::onencrypted, EmptyString(), handler);
   }
 }
 
 void
 HTMLMediaElement::DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
                                     const nsAString& aInitDataType)
 {
+  if (mReadyState == nsIDOMHTMLMediaElement::HAVE_NOTHING) {
+    // Ready state not HAVE_METADATA (yet), don't dispatch encrypted now.
+    // Queueing for later dispatch in MetadataLoaded.
+    mPendingEncryptedInitData.AddInitData(aInitDataType, aInitData);
+    return;
+  }
+
   nsRefPtr<MediaEncryptedEvent> event;
   if (IsCORSSameOrigin()) {
     event = MediaEncryptedEvent::Constructor(this, aInitDataType, aInitData);
   } else {
     event = MediaEncryptedEvent::Constructor(this);
   }
 
   nsRefPtr<AsyncEventDispatcher> asyncDispatcher =
--- a/dom/html/HTMLMediaElement.h
+++ b/dom/html/HTMLMediaElement.h
@@ -556,17 +556,16 @@ public:
                                          ErrorResult& aRv);
 
   mozilla::dom::EventHandlerNonNull* GetOnencrypted();
   void SetOnencrypted(mozilla::dom::EventHandlerNonNull* listener);
 
   void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
                          const nsAString& aInitDataType) override;
 
-
   bool IsEventAttributeName(nsIAtom* aName) override;
 
   // Returns the principal of the "top level" document; the origin displayed
   // in the URL bar of the browser window.
   already_AddRefed<nsIPrincipal> GetTopLevelPrincipal();
 
   bool ContainsRestrictedContent();
 #endif // MOZ_EME
@@ -1317,16 +1316,21 @@ protected:
   CORSMode mCORSMode;
 
   // Info about the played media.
   MediaInfo mMediaInfo;
 
   // True if the media has encryption information.
   bool mIsEncrypted;
 
+#ifdef MOZ_EME
+  // Init Data that needs to be sent in 'encrypted' events in MetadataLoaded().
+  EncryptionInfo mPendingEncryptedInitData;
+#endif // MOZ_EME
+
   // True if the media's channel's download has been suspended.
   bool mDownloadSuspendedByCache;
 
   // Audio Channel.
   AudioChannel mAudioChannel;
 
   // The audio channel has been faded.
   bool mAudioChannelFaded;
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2021,18 +2021,18 @@ TabChild::RecvUpdateDimensions(const nsI
                       && (size.width != 0 && size.height != 0);
     if (initialSizing) {
       mHasValidInnerSize = true;
     }
 
     mOrientation = orientation;
     ScreenIntSize oldScreenSize = mInnerSize;
     mInnerSize = size;
-    mWidget->Resize(0, 0, size.width, size.height,
-                    true);
+    mWidget->Resize(rect.x + chromeDisp.x, rect.y + chromeDisp.y, size.width, size.height,
+                     true);
 
     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(WebNavigation());
     baseWin->SetPositionAndSize(0, 0, size.width, size.height,
                                 true);
 
     if (initialSizing && mContentDocumentIsDisplayed) {
       // If this is the first time we're getting a valid mInnerSize, and the
       // before-first-paint event has already been handled, then we need to set
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -75,16 +75,17 @@
 #include "LoadContext.h"
 #include "nsNetCID.h"
 #include "nsIAuthInformation.h"
 #include "nsIAuthPromptCallback.h"
 #include "nsAuthInformationHolder.h"
 #include "nsICancelable.h"
 #include "gfxPrefs.h"
 #include "nsILoginManagerPrompter.h"
+#include "nsPIWindowRoot.h"
 #include <algorithm>
 
 using namespace mozilla::dom;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::layout;
 using namespace mozilla::services;
 using namespace mozilla::widget;
@@ -262,16 +263,17 @@ TabParent::TabParent(nsIContentParent* a
   , mIMECompositionRectOffset(0)
   , mRect(0, 0, 0, 0)
   , mDimensions(0, 0)
   , mOrientation(0)
   , mDPI(0)
   , mDefaultScale(0)
   , mShown(false)
   , mUpdatedDimensions(false)
+  , mChromeOffset(0, 0)
   , mManager(aManager)
   , mMarkedDestroying(false)
   , mIsDestroyed(false)
   , mAppPackageFileDescriptorSent(false)
   , mSendOfflineStatus(true)
   , mChromeFlags(aChromeFlags)
   , mInitedByParent(false)
   , mTabId(aTabId)
@@ -320,21 +322,47 @@ void
 TabParent::CacheFrameLoader(nsFrameLoader* aFrameLoader)
 {
   mFrameLoader = aFrameLoader;
 }
 
 void
 TabParent::SetOwnerElement(Element* aElement)
 {
+  // If we held previous content then unregister for its events.
+  RemoveWindowListeners();
+
+  // Update to the new content, and register to listen for events from it.
   mFrameElement = aElement;
+  if (mFrameElement && mFrameElement->OwnerDoc()->GetWindow()) {
+    nsCOMPtr<nsPIDOMWindow> window = mFrameElement->OwnerDoc()->GetWindow();
+    nsCOMPtr<EventTarget> eventTarget = window->GetTopWindowRoot();
+    if (eventTarget) {
+      eventTarget->AddEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"),
+                                    this, false, false);
+    }
+  }
+
   TryCacheDPIAndScale();
 }
 
 void
+TabParent::RemoveWindowListeners()
+{
+  if (mFrameElement && mFrameElement->OwnerDoc()->GetWindow()) {
+    nsCOMPtr<nsPIDOMWindow> window = mFrameElement->OwnerDoc()->GetWindow();
+    nsCOMPtr<EventTarget> eventTarget = window->GetTopWindowRoot();
+    if (eventTarget) {
+      eventTarget->RemoveEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"),
+                                       this, false);
+    }
+  }
+}
+
+void
 TabParent::GetAppType(nsAString& aOut)
 {
   aOut.Truncate();
   nsCOMPtr<Element> elem = do_QueryInterface(mFrameElement);
   if (!elem) {
     return;
   }
 
@@ -875,34 +903,43 @@ TabParent::RecvSetDimensions(const uint3
     return true;
   }
 
   MOZ_ASSERT(false, "Unknown flags!");
   return false;
 }
 
 void
-TabParent::UpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size,
-                            const nsIntPoint& aChromeDisp)
+TabParent::UpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size)
 {
   if (mIsDestroyed) {
     return;
   }
   hal::ScreenConfiguration config;
   hal::GetCurrentScreenConfiguration(&config);
   ScreenOrientation orientation = config.orientation();
+  nsIntPoint chromeOffset = -LayoutDevicePixel::ToUntyped(GetChildProcessOffset());
 
   if (!mUpdatedDimensions || mOrientation != orientation ||
-      mDimensions != size || !mRect.IsEqualEdges(rect)) {
+      mDimensions != size || !mRect.IsEqualEdges(rect) ||
+      chromeOffset != mChromeOffset) {
+    nsCOMPtr<nsIWidget> widget = GetWidget();
+    nsIntRect contentRect = rect;
+    if (widget) {
+      contentRect.x += widget->GetClientOffset().x;
+      contentRect.y += widget->GetClientOffset().y;
+    }
+
     mUpdatedDimensions = true;
-    mRect = rect;
+    mRect = contentRect;
     mDimensions = size;
     mOrientation = orientation;
-
-    unused << SendUpdateDimensions(mRect, mDimensions, mOrientation, aChromeDisp);
+    mChromeOffset = chromeOffset;
+
+    unused << SendUpdateDimensions(mRect, mDimensions, mOrientation, mChromeOffset);
   }
 }
 
 void
 TabParent::UpdateFrame(const FrameMetrics& aFrameMetrics)
 {
   if (!mIsDestroyed) {
     unused << SendUpdateFrame(aFrameMetrics);
@@ -2735,16 +2772,37 @@ TabParent::AllocPPluginWidgetParent()
 
 bool
 TabParent::DeallocPPluginWidgetParent(mozilla::plugins::PPluginWidgetParent* aActor)
 {
   delete aActor;
   return true;
 }
 
+nsresult
+TabParent::HandleEvent(nsIDOMEvent* aEvent)
+{
+  nsAutoString eventType;
+  aEvent->GetType(eventType);
+
+  if (eventType.EqualsLiteral("MozUpdateWindowPos") && !mIsDestroyed) {
+    // This event is sent when the widget moved.  Therefore we only update
+    // the position.
+    nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
+    if (!frameLoader) {
+      return NS_OK;
+    }
+    nsIntRect windowDims;
+    NS_ENSURE_SUCCESS(frameLoader->GetWindowDimensions(windowDims), NS_ERROR_FAILURE);
+    UpdateDimensions(windowDims, mDimensions);
+    return NS_OK;
+  }
+  return NS_OK;
+}
+
 class FakeChannel final : public nsIChannel,
                           public nsIAuthPromptCallback,
                           public nsIInterfaceRequestor,
                           public nsILoadContext
 {
 public:
   FakeChannel(const nsCString& aUri, uint64_t aCallbackId, Element* aElement)
     : mCallbackId(aCallbackId)
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -55,29 +55,32 @@ struct IMENotification;
 namespace dom {
 
 class ClonedMessageData;
 class nsIContentParent;
 class Element;
 struct StructuredCloneData;
 
 class TabParent final : public PBrowserParent
+                      , public nsIDOMEventListener
                       , public nsITabParent
                       , public nsIAuthPromptProvider
                       , public nsISecureBrowserUI
                       , public nsSupportsWeakReference
                       , public TabContext
 {
     typedef mozilla::dom::ClonedMessageData ClonedMessageData;
 
     virtual ~TabParent();
 
 public:
     // nsITabParent
     NS_DECL_NSITABPARENT
+    // nsIDOMEventListener interfaces
+    NS_DECL_NSIDOMEVENTLISTENER
 
     TabParent(nsIContentParent* aManager,
               const TabId& aTabId,
               const TabContext& aContext,
               uint32_t aChromeFlags);
     Element* GetOwnerElement() const { return mFrameElement; }
     void SetOwnerElement(Element* aElement);
 
@@ -102,16 +105,18 @@ public:
     }
 
     already_AddRefed<nsILoadContext> GetLoadContext();
 
     nsIXULBrowserWindow* GetXULBrowserWindow();
 
     void Destroy();
 
+    void RemoveWindowListeners();
+
     virtual bool RecvMoveFocus(const bool& aForward) override;
     virtual bool RecvEvent(const RemoteDOMEvent& aEvent) override;
     virtual bool RecvReplyKeyEvent(const WidgetKeyboardEvent& aEvent) override;
     virtual bool RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& aEvent) override;
     virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
                                             const nsString& aURL,
                                             const nsString& aName,
                                             const nsString& aFeatures,
@@ -220,18 +225,17 @@ public:
     AllocPColorPickerParent(const nsString& aTitle, const nsString& aInitialColor) override;
     virtual bool DeallocPColorPickerParent(PColorPickerParent* aColorPicker) override;
 
     void LoadURL(nsIURI* aURI);
     // XXX/cjones: it's not clear what we gain by hiding these
     // message-sending functions under a layer of indirection and
     // eating the return values
     void Show(const ScreenIntSize& size, bool aParentIsActive);
-    void UpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size,
-                          const nsIntPoint& chromeDisp);
+    void UpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size);
     void UpdateFrame(const layers::FrameMetrics& aFrameMetrics);
     void UIResolutionChanged();
     void RequestFlingSnap(const FrameMetrics::ViewID& aScrollId,
                           const mozilla::CSSPoint& aDestination);
     void AcknowledgeScrollUpdate(const ViewID& aScrollId, const uint32_t& aScrollGeneration);
     void HandleDoubleTap(const CSSPoint& aPoint,
                          Modifiers aModifiers,
                          const ScrollableLayerGuid& aGuid);
@@ -422,16 +426,17 @@ protected:
 
     nsIntRect mRect;
     ScreenIntSize mDimensions;
     ScreenOrientation mOrientation;
     float mDPI;
     CSSToLayoutDeviceScale mDefaultScale;
     bool mShown;
     bool mUpdatedDimensions;
+    nsIntPoint mChromeOffset;
 
 private:
     already_AddRefed<nsFrameLoader> GetFrameLoader(bool aUseCachedFrameLoaderAfterDestroy = false) const;
     layout::RenderFrameParent* GetRenderFrame();
     nsRefPtr<nsIContentParent> mManager;
     void TryCacheDPIAndScale();
 
     CSSPoint AdjustTapToChildWidget(const CSSPoint& aPoint);
--- a/dom/media/MediaDecoderOwner.h
+++ b/dom/media/MediaDecoderOwner.h
@@ -131,19 +131,19 @@ public:
   virtual VideoFrameContainer* GetVideoFrameContainer() = 0;
 
   // Called by the media decoder object, on the main thread,
   // when the connection between Rtsp server and client gets lost.
   virtual void ResetConnectionState() = 0;
 
 #ifdef MOZ_EME
   // Dispatches a "encrypted" event to the HTMLMediaElement, with the
-  // provided init data.
+  // provided init data. Actual dispatch may be delayed until HAVE_METADATA.
   // Main thread only.
   virtual void DispatchEncrypted(const nsTArray<uint8_t>& aInitData,
                                  const nsAString& aInitDataType) = 0;
-#endif
+#endif // MOZ_EME
 };
 
 }
 
 #endif
 
--- a/dom/media/MediaInfo.h
+++ b/dom/media/MediaInfo.h
@@ -100,43 +100,68 @@ public:
   // True if we have an active audio bitstream.
   bool mHasAudio;
 
   TrackInfo mTrackInfo;
 };
 
 class EncryptionInfo {
 public:
-  EncryptionInfo() : mIsEncrypted(false) {}
+  struct InitData {
+    template<typename AInitDatas>
+    InitData(const nsAString& aType, AInitDatas&& aInitData)
+      : mType(aType)
+      , mInitData(Forward<AInitDatas>(aInitData))
+    {
+    }
 
-  // Encryption type to be passed to JS. Usually `cenc'.
-  nsString mType;
+    // Encryption type to be passed to JS. Usually `cenc'.
+    nsString mType;
 
-  // Encryption data.
-  nsTArray<uint8_t> mInitData;
+    // Encryption data.
+    nsTArray<uint8_t> mInitData;
+  };
+  typedef nsTArray<InitData> InitDatas;
 
   // True if the stream has encryption metadata
-  bool mIsEncrypted;
+  bool IsEncrypted() const
+  {
+    return !mInitDatas.IsEmpty();
+  }
+
+  template<typename AInitDatas>
+  void AddInitData(const nsAString& aType, AInitDatas&& aInitData)
+  {
+    mInitDatas.AppendElement(InitData(aType, Forward<AInitDatas>(aInitData)));
+  }
+
+  void AddInitData(const EncryptionInfo& aInfo)
+  {
+    mInitDatas.AppendElements(aInfo.mInitDatas);
+  }
+
+  // One 'InitData' per encrypted buffer.
+  InitDatas mInitDatas;
 };
 
 class MediaInfo {
 public:
   bool HasVideo() const
   {
     return mVideo.mHasVideo;
   }
 
   bool HasAudio() const
   {
     return mAudio.mHasAudio;
   }
 
   bool IsEncrypted() const
   {
-    return mCrypto.mIsEncrypted;
+    return mCrypto.IsEncrypted();
   }
 
   bool HasValidMedia() const
   {
     return HasVideo() || HasAudio();
   }
 
   // TODO: Store VideoInfo and AudioIndo in arrays to support multi-tracks.
--- a/dom/media/fmp4/MP4Reader.cpp
+++ b/dom/media/fmp4/MP4Reader.cpp
@@ -259,16 +259,44 @@ MP4Reader::Init(MediaDecoderReader* aClo
     sSetupPrefCache = true;
     Preferences::AddBoolVarCache(&sIsEMEEnabled, "media.eme.enabled", false);
     Preferences::AddBoolVarCache(&sDemuxSkipToNextKeyframe, "media.fmp4.demux-skip", true);
   }
 
   return NS_OK;
 }
 
+#ifdef MOZ_EME
+class DispatchKeyNeededEvent : public nsRunnable {
+public:
+  DispatchKeyNeededEvent(AbstractMediaDecoder* aDecoder,
+                         nsTArray<uint8_t>& aInitData,
+                         const nsString& aInitDataType)
+    : mDecoder(aDecoder)
+    , mInitData(aInitData)
+    , mInitDataType(aInitDataType)
+  {
+  }
+  NS_IMETHOD Run() {
+    // Note: Null check the owner, as the decoder could have been shutdown
+    // since this event was dispatched.
+    MediaDecoderOwner* owner = mDecoder->GetOwner();
+    if (owner) {
+      owner->DispatchEncrypted(mInitData, mInitDataType);
+    }
+    mDecoder = nullptr;
+    return NS_OK;
+  }
+private:
+  nsRefPtr<AbstractMediaDecoder> mDecoder;
+  nsTArray<uint8_t> mInitData;
+  nsString mInitDataType;
+};
+#endif // MOZ_EME
+
 void MP4Reader::RequestCodecResource() {
   if (mVideo.mDecoder) {
     mVideo.mDecoder->AllocateMediaResources();
   }
 }
 
 bool MP4Reader::IsWaitingMediaResources() {
   return mVideo.mDecoder && mVideo.mDecoder->IsWaitingMediaResources();
@@ -363,17 +391,17 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo
     if (mAudio.mActive) {
       mAudio.mTrackDemuxer = new MP4AudioDemuxer(mDemuxer);
     }
     mCrypto = mDemuxer->Crypto();
 
     {
       MonitorAutoUnlock unlock(mDemuxerMonitor);
       ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
-      mInfo.mCrypto.mIsEncrypted = mIsEncrypted = mCrypto.valid;
+      mIsEncrypted = mCrypto.valid;
     }
 
     // Remember that we've initialized the demuxer, so that if we're decoding
     // an encrypted stream and we need to wait for a CDM to be set, we don't
     // need to reinit the demuxer.
     mDemuxerInitialized = true;
   } else if (mPlatform && !IsWaitingMediaResources()) {
     *aInfo = mInfo;
@@ -395,25 +423,31 @@ MP4Reader::ReadMetadata(MediaInfo* aInfo
     mVideo.mCallback = new DecoderCallback(this, kVideo);
 
     // Collect telemetry from h264 AVCC SPS.
     if (!mFoundSPSForTelemetry) {
       mFoundSPSForTelemetry = AccumulateSPSTelemetry(video.extra_data);
     }
   }
 
-  if (mIsEncrypted) {
+  if (mCrypto.valid) {
     nsTArray<uint8_t> initData;
     ExtractCryptoInitData(initData);
     if (initData.Length() == 0) {
       return NS_ERROR_FAILURE;
     }
 
-    mInfo.mCrypto.mInitData = initData;
-    mInfo.mCrypto.mType = NS_LITERAL_STRING("cenc");
+#ifdef MOZ_EME
+    // Try and dispatch 'encrypted'. Won't go if ready state still HAVE_NOTHING.
+    NS_DispatchToMainThread(
+      new DispatchKeyNeededEvent(mDecoder, initData, NS_LITERAL_STRING("cenc")));
+#endif // MOZ_EME
+    // Add init data to info, will get sent from HTMLMediaElement::MetadataLoaded
+    // (i.e., when transitioning from HAVE_NOTHING to HAVE_METADATA).
+    mInfo.mCrypto.AddInitData(NS_LITERAL_STRING("cenc"), Move(initData));
   }
 
   // Get the duration, and report it to the decoder if we have it.
   Microseconds duration;
   {
     MonitorAutoLock lock(mDemuxerMonitor);
     duration = mDemuxer->Duration();
   }
--- a/dom/media/fmp4/MP4Reader.h
+++ b/dom/media/fmp4/MP4Reader.h
@@ -270,18 +270,16 @@ private:
   // frames every time that DecodeVideoData() is called, and report the
   // delta there.
   uint64_t mLastReportedNumDecodedFrames;
 
   DecoderData& GetDecoderData(mp4_demuxer::TrackType aTrack);
 
   layers::LayersBackend mLayersBackendType;
 
-  nsTArray<nsTArray<uint8_t>> mInitDataEncountered;
-
   // True if we've read the streams' metadata.
   bool mDemuxerInitialized;
 
   // True if we've gathered telemetry from an SPS.
   bool mFoundSPSForTelemetry;
 
   // Synchronized by decoder monitor.
   bool mIsEncrypted;
--- a/dom/media/mediasource/MediaSourceReader.cpp
+++ b/dom/media/mediasource/MediaSourceReader.cpp
@@ -1063,32 +1063,16 @@ MediaSourceReader::MaybeNotifyHaveData()
     if (ended || haveVideo) {
       WaitPromise(MediaData::VIDEO_DATA).ResolveIfExists(MediaData::VIDEO_DATA, __func__);
     }
   }
   MSE_DEBUG("isSeeking=%d haveAudio=%d, haveVideo=%d ended=%d",
             IsSeeking(), haveAudio, haveVideo, ended);
 }
 
-static void
-CombineEncryptionData(EncryptionInfo& aTo, const EncryptionInfo& aFrom)
-{
-  if (!aFrom.mIsEncrypted) {
-    return;
-  }
-  aTo.mIsEncrypted = true;
-
-  if (!aTo.mType.IsEmpty() && !aTo.mType.Equals(aFrom.mType)) {
-    NS_WARNING("mismatched encryption types");
-  }
-
-  aTo.mType = aFrom.mType;
-  aTo.mInitData.AppendElements(aFrom.mInitData);
-}
-
 nsresult
 MediaSourceReader::ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
 {
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
 
   MSE_DEBUG("tracks=%u/%u audio=%p video=%p",
             mEssentialTrackBuffers.Length(), mTrackBuffers.Length(),
             mAudioTrack.get(), mVideoTrack.get());
@@ -1102,30 +1086,30 @@ MediaSourceReader::ReadMetadata(MediaInf
 
   if (mAudioTrack) {
     MOZ_ASSERT(mAudioTrack->IsReady());
     mAudioSourceDecoder = mAudioTrack->Decoders()[0];
 
     const MediaInfo& info = GetAudioReader()->GetMediaInfo();
     MOZ_ASSERT(info.HasAudio());
     mInfo.mAudio = info.mAudio;
-    CombineEncryptionData(mInfo.mCrypto, info.mCrypto);
+    mInfo.mCrypto.AddInitData(info.mCrypto);
     MSE_DEBUG("audio reader=%p duration=%lld",
               mAudioSourceDecoder.get(),
               mAudioSourceDecoder->GetReader()->GetDecoder()->GetMediaDuration());
   }
 
   if (mVideoTrack) {
     MOZ_ASSERT(mVideoTrack->IsReady());
     mVideoSourceDecoder = mVideoTrack->Decoders()[0];
 
     const MediaInfo& info = GetVideoReader()->GetMediaInfo();
     MOZ_ASSERT(info.HasVideo());
     mInfo.mVideo = info.mVideo;
-    CombineEncryptionData(mInfo.mCrypto, info.mCrypto);
+    mInfo.mCrypto.AddInitData(info.mCrypto);
     MSE_DEBUG("video reader=%p duration=%lld",
               GetVideoReader(),
               GetVideoReader()->GetDecoder()->GetMediaDuration());
   }
 
   *aInfo = mInfo;
   *aTags = nullptr; // TODO: Handle metadata.
 
--- a/dom/media/test/manifest.js
+++ b/dom/media/test/manifest.js
@@ -659,16 +659,17 @@ var gEMETests = [
       }
     ],
     keys: {
       // "keyid" : "key"
       "7e571d037e571d037e571d037e571d03" : "7e5733337e5733337e5733337e573333",
       "7e571d047e571d047e571d047e571d04" : "7e5744447e5744447e5744447e574444",
     },
     sessionType:"temporary",
+    sessionCount:1,
     duration:1.60,
   },
   {
     name:"bipbop-cenc-videoinit.mp4",
     tracks: [
       {
         name:"video",
         type:"video/mp4; codecs=\"avc1.64000d\"",
@@ -679,16 +680,17 @@ var gEMETests = [
       }
     ],
     keys: {
       // "keyid" : "key"
       "7e571d037e571d037e571d037e571d03" : "7e5733337e5733337e5733337e573333",
       "7e571d047e571d047e571d047e571d04" : "7e5744447e5744447e5744447e574444",
     },
     sessionType:"temporary",
+    sessionCount:1,
     crossOrigin:true,
     duration:1.60,
   },
   {
     name:"bipbop-cenc-videoinit.mp4",
     tracks: [
       {
         name:"audio",
@@ -709,16 +711,17 @@ var gEMETests = [
       },
     ],
     keys: {
       // "keyid" : "key"
       "7e571d037e571d037e571d037e571d03" : "7e5733337e5733337e5733337e573333",
       "7e571d047e571d047e571d047e571d04" : "7e5744447e5744447e5744447e574444",
     },
     sessionType:"temporary",
+    sessionCount:2,
     duration:1.60,
   },
   {
     name:"bipbop-cenc-videoinit.mp4",
     tracks: [
       {
         name:"audio",
         type:"audio/mp4; codecs=\"mp4a.40.2\"",
@@ -738,16 +741,17 @@ var gEMETests = [
       },
     ],
     keys: {
       // "keyid" : "key"
       "7e571d037e571d037e571d037e571d03" : "7e5733337e5733337e5733337e573333",
       "7e571d047e571d047e571d047e571d04" : "7e5744447e5744447e5744447e574444",
     },
     sessionType:"temporary",
+    sessionCount:2,
     crossOrigin:true,
     duration:1.60,
   },
 ];
 
 var gEMENonMSEFailTests = [
   {
     name:"short-cenc.mp4",
--- a/dom/media/test/test_eme_playback.html
+++ b/dom/media/test/test_eme_playback.html
@@ -43,35 +43,37 @@ function startTest(test, token)
     {
       onsessioncreated: function(session) {
         sessions.push(session);
         session.addEventListener("keystatuseschange", KeysChangeFunc(session, test.keys, token), false);
       }
     }
   );
 
-  var gotEncrypted = false;
+  var gotEncrypted = 0;
   var gotPlaying = false;
 
   v.addEventListener("encrypted", function(ev) {
-    gotEncrypted = true;
+    gotEncrypted += 1;
   });
 
   v.addEventListener("playing", function () { gotPlaying = true; });
 
   v.addEventListener("loadedmetadata", function() {
     ok(SpecialPowers.do_lookupGetter(v, "isEncrypted").apply(v),
        TimeStamp(token) + " isEncrypted should be true");
     is(v.isEncrypted, undefined, "isEncrypted should not be accessible from content");
   });
 
   v.addEventListener("ended", function(ev) {
     ok(true, TimeStamp(token) + " got ended event");
 
-    ok(gotEncrypted, TimeStamp(token) + " encrypted event should have fired");
+    is(gotEncrypted, test.sessionCount,
+       TimeStamp(token) + " encrypted events expected: " + test.sessionCount
+       + ", actual: " + gotEncrypted);
     ok(gotPlaying, TimeStamp(token) + " playing event should have fired");
 
     ok(Math.abs(test.duration - v.duration) < 0.1,
        TimeStamp(token) + " Duration of video should be corrrect");
     ok(Math.abs(test.duration - v.currentTime) < 0.1,
        TimeStamp(token) + " Current time should be same as duration");
 
     // Verify all sessions had all keys went sent the to the CDM usable, and thus
--- a/dom/media/webaudio/test/test_mediaElementAudioSourceNodeCrossOrigin.html
+++ b/dom/media/webaudio/test/test_mediaElementAudioSourceNodeCrossOrigin.html
@@ -6,16 +6,19 @@
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
 </head>
 <body>
 <pre id="test">
 <script class="testbody" type="text/javascript">
 SimpleTest.waitForExplicitFinish();
 
+// Turn off the authentication dialog blocking for this test.
+SpecialPowers.setIntPref("network.auth.allow-subresource-auth", 2)
+
 var tests = [
   // Not the same origin no CORS asked for, should have silence
   { url: "http://example.org:80/tests/dom/media/webaudio/test/small-shot.ogg",
     cors: null,
     expectSilence: true },
   // Same origin, should have sound
   { url: "small-shot.ogg",
     cors: null,
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -785,28 +785,27 @@ NPBool nsPluginInstanceOwner::ConvertPoi
   nsPoint windowPosition = AsNsPoint(rootWidget->GetWindowPosition()) / scaleFactor;
 
   // Window size is tab size + chrome size.
   nsIntRect tabContentBounds;
   NS_ENSURE_SUCCESS(puppetWidget->GetBounds(tabContentBounds), false);
   tabContentBounds.ScaleInverseRoundOut(scaleFactor);
   int32_t windowH = tabContentBounds.height + int(chromeSize.y);
 
-  // This is actually relative to window-chrome.
   nsPoint pluginPosition = AsNsPoint(pluginFrame->GetScreenRect().TopLeft());
 
   // Convert (sourceX, sourceY) to 'real' (not PuppetWidget) screen space.
   // In OSX, the Y-axis increases upward, which is the reverse of ours.
   // We want OSX coordinates for window and screen so those equations are swapped.
   nsPoint sourcePoint(sourceX, sourceY);
   nsPoint screenPoint;
   switch (sourceSpace) {
     case NPCoordinateSpacePlugin:
-      screenPoint = sourcePoint + pluginFrame->GetContentRectRelativeToSelf().TopLeft() +
-        chromeSize + pluginPosition + windowPosition;
+      screenPoint = sourcePoint + pluginPosition +
+        pluginFrame->GetContentRectRelativeToSelf().TopLeft() / nsPresContext::AppUnitsPerCSSPixel();
       break;
     case NPCoordinateSpaceWindow:
       screenPoint = nsPoint(sourcePoint.x, windowH-sourcePoint.y) +
         windowPosition;
       break;
     case NPCoordinateSpaceFlippedWindow:
       screenPoint = sourcePoint + windowPosition;
       break;
@@ -819,18 +818,18 @@ NPBool nsPluginInstanceOwner::ConvertPoi
     default:
       return false;
   }
 
   // Convert from screen to dest space.
   nsPoint destPoint;
   switch (destSpace) {
     case NPCoordinateSpacePlugin:
-      destPoint = screenPoint - pluginFrame->GetContentRectRelativeToSelf().TopLeft() -
-        chromeSize - pluginPosition - windowPosition;
+      destPoint = screenPoint - pluginPosition -
+        pluginFrame->GetContentRectRelativeToSelf().TopLeft() / nsPresContext::AppUnitsPerCSSPixel();
       break;
     case NPCoordinateSpaceWindow:
       destPoint = screenPoint - windowPosition;
       destPoint.y = windowH - destPoint.y;
       break;
     case NPCoordinateSpaceFlippedWindow:
       destPoint = screenPoint - windowPosition;
       break;
--- a/dom/vr/VRDevice.cpp
+++ b/dom/vr/VRDevice.cpp
@@ -12,40 +12,119 @@
 #include "gfxVR.h"
 #include "nsIFrame.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace dom {
 
-VRFieldOfView*
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRFieldOfViewReadOnly, mParent)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRFieldOfViewReadOnly, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRFieldOfViewReadOnly, Release)
+
+JSObject*
+VRFieldOfViewReadOnly::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return VRFieldOfViewReadOnlyBinding::Wrap(aCx, this, aGivenProto);
+}
+
+already_AddRefed<VRFieldOfView>
 VRFieldOfView::Constructor(const GlobalObject& aGlobal, const VRFieldOfViewInit& aParams,
                            ErrorResult& aRV)
 {
-  return new VRFieldOfView(aParams.mUpDegrees, aParams.mRightDegrees,
-                           aParams.mDownDegrees, aParams.mLeftDegrees);
+  nsRefPtr<VRFieldOfView> fov =
+    new VRFieldOfView(aGlobal.GetAsSupports(),
+                      aParams.mUpDegrees, aParams.mRightDegrees,
+                      aParams.mDownDegrees, aParams.mLeftDegrees);
+  return fov.forget();
 }
 
-VRFieldOfView*
+already_AddRefed<VRFieldOfView>
 VRFieldOfView::Constructor(const GlobalObject& aGlobal,
                            double aUpDegrees, double aRightDegrees,
                            double aDownDegrees, double aLeftDegrees,
                            ErrorResult& aRV)
 {
-  return new VRFieldOfView(aUpDegrees, aRightDegrees, aDownDegrees,
-                           aLeftDegrees);
+  nsRefPtr<VRFieldOfView> fov =
+    new VRFieldOfView(aGlobal.GetAsSupports(),
+                      aUpDegrees, aRightDegrees, aDownDegrees,
+                      aLeftDegrees);
+  return fov.forget();
+}
+
+JSObject*
+VRFieldOfView::WrapObject(JSContext* aCx,
+                          JS::Handle<JSObject*> aGivenProto)
+{
+  return VRFieldOfViewBinding::Wrap(aCx, this, aGivenProto);
+}
+
+NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VREyeParameters, mParent, mMinFOV, mMaxFOV, mRecFOV, mCurFOV, mEyeTranslation, mRenderRect)
+NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VREyeParameters, AddRef)
+NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VREyeParameters, Release)
+
+VREyeParameters::VREyeParameters(nsISupports* aParent,
+                                 const gfx::VRFieldOfView& aMinFOV,
+                                 const gfx::VRFieldOfView& aMaxFOV,
+                                 const gfx::VRFieldOfView& aRecFOV,
+                                 const gfx::Point3D& aEyeTranslation,
+                                 const gfx::VRFieldOfView& aCurFOV,
+                                 const gfx::IntRect& aRenderRect)
+  : mParent(aParent)
+{
+  mMinFOV = new VRFieldOfView(aParent, aMinFOV);
+  mMaxFOV = new VRFieldOfView(aParent, aMaxFOV);
+  mRecFOV = new VRFieldOfView(aParent, aRecFOV);
+  mCurFOV = new VRFieldOfView(aParent, aCurFOV);
+
+  mEyeTranslation = new DOMPoint(aParent, aEyeTranslation.x, aEyeTranslation.y, aEyeTranslation.z, 0.0);
+  mRenderRect = new DOMRect(aParent, aRenderRect.x, aRenderRect.y, aRenderRect.width, aRenderRect.height);
 }
 
-bool
-VRFieldOfView::WrapObject(JSContext* aCx,
-                          JS::Handle<JSObject*> aGivenProto,
-                          JS::MutableHandle<JSObject*> aReflector)
+VRFieldOfView*
+VREyeParameters::MinimumFieldOfView()
+{
+  return mMinFOV;
+}
+
+VRFieldOfView*
+VREyeParameters::MaximumFieldOfView()
+{
+  return mMaxFOV;
+}
+
+VRFieldOfView*
+VREyeParameters::RecommendedFieldOfView()
 {
-  return VRFieldOfViewBinding::Wrap(aCx, this, aGivenProto, aReflector);
+  return mRecFOV;
+}
+
+VRFieldOfView*
+VREyeParameters::CurrentFieldOfView()
+{
+  return mCurFOV;
+}
+
+DOMPoint*
+VREyeParameters::EyeTranslation()
+{
+  return mEyeTranslation;
+}
+
+DOMRect*
+VREyeParameters::RenderRect()
+{
+  return mRenderRect;
+}
+
+JSObject*
+VREyeParameters::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+{
+  return VREyeParametersBinding::Wrap(aCx, this, aGivenProto);
 }
 
 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(VRPositionState, mParent)
 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(VRPositionState, AddRef)
 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(VRPositionState, Release)
 
 VRPositionState::VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorState& aState)
   : mParent(aParent)
@@ -121,57 +200,40 @@ HMDVRDevice::WrapObject(JSContext* aCx, 
 }
 
 /* virtual */ JSObject*
 PositionSensorVRDevice::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return PositionSensorVRDeviceBinding::Wrap(aCx, this, aGivenProto);
 }
 
-static void
-ReleaseHMDInfoRef(void *, nsIAtom*, void *aPropertyValue, void *)
-{
-  if (aPropertyValue) {
-    static_cast<VRHMDInfo*>(aPropertyValue)->Release();
-  }
-}
-
-void
-HMDVRDevice::XxxToggleElementVR(Element& aElement)
-{
-  VRHMDInfo* hmdPtr = static_cast<VRHMDInfo*>(aElement.GetProperty(nsGkAtoms::vr_state));
-  if (hmdPtr) {
-    aElement.DeleteProperty(nsGkAtoms::vr_state);
-    return;
-  }
-
-  nsRefPtr<VRHMDInfo> hmdRef = mHMD;
-  aElement.SetProperty(nsGkAtoms::vr_state, hmdRef.forget().take(),
-                       ReleaseHMDInfoRef,
-                       true);
-}
-
 namespace {
 
-gfx::VRHMDInfo::Eye
-EyeToEye(const VREye& aEye)
-{
-  return aEye == VREye::Left ? gfx::VRHMDInfo::Eye_Left : gfx::VRHMDInfo::Eye_Right;
-}
-
 class HMDInfoVRDevice : public HMDVRDevice
 {
 public:
   HMDInfoVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD)
     : HMDVRDevice(aParent, aHMD)
   {
     // XXX TODO use real names/IDs
-    mHWID.AppendPrintf("HMDInfo-0x%llx", aHMD);
-    mDeviceId.AssignLiteral("somedevid");
-    mDeviceName.AssignLiteral("HMD Device");
+    uint64_t hmdid = reinterpret_cast<uint64_t>(aHMD);
+
+    mHWID.Truncate();
+    mHWID.AppendPrintf("HMDInfo-0x%llx", hmdid);
+
+    mDeviceId.Truncate();
+    mDeviceId.AppendPrintf("HMDInfo-dev-0x%llx", hmdid);
+
+    if (aHMD->GetType() == VRHMDType::Oculus) {
+      mDeviceName.AssignLiteral("VR HMD Device (oculus)");
+    } else if (aHMD->GetType() == VRHMDType::Cardboard) {
+      mDeviceName.AssignLiteral("VR HMD Device (cardboard)");
+    } else {
+      mDeviceName.AssignLiteral("VR HMD Device (unknown)");
+    }
 
     mValid = true;
   }
 
   virtual ~HMDInfoVRDevice() { }
 
   /* If a field of view that is set to all 0's is passed in,
    * the recommended field of view for that eye is used.
@@ -188,116 +250,112 @@ public:
     if (left.IsZero())
       left = mHMD->GetRecommendedEyeFOV(VRHMDInfo::Eye_Left);
     if (right.IsZero())
       right = mHMD->GetRecommendedEyeFOV(VRHMDInfo::Eye_Right);
 
     mHMD->SetFOV(left, right, zNear, zFar);
   }
 
-  virtual already_AddRefed<DOMPoint> GetEyeTranslation(VREye aEye) override
-  {
-    gfx::Point3D p = mHMD->GetEyeTranslation(EyeToEye(aEye));
-
-    nsRefPtr<DOMPoint> obj = new DOMPoint(mParent, p.x, p.y, p.z, 0.0);
-    return obj.forget();
-  }
-
-  virtual VRFieldOfView* GetCurrentEyeFieldOfView(VREye aEye) override
-  {
-    return CopyFieldOfView(mHMD->GetEyeFOV(EyeToEye(aEye)));
-  }
-
-  virtual VRFieldOfView* GetRecommendedEyeFieldOfView(VREye aEye) override
+  virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye) override
   {
-    return CopyFieldOfView(mHMD->GetRecommendedEyeFOV(EyeToEye(aEye)));
-  }
-
-  virtual VRFieldOfView* GetMaximumEyeFieldOfView(VREye aEye) override
-  {
-    return CopyFieldOfView(mHMD->GetMaximumEyeFOV(EyeToEye(aEye)));
-  }
-
-  virtual already_AddRefed<DOMRect> GetRecommendedEyeRenderRect(VREye aEye) override
-  {
-    const IntSize& a(mHMD->SuggestedEyeResolution());
-    nsRefPtr<DOMRect> obj =
-      new DOMRect(mParent,
-                  (aEye == VREye::Left) ? 0 : a.width, 0,
-                  a.width, a.height);
-    return obj.forget();
+    gfx::IntSize sz(mHMD->SuggestedEyeResolution());
+    gfx::VRHMDInfo::Eye eye = aEye == VREye::Left ? gfx::VRHMDInfo::Eye_Left : gfx::VRHMDInfo::Eye_Right;
+    nsRefPtr<VREyeParameters> params =
+      new VREyeParameters(mParent,
+                          gfx::VRFieldOfView(15, 15, 15, 15), // XXX min?
+                          mHMD->GetMaximumEyeFOV(eye),
+                          mHMD->GetRecommendedEyeFOV(eye),
+                          mHMD->GetEyeTranslation(eye),
+                          mHMD->GetEyeFOV(eye),
+                          gfx::IntRect((aEye == VREye::Left) ? 0 : sz.width, 0, sz.width, sz.height));
+    return params.forget();
   }
 
 protected:
-  VRFieldOfView*
-  CopyFieldOfView(const gfx::VRFieldOfView& aSrc)
-  {
-    return new VRFieldOfView(aSrc.upDegrees, aSrc.rightDegrees,
-                             aSrc.downDegrees, aSrc.leftDegrees);
-  }
 };
 
 class HMDPositionVRDevice : public PositionSensorVRDevice
 {
 public:
   HMDPositionVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD)
     : PositionSensorVRDevice(aParent)
     , mHMD(aHMD)
     , mTracking(false)
   {
     // XXX TODO use real names/IDs
-    mHWID.AppendPrintf("HMDInfo-0x%llx", aHMD);
-    mDeviceId.AssignLiteral("somedevid");
-    mDeviceName.AssignLiteral("HMD Position Device");
+    uint64_t hmdid = reinterpret_cast<uint64_t>(aHMD);
+
+    mHWID.Truncate();
+    mHWID.AppendPrintf("HMDInfo-0x%llx", hmdid);
+
+    mDeviceId.Truncate();
+    mDeviceId.AppendPrintf("HMDInfo-dev-0x%llx", hmdid);
+
+    if (aHMD->GetType() == VRHMDType::Oculus) {
+      mDeviceName.AssignLiteral("VR Position Device (oculus)");
+    } else if (aHMD->GetType() == VRHMDType::Cardboard) {
+      mDeviceName.AssignLiteral("VR Position Device (cardboard)");
+    } else {
+      mDeviceName.AssignLiteral("VR Position Device (unknown)");
+    }
 
     mValid = true;
   }
 
   ~HMDPositionVRDevice()
   {
     if (mTracking) {
       mHMD->StopSensorTracking();
     }
   }
 
-  virtual already_AddRefed<VRPositionState> GetState(double timeOffset) override
+  virtual already_AddRefed<VRPositionState> GetState() override
   {
     if (!mTracking) {
       mHMD->StartSensorTracking();
       mTracking = true;
     }
 
-    gfx::VRHMDSensorState state = mHMD->GetSensorState(timeOffset);
+    gfx::VRHMDSensorState state = mHMD->GetSensorState();
     nsRefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
 
     return obj.forget();
   }
 
-  virtual void ZeroSensor() override
+  virtual already_AddRefed<VRPositionState> GetImmediateState() override
+  {
+    if (!mTracking) {
+      mHMD->StartSensorTracking();
+      mTracking = true;
+    }
+
+    gfx::VRHMDSensorState state = mHMD->GetSensorState();
+    nsRefPtr<VRPositionState> obj = new VRPositionState(mParent, state);
+
+    return obj.forget();
+  }
+
+  virtual void ResetSensor() override
   {
     mHMD->ZeroSensor();
   }
 
 protected:
   nsRefPtr<gfx::VRHMDInfo> mHMD;
   bool mTracking;
 };
 
 } // namespace
 
 bool
 VRDevice::CreateAllKnownVRDevices(nsISupports *aParent, nsTArray<nsRefPtr<VRDevice>>& aDevices)
 {
-  if (!gfx::VRHMDManagerOculus::Init()) {
-    NS_WARNING("Failed to initialize Oculus HMD Manager");
-    return false;
-  }
-
   nsTArray<nsRefPtr<gfx::VRHMDInfo>> hmds;
-  gfx::VRHMDManagerOculus::GetOculusHMDs(hmds);
+  gfx::VRHMDManager::GetAllHMDs(hmds);
 
   for (size_t i = 0; i < hmds.Length(); ++i) {
     uint32_t sensorBits = hmds[i]->GetSupportedSensorStateBits();
     aDevices.AppendElement(new HMDInfoVRDevice(aParent, hmds[i]));
 
     if (sensorBits &
         (gfx::VRHMDInfo::State_Position | gfx::VRHMDInfo::State_Orientation))
     {
--- a/dom/vr/VRDevice.h
+++ b/dom/vr/VRDevice.h
@@ -21,71 +21,91 @@
 
 #include "gfxVR.h"
 
 namespace mozilla {
 namespace dom {
 
 class Element;
 
-class VRFieldOfViewReadOnly : public NonRefcountedDOMObject
+class VRFieldOfViewReadOnly : public nsWrapperCache
 {
 public:
-  VRFieldOfViewReadOnly(double aUpDegrees, double aRightDegrees,
+  VRFieldOfViewReadOnly(nsISupports* aParent,
+                        double aUpDegrees, double aRightDegrees,
                         double aDownDegrees, double aLeftDegrees)
-    : mUpDegrees(aUpDegrees)
+    : mParent(aParent)
+    , mUpDegrees(aUpDegrees)
     , mRightDegrees(aRightDegrees)
     , mDownDegrees(aDownDegrees)
     , mLeftDegrees(aLeftDegrees)
   {
   }
 
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRFieldOfViewReadOnly)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRFieldOfViewReadOnly)
+
   double UpDegrees() const { return mUpDegrees; }
   double RightDegrees() const { return mRightDegrees; }
   double DownDegrees() const { return mDownDegrees; }
   double LeftDegrees() const { return mLeftDegrees; }
 
+  nsISupports* GetParentObject() const { return mParent; }
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+
 protected:
+  virtual ~VRFieldOfViewReadOnly() {}
+
+  nsCOMPtr<nsISupports> mParent;
+
   double mUpDegrees;
   double mRightDegrees;
   double mDownDegrees;
   double mLeftDegrees;
 };
 
 class VRFieldOfView final : public VRFieldOfViewReadOnly
 {
 public:
-  explicit VRFieldOfView(double aUpDegrees = 0.0, double aRightDegrees = 0.0,
-                         double aDownDegrees = 0.0, double aLeftDegrees = 0.0)
-    : VRFieldOfViewReadOnly(aUpDegrees, aRightDegrees, aDownDegrees, aLeftDegrees)
+  VRFieldOfView(nsISupports* aParent, const gfx::VRFieldOfView& aSrc)
+    : VRFieldOfViewReadOnly(aParent,
+                            aSrc.upDegrees, aSrc.rightDegrees,
+                            aSrc.downDegrees, aSrc.leftDegrees)
   {}
 
-  static VRFieldOfView*
+  explicit VRFieldOfView(nsISupports* aParent,
+                         double aUpDegrees = 0.0, double aRightDegrees = 0.0,
+                         double aDownDegrees = 0.0, double aLeftDegrees = 0.0)
+    : VRFieldOfViewReadOnly(aParent,
+                            aUpDegrees, aRightDegrees, aDownDegrees, aLeftDegrees)
+  {}
+
+  static already_AddRefed<VRFieldOfView>
   Constructor(const GlobalObject& aGlobal, const VRFieldOfViewInit& aParams,
               ErrorResult& aRv);
 
-  static VRFieldOfView*
+  static already_AddRefed<VRFieldOfView>
   Constructor(const GlobalObject& aGlobal,
               double aUpDegrees, double aRightDegrees,
               double aDownDegrees, double aLeftDegrees,
               ErrorResult& aRv);
 
-  bool WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto, JS::MutableHandle<JSObject*> aReflector);
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   void SetUpDegrees(double aVal) { mUpDegrees = aVal; }
   void SetRightDegrees(double aVal) { mRightDegrees = aVal; }
   void SetDownDegrees(double aVal) { mDownDegrees = aVal; }
   void SetLeftDegrees(double aVal) { mLeftDegrees = aVal; }
 };
 
 class VRPositionState final : public nsWrapperCache
 {
   ~VRPositionState() {}
 public:
-  explicit VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
+  VRPositionState(nsISupports* aParent, const gfx::VRHMDSensorState& aState);
 
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VRPositionState)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VRPositionState)
 
   double TimeStamp() const { return mTimeStamp; }
 
   bool HasPosition() const { return mPosition != nullptr; }
   DOMPoint* GetPosition() const { return mPosition; }
@@ -112,16 +132,53 @@ protected:
   nsRefPtr<DOMPoint> mLinearVelocity;
   nsRefPtr<DOMPoint> mLinearAcceleration;
 
   nsRefPtr<DOMPoint> mOrientation;
   nsRefPtr<DOMPoint> mAngularVelocity;
   nsRefPtr<DOMPoint> mAngularAcceleration;
 };
 
+class VREyeParameters final : public nsWrapperCache
+{
+public:
+  VREyeParameters(nsISupports* aParent,
+                  const gfx::VRFieldOfView& aMinFOV,
+                  const gfx::VRFieldOfView& aMaxFOV,
+                  const gfx::VRFieldOfView& aRecFOV,
+                  const gfx::Point3D& aEyeTranslation,
+                  const gfx::VRFieldOfView& aCurFOV,
+                  const gfx::IntRect& aRenderRect);
+
+  NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(VREyeParameters)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(VREyeParameters)
+
+  VRFieldOfView* MinimumFieldOfView();
+  VRFieldOfView* MaximumFieldOfView();
+  VRFieldOfView* RecommendedFieldOfView();
+  DOMPoint* EyeTranslation();
+
+  VRFieldOfView* CurrentFieldOfView();
+  DOMRect* RenderRect();
+
+  nsISupports* GetParentObject() const { return mParent; }
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
+protected:
+  ~VREyeParameters() {}
+
+  nsCOMPtr<nsISupports> mParent;
+
+  nsRefPtr<VRFieldOfView> mMinFOV;
+  nsRefPtr<VRFieldOfView> mMaxFOV;
+  nsRefPtr<VRFieldOfView> mRecFOV;
+  nsRefPtr<DOMPoint> mEyeTranslation;
+  nsRefPtr<VRFieldOfView> mCurFOV;
+  nsRefPtr<DOMRect> mRenderRect;
+};
+
 class VRDevice : public nsISupports,
                  public nsWrapperCache
 {
 public:
   // create new VRDevice objects for all known underlying gfx::vr devices
   static bool CreateAllKnownVRDevices(nsISupports *aParent, nsTArray<nsRefPtr<VRDevice>>& aDevices);
 
 public:
@@ -171,49 +228,45 @@ protected:
   VRDeviceType mType;
 
   bool mValid;
 };
 
 class HMDVRDevice : public VRDevice
 {
 public:
-  virtual already_AddRefed<DOMPoint> GetEyeTranslation(VREye aEye) = 0;
+  virtual already_AddRefed<VREyeParameters> GetEyeParameters(VREye aEye) = 0;
 
   virtual void SetFieldOfView(const VRFieldOfViewInit& aLeftFOV,
                               const VRFieldOfViewInit& aRightFOV,
                               double zNear, double zFar) = 0;
-  virtual VRFieldOfView* GetCurrentEyeFieldOfView(VREye aEye) = 0;
-  virtual VRFieldOfView* GetRecommendedEyeFieldOfView(VREye aEye) = 0;
-  virtual VRFieldOfView* GetMaximumEyeFieldOfView(VREye aEye) = 0;
-  virtual already_AddRefed<DOMRect> GetRecommendedEyeRenderRect(VREye aEye) = 0;
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
-  void XxxToggleElementVR(Element& aElement);
-
   gfx::VRHMDInfo *GetHMD() { return mHMD.get(); }
 
 protected:
   HMDVRDevice(nsISupports* aParent, gfx::VRHMDInfo* aHMD)
     : VRDevice(aParent, VRDevice::HMD)
     , mHMD(aHMD)
   { }
 
   virtual ~HMDVRDevice() { }
 
   nsRefPtr<gfx::VRHMDInfo> mHMD;
 };
 
 class PositionSensorVRDevice : public VRDevice
 {
 public:
-  virtual already_AddRefed<VRPositionState> GetState(double timeOffset) = 0;
+  virtual already_AddRefed<VRPositionState> GetState() = 0;
 
-  virtual void ZeroSensor() = 0;
+  virtual already_AddRefed<VRPositionState> GetImmediateState() = 0;
+
+  virtual void ResetSensor() = 0;
 
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 protected:
   explicit PositionSensorVRDevice(nsISupports* aParent)
     : VRDevice(aParent, VRDevice::PositionSensor)
   { }
 
--- a/dom/webidl/VRDevice.webidl
+++ b/dom/webidl/VRDevice.webidl
@@ -47,86 +47,84 @@ interface VRPositionState {
 
   readonly attribute boolean hasOrientation;
   // XXX should be DOMQuaternion as soon as we add that
   readonly attribute DOMPoint? orientation;
   readonly attribute DOMPoint? angularVelocity;
   readonly attribute DOMPoint? angularAcceleration;
 };
 
+[Pref="dom.vr.enabled",
+ HeaderFile="mozilla/dom/VRDevice.h"]
+interface VREyeParameters {
+  /* These values are expected to be static per-device/per-user */
+  [Constant, Cached] readonly attribute VRFieldOfView minimumFieldOfView;
+  [Constant, Cached] readonly attribute VRFieldOfView maximumFieldOfView;
+  [Constant, Cached] readonly attribute VRFieldOfView recommendedFieldOfView;
+  [Constant, Cached] readonly attribute DOMPoint eyeTranslation;
+
+  /* These values will vary after a FOV has been set */
+  [Constant, Cached] readonly attribute VRFieldOfView currentFieldOfView;
+  [Constant, Cached] readonly attribute DOMRect renderRect;
+};
+
 [Pref="dom.vr.enabled"]
 interface VRDevice {
   /**
    * An identifier for the distinct hardware unit that this
    * VR Device is a part of.  All VRDevice/Sensors that come
    * from the same hardware will have the same hardwareId
    */
-  [Pure] readonly attribute DOMString hardwareUnitId;
+  [Constant] readonly attribute DOMString hardwareUnitId;
 
   /**
    * An identifier for this distinct sensor/device on a physical
    * hardware device.  This shouldn't change across browser
    * restrats, allowing configuration data to be saved based on it.
    */
-  [Pure] readonly attribute DOMString deviceId;
+  [Constant] readonly attribute DOMString deviceId;
 
   /**
    * a device name, a user-readable name identifying it
    */
-  [Pure] readonly attribute DOMString deviceName;
+  [Constant] readonly attribute DOMString deviceName;
 };
 
 [Pref="dom.vr.enabled",
  HeaderFile="mozilla/dom/VRDevice.h"]
 interface HMDVRDevice : VRDevice {
-  /* The translation that should be applied to the view matrix for rendering each eye */
-  DOMPoint getEyeTranslation(VREye whichEye);
-
-  // the FOV that the HMD was configured with
-  [NewObject]
-  VRFieldOfView getCurrentEyeFieldOfView(VREye whichEye);
-
-  // the recommended FOV, per eye.
-  [NewObject]
-  VRFieldOfView getRecommendedEyeFieldOfView(VREye whichEye);
-
-  // the maximum FOV, per eye.  Above this, rendering will look broken.
-  [NewObject]
-  VRFieldOfView getMaximumEyeFieldOfView(VREye whichEye);
+  // Return the current VREyeParameters for the given eye
+  VREyeParameters getEyeParameters(VREye whichEye);
 
   // Set a field of view.  If either of the fields of view is null,
   // or if their values are all zeros, then the recommended field of view
   // for that eye will be used.
   void setFieldOfView(optional VRFieldOfViewInit leftFOV,
                       optional VRFieldOfViewInit rightFOV,
                       optional double zNear = 0.01,
                       optional double zFar = 10000.0);
-
-  // return a recommended rect for this eye.  Only useful for Canvas rendering,
-  // the x/y coordinates will be the location in the canvas where this eye should
-  // begin, and the width/height are the dimensions.  Any canvas in the appropriate
-  // ratio will work.
-  DOMRect getRecommendedEyeRenderRect(VREye whichEye);
-
-  // hack for testing
-  void xxxToggleElementVR(Element element);
 };
 
 [Pref="dom.vr.enabled" ,
  HeaderFile="mozilla/dom/VRDevice.h"]
 interface PositionSensorVRDevice : VRDevice {
   /*
-   * Return a VRPositionState dictionary containing the state of this position sensor,
-   * at an optional past time or predicted for a future time if timeOffset is != 0.
+   * Return a VRPositionState dictionary containing the state of this position sensor
+   * for the current frame if within a requestAnimationFrame callback, or for the
+   * previous frame if not.
    *
    * The VRPositionState will contain the position, orientation, and velocity
    * and acceleration of each of these properties.  Use "hasPosition" and "hasOrientation"
    * to check if the associated members are valid; if these are false, those members
    * will be null.
    */
-  [NewObject]
-  VRPositionState getState(optional double timeOffset = 0.0);
+  [NewObject] VRPositionState getState();
 
-  /* Zero this sensor, treating its current position and orientation
+  /*
+   * Return the current instantaneous sensor state.
+   */
+  [NewObject] VRPositionState getImmediateState();
+
+  /* Reset this sensor, treating its current position and orientation
    * as the "origin/zero" values.
    */
-  void zeroSensor();
+  void resetSensor();
 };
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -4218,17 +4218,18 @@ private:
 
 NS_IMPL_ISUPPORTS(ReportDebuggerErrorRunnable, nsIRunnable)
 
 WorkerDebugger::WorkerDebugger(WorkerPrivate* aWorkerPrivate)
 : mMutex("WorkerDebugger::mMutex"),
   mCondVar(mMutex, "WorkerDebugger::mCondVar"),
   mWorkerPrivate(aWorkerPrivate),
   mIsEnabled(false),
-  mIsInitialized(false)
+  mIsInitialized(false),
+  mIsFrozen(false)
 {
   mWorkerPrivate->AssertIsOnParentThread();
 }
 
 WorkerDebugger::~WorkerDebugger()
 {
   MOZ_ASSERT(!mWorkerPrivate);
   MOZ_ASSERT(!mIsEnabled);
@@ -4273,16 +4274,31 @@ WorkerDebugger::GetIsChrome(bool* aResul
     return NS_ERROR_UNEXPECTED;
   }
 
   *aResult = mWorkerPrivate->IsChromeWorker();
   return NS_OK;
 }
 
 NS_IMETHODIMP
+WorkerDebugger::GetIsFrozen(bool* aResult)
+{
+  AssertIsOnMainThread();
+
+  MutexAutoLock lock(mMutex);
+
+  if (!mWorkerPrivate) {
+    return NS_ERROR_UNEXPECTED;
+  }
+
+  *aResult = mIsFrozen;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 WorkerDebugger::GetParent(nsIWorkerDebugger** aResult)
 {
   AssertIsOnMainThread();
 
   MutexAutoLock lock(mMutex);
 
   if (!mWorkerPrivate) {
     return NS_ERROR_UNEXPECTED;
@@ -4470,16 +4486,62 @@ WorkerDebugger::Disable()
       listeners[index]->OnClose();
     }
   }
 
   NotifyIsEnabled(false);
 }
 
 void
+WorkerDebugger::Freeze()
+{
+  mWorkerPrivate->AssertIsOnWorkerThread();
+
+  nsCOMPtr<nsIRunnable> runnable =
+    NS_NewRunnableMethod(this, &WorkerDebugger::FreezeOnMainThread);
+  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
+    NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL)));
+}
+
+void
+WorkerDebugger::FreezeOnMainThread()
+{
+  AssertIsOnMainThread();
+
+  mIsFrozen = true;
+
+  for (size_t index = 0; index < mListeners.Length(); ++index) {
+    mListeners[index]->OnFreeze();
+  }
+}
+
+void
+WorkerDebugger::Thaw()
+{
+  mWorkerPrivate->AssertIsOnWorkerThread();
+
+  nsCOMPtr<nsIRunnable> runnable =
+    NS_NewRunnableMethod(this, &WorkerDebugger::ThawOnMainThread);
+  MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
+    NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL)));
+}
+
+void
+WorkerDebugger::ThawOnMainThread()
+{
+  AssertIsOnMainThread();
+
+  mIsFrozen = false;
+
+  for (size_t index = 0; index < mListeners.Length(); ++index) {
+    mListeners[index]->OnThaw();
+  }
+}
+
+void
 WorkerDebugger::PostMessageToDebugger(const nsAString& aMessage)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
 
   nsCOMPtr<nsIRunnable> runnable =
     NS_NewRunnableMethodWithArg<nsString>(this,
       &WorkerDebugger::PostMessageToDebuggerOnMainThread, nsString(aMessage));
   NS_DispatchToMainThread(runnable, NS_DISPATCH_NORMAL);
@@ -5688,27 +5750,29 @@ WorkerPrivate::RemainingRunTimeMS() cons
 bool
 WorkerPrivate::FreezeInternal(JSContext* aCx)
 {
   AssertIsOnWorkerThread();
 
   NS_ASSERTION(!mFrozen, "Already frozen!");
 
   mFrozen = true;
+  mDebugger->Freeze();
   return true;
 }
 
 bool
 WorkerPrivate::ThawInternal(JSContext* aCx)
 {
   AssertIsOnWorkerThread();
 
   NS_ASSERTION(mFrozen, "Not yet frozen!");
 
   mFrozen = false;
+  mDebugger->Thaw();
   return true;
 }
 
 void
 WorkerPrivate::TraceTimeouts(const TraceCallbacks& aCallbacks,
                              void* aClosure) const
 {
   AssertIsOnWorkerThread();
--- a/dom/workers/WorkerPrivate.h
+++ b/dom/workers/WorkerPrivate.h
@@ -722,16 +722,17 @@ class WorkerDebugger : public nsIWorkerD
   mozilla::CondVar mCondVar;
 
   // Protected by mMutex
   WorkerPrivate* mWorkerPrivate;
   bool mIsEnabled;
 
   // Only touched on the main thread.
   bool mIsInitialized;
+  bool mIsFrozen;
   nsTArray<nsCOMPtr<nsIWorkerDebuggerListener>> mListeners;
 
 public:
   explicit WorkerDebugger(WorkerPrivate* aWorkerPrivate);
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIWORKERDEBUGGER
 
@@ -743,30 +744,42 @@ public:
 
   void
   Enable();
 
   void
   Disable();
 
   void
+  Freeze();
+
+  void
+  Thaw();
+
+  void
   PostMessageToDebugger(const nsAString& aMessage);
 
   void
   ReportErrorToDebugger(const nsAString& aFilename, uint32_t aLineno,
                         const nsAString& aMessage);
 
 private:
   virtual
   ~WorkerDebugger();
 
   void
   NotifyIsEnabled(bool aIsEnabled);
 
   void
+  FreezeOnMainThread();
+
+  void
+  ThawOnMainThread();
+
+  void
   PostMessageToDebuggerOnMainThread(const nsAString& aMessage);
 
   void
   ReportErrorToDebuggerOnMainThread(const nsAString& aFilename,
                                     uint32_t aLineno,
                                     const nsAString& aMessage);
 };
 
--- a/dom/workers/nsIWorkerDebugger.idl
+++ b/dom/workers/nsIWorkerDebugger.idl
@@ -1,34 +1,40 @@
 #include "nsISupports.idl"
 
 interface nsIDOMWindow;
 
-[scriptable, uuid(55d54034-1573-4889-b1d9-93ba12fc33c7)]
+[scriptable, uuid(530db841-1b2c-485a-beeb-f2b1acb9714e)]
 interface nsIWorkerDebuggerListener : nsISupports
 {
   void onClose();
 
   void onError(in DOMString filename, in unsigned long lineno,
                in DOMString message);
 
+  void onFreeze();
+
   void onMessage(in DOMString message);
+
+  void onThaw();
 };
 
-[scriptable, builtinclass, uuid(28e0a60c-ff10-446c-8c2a-5fbdc01394ea)]
+[scriptable, builtinclass, uuid(d7c73e54-3c41-4393-9d13-fa2ed4Ba6764)]
 interface nsIWorkerDebugger : nsISupports
 {
   const unsigned long TYPE_DEDICATED = 0;
   const unsigned long TYPE_SHARED = 1;
   const unsigned long TYPE_SERVICE = 2;
 
   readonly attribute bool isClosed;
 
   readonly attribute bool isChrome;
 
+  readonly attribute bool isFrozen;
+
   readonly attribute nsIWorkerDebugger parent;
 
   readonly attribute unsigned long type;
 
   readonly attribute DOMString url;
 
   readonly attribute nsIDOMWindow window;
 
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/WorkerDebugger.isFrozen_iframe1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <script>
+      var worker = new Worker("WorkerDebugger.isFrozen_worker1.js");
+      worker.onmessage = function () {
+        parent.postMessage("ready", "*");
+      };
+    </script>
+  </head>
+  <body>
+    This is page 1.
+  </body>
+<html>
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/WorkerDebugger.isFrozen_iframe2.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <script>
+      var worker = new Worker("WorkerDebugger.isFrozen_worker2.js");
+      worker.onmessage = function () {
+        parent.postMessage("ready", "*");
+      };
+    </script>
+  </head>
+  <body>
+    This is page 2.
+  </body>
+<html>
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/WorkerDebugger.isFrozen_worker1.js
@@ -0,0 +1,5 @@
+"use strict";
+
+onmessage = function () {};
+
+postMessage("ready");
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/WorkerDebugger.isFrozen_worker2.js
@@ -0,0 +1,5 @@
+"use strict";
+
+onmessage = function () {};
+
+postMessage("ready");
--- a/dom/workers/test/chrome.ini
+++ b/dom/workers/test/chrome.ini
@@ -1,14 +1,18 @@
 [DEFAULT]
 skip-if = buildapp == 'b2g'
 support-files =
   WorkerDebugger.initialize_childWorker.js
   WorkerDebugger.initialize_debugger.js
   WorkerDebugger.initialize_worker.js
+  WorkerDebugger.isFrozen_iframe1.html
+  WorkerDebugger.isFrozen_iframe2.html
+  WorkerDebugger.isFrozen_worker1.js
+  WorkerDebugger.isFrozen_worker2.js
   WorkerDebugger.postMessage_childWorker.js
   WorkerDebugger.postMessage_debugger.js
   WorkerDebugger.postMessage_worker.js
   WorkerDebuggerGlobalScope.createSandbox_debugger.js
   WorkerDebuggerGlobalScope.createSandbox_sandbox.js
   WorkerDebuggerGlobalScope.createSandbox_worker.js
   WorkerDebuggerGlobalScope.enterEventLoop_childWorker.js
   WorkerDebuggerGlobalScope.enterEventLoop_debugger.js
@@ -42,16 +46,17 @@ support-files =
   file_worker.js
   jsm_url_worker.js
   workersDisabled_worker.js
   file_url.jsm
   bug1062920_worker.js
 
 [test_WorkerDebugger.xul]
 [test_WorkerDebugger.initialize.xul]
+[test_WorkerDebugger.isFrozen.xul]
 [test_WorkerDebugger.postMessage.xul]
 [test_WorkerDebuggerGlobalScope.createSandbox.xul]
 [test_WorkerDebuggerGlobalScope.enterEventLoop.xul]
 [test_WorkerDebuggerGlobalScope.reportError.xul]
 [test_WorkerDebuggerGlobalScope.setImmediate.xul]
 [test_WorkerDebuggerManager.xul]
 [test_bug883784.jsm]
 [test_bug883784.xul]
--- a/dom/workers/test/dom_worker_helper.js
+++ b/dom/workers/test/dom_worker_helper.js
@@ -125,16 +125,51 @@ function waitForDebuggerMessage(dbg, mes
         ok(true, "Should receive " + message + " message from debugger.");
         dbg.removeListener(this);
         resolve();
       }
     });
   });
 }
 
+function waitForDebuggerFreeze(dbg) {
+  return new Promise(function (resolve) {
+    dbg.addListener({
+      onFreeze: function () {
+        dbg.removeListener(this);
+        resolve();
+      }
+    });
+  });
+}
+
+function waitForDebuggerThaw(dbg) {
+  return new Promise(function (resolve) {
+    dbg.addListener({
+      onThaw: function () {
+        dbg.removeListener(this);
+        resolve();
+      }
+    });
+  });
+}
+
+function waitForWindowMessage(window, message) {
+  return new Promise(function (resolve) {
+    let onmessage = function (event) {
+      if (event.data !== event.data) {
+        return;
+      }
+      window.removeEventListener("message", onmessage, false);
+      resolve();
+    };
+    window.addEventListener("message", onmessage, false);
+  });
+}
+
 function waitForWorkerMessage(worker, message) {
   return new Promise(function (resolve) {
     worker.addEventListener("message", function onmessage(event) {
       if (event.data !== message) {
         return;
       }
       ok(true, "Should receive " + message + " message from worker.");
       worker.removeEventListener("message", onmessage);
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/test_WorkerDebugger.isFrozen.xul
@@ -0,0 +1,98 @@
+<?xml version="1.0"?>
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<window title="Test for WorkerDebugger.isFrozen"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        onload="test();">
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+  <script type="application/javascript" src="dom_worker_helper.js"/>
+
+  <script type="application/javascript">
+  <![CDATA[
+
+    const CACHE_SUBFRAMES = "browser.sessionhistory.cache_subframes";
+    const MAX_TOTAL_VIEWERS = "browser.sessionhistory.max_total_viewers";
+
+    const IFRAME1_URL = "WorkerDebugger.isFrozen_iframe1.html";
+    const IFRAME2_URL = "WorkerDebugger.isFrozen_iframe2.html";
+
+    const WORKER1_URL = "WorkerDebugger.isFrozen_worker1.js";
+    const WORKER2_URL = "WorkerDebugger.isFrozen_worker2.js";
+
+    function test() {
+      Task.spawn(function* () {
+        SimpleTest.waitForExplicitFinish();
+
+        var oldMaxTotalViewers = SpecialPowers.getIntPref(MAX_TOTAL_VIEWERS);
+
+        SpecialPowers.setBoolPref(CACHE_SUBFRAMES, true);
+        SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, 10);
+
+        let iframe = $("iframe");
+
+        let promise = waitForMultiple([
+          waitForRegister(WORKER1_URL),
+          waitForWindowMessage(window, "ready"),
+        ]);
+        iframe.src = IFRAME1_URL;
+        let [dbg1] = yield promise;
+        is(dbg1.isClosed, false,
+           "debugger for worker on page 1 should not be closed");
+        is(dbg1.isFrozen, false,
+           "debugger for worker on page 1 should not be frozen");
+
+        promise = waitForMultiple([
+          waitForDebuggerFreeze(dbg1),
+          waitForRegister(WORKER2_URL),
+          waitForWindowMessage(window, "ready"),
+        ]);
+        iframe.src = IFRAME2_URL;
+        let [_, dbg2] = yield promise;
+        is(dbg1.isClosed, false,
+           "debugger for worker on page 1 should not be closed");
+        is(dbg1.isFrozen, true,
+           "debugger for worker on page 1 should be frozen");
+        is(dbg2.isClosed, false,
+           "debugger for worker on page 2 should not be closed");
+        is(dbg2.isFrozen, false,
+           "debugger for worker on page 2 should not be frozen");
+
+        promise = waitForMultiple([
+          waitForDebuggerFreeze(dbg2),
+          waitForDebuggerThaw(dbg1),
+        ]);
+        iframe.contentWindow.history.back();
+        yield promise;
+        is(dbg1.isClosed, false,
+           "debugger for worker on page 1 should not be closed")
+        is(dbg1.isFrozen, false,
+           "debugger for worker on page 1 should not be frozen");
+        is(dbg2.isClosed, false,
+           "debugger for worker on page 2 should not be closed");
+        is(dbg2.isFrozen, true,
+           "debugger for worker on page 2 should be frozen");
+
+        SpecialPowers.clearUserPref(CACHE_SUBFRAMES);
+        SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, oldMaxTotalViewers);
+
+        SimpleTest.finish();
+      });
+    }
+
+  ]]>
+  </script>
+
+  <body xmlns="http://www.w3.org/1999/xhtml">
+    <p id="display"></p>
+    <div id="content" style="display:none;"></div>
+    <pre id="test"></pre>
+    <iframe id="iframe"></iframe>
+  </body>
+  <label id="test-result"/>
+</window>
--- a/embedding/browser/nsDocShellTreeOwner.cpp
+++ b/embedding/browser/nsDocShellTreeOwner.cpp
@@ -1447,19 +1447,25 @@ ChromeTooltipListener::sTooltipCallback(
       bool textFound = false;
 
       self->mTooltipTextProvider->GetNodeText(
           self->mPossibleTooltipNode, getter_Copies(tooltipText), &textFound);
 
       if (textFound) {
         nsString tipText(tooltipText);
         LayoutDeviceIntPoint screenDot = widget->WidgetToScreenOffset();
-        self->ShowTooltip(self->mMouseScreenX - screenDot.x,
-                          self->mMouseScreenY - screenDot.y,
-                          tipText);
+        double scaleFactor = 1.0;
+        if (shell->GetPresContext()) {
+          scaleFactor = double(nsPresContext::AppUnitsPerCSSPixel())/
+          shell->GetPresContext()->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom();
+        }
+        // ShowTooltip expects widget-relative position.
+        self->ShowTooltip(self->mMouseScreenX - screenDot.x / scaleFactor,
+          self->mMouseScreenY - screenDot.y / scaleFactor,
+          tipText);
       }
     }
 
     // release tooltip target if there is one, NO MATTER WHAT
     self->mPossibleTooltipNode = nullptr;
   } // if "self" data valid
 
 } // sTooltipCallback
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -5,16 +5,17 @@
 
 #ifndef _MOZILLA_GFX_2D_H
 #define _MOZILLA_GFX_2D_H
 
 #include "Types.h"
 #include "Point.h"
 #include "Rect.h"
 #include "Matrix.h"
+#include "Quaternion.h"
 #include "UserData.h"
 
 // GenericRefCountedBase allows us to hold on to refcounted objects of any type
 // (contrary to RefCounted<T> which requires knowing the type T) and, in particular,
 // without having a dependency on that type. This is used for DrawTargetSkia
 // to be able to hold on to a GLContext.
 #include "mozilla/GenericRefCounted.h"
 
--- a/gfx/2d/Matrix.cpp
+++ b/gfx/2d/Matrix.cpp
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * 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 "Matrix.h"
+#include "Quaternion.h"
 #include "Tools.h"
 #include <algorithm>
 #include <ostream>
 #include <math.h>
 
 #include "mozilla/FloatingPoint.h" // for UnspecifiedNaN
 
 using namespace std;
@@ -23,16 +24,27 @@ operator<<(std::ostream& aStream, const 
                  << " "  << aMatrix._12
                  << "; " << aMatrix._21
                  << " "  << aMatrix._22
                  << "; " << aMatrix._31
                  << " "  << aMatrix._32
                  << "; ]";
 }
 
+std::ostream&
+operator<<(std::ostream& aStream, const Matrix4x4& aMatrix)
+{
+  const Float *f = &aMatrix._11;
+  aStream << "[ " << f[0] << " "  << f[1] << " " << f[2] << " " << f[3] << " ;" << std::endl; f += 4;
+  aStream << "  " << f[0] << " "  << f[1] << " " << f[2] << " " << f[3] << " ;" << std::endl; f += 4;
+  aStream << "  " << f[0] << " "  << f[1] << " " << f[2] << " " << f[3] << " ;" << std::endl; f += 4;
+  aStream << "  " << f[0] << " "  << f[1] << " " << f[2] << " " << f[3] << " ]" << std::endl;
+  return aStream;
+}
+
 Matrix
 Matrix::Rotation(Float aAngle)
 {
   Matrix newMatrix;
 
   Float s = sin(aAngle);
   Float c = cos(aAngle);
 
@@ -278,10 +290,37 @@ Matrix4x4::SetNAN()
   _33 = UnspecifiedNaN<Float>();
   _43 = UnspecifiedNaN<Float>();
   _14 = UnspecifiedNaN<Float>();
   _24 = UnspecifiedNaN<Float>();
   _34 = UnspecifiedNaN<Float>();
   _44 = UnspecifiedNaN<Float>();
 }
 
+void
+Matrix4x4::SetRotationFromQuaternion(const Quaternion& q)
+{
+  const Float x2 = q.x + q.x, y2 = q.y + q.y, z2 = q.z + q.z;
+  const Float xx = q.x * x2, xy = q.x * y2, xz = q.x * z2;
+  const Float yy = q.y * y2, yz = q.y * z2, zz = q.z * z2;
+  const Float wx = q.w * x2, wy = q.w * y2, wz = q.w * z2;
+
+  _11 = 1.0f - (yy + zz);
+  _21 = xy + wz;
+  _31 = xz - wy;
+  _41 = 0.0f;
+
+  _12 = xy - wz;
+  _22 = 1.0f - (xx + zz);
+  _32 = yz + wx;
+  _42 = 0.0f;
+
+  _13 = xz + wy;
+  _23 = yz - wx;
+  _33 = 1.0f - (xx + yy);
+  _43 = 0.0f;
+
+  _14 = _42 = _43 = 0.0f;
+  _44 = 1.0f;
+}
+
 }
 }
--- a/gfx/2d/Matrix.h
+++ b/gfx/2d/Matrix.h
@@ -12,16 +12,18 @@
 #include <iosfwd>
 #include <math.h>
 #include "mozilla/Attributes.h"
 #include "mozilla/DebugOnly.h"
 
 namespace mozilla {
 namespace gfx {
 
+class Quaternion;
+
 static bool FuzzyEqual(Float aV1, Float aV2) {
   // XXX - Check if fabs does the smart thing and just negates the sign bit.
   return fabs(aV2 - aV1) < 1e-6;
 }
 
 class Matrix
 {
 public:
@@ -385,16 +387,18 @@ public:
     memcpy(this, &aOther, sizeof(*this));
   }
 
   Float _11, _12, _13, _14;
   Float _21, _22, _23, _24;
   Float _31, _32, _33, _34;
   Float _41, _42, _43, _44;
 
+  friend std::ostream& operator<<(std::ostream& aStream, const Matrix4x4& aMatrix);
+
   Point4D& operator[](int aIndex)
   {
       MOZ_ASSERT(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
       return *reinterpret_cast<Point4D*>((&_11)+4*aIndex);
   }
   const Point4D& operator[](int aIndex) const
   {
       MOZ_ASSERT(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
@@ -867,16 +871,21 @@ public:
   {
       MOZ_ASSERT(aIndex >= 0 && aIndex <= 3, "Invalid matrix array index");
       *((&_11)+aIndex) = aVector.x;
       *((&_21)+aIndex) = aVector.y;
       *((&_31)+aIndex) = aVector.z;
       *((&_41)+aIndex) = aVector.w;
   }
 
+  // Sets this matrix to a rotation matrix given by aQuat.
+  // This quaternion *MUST* be normalized!
+  // Implemented in Quaternion.cpp
+  void SetRotationFromQuaternion(const Quaternion& aQuat);
+
   // Set all the members of the matrix to NaN
   void SetNAN();
 };
 
 class Matrix5x4
 {
 public:
   Matrix5x4()
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Quaternion.cpp
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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 "Quaternion.h"
+#include "Matrix.h"
+#include "Tools.h"
+#include <algorithm>
+#include <ostream>
+#include <math.h>
+
+using namespace std;
+
+namespace mozilla {
+namespace gfx {
+
+std::ostream&
+operator<<(std::ostream& aStream, const Quaternion& aQuat)
+{
+  return aStream << "< " << aQuat.x << " "  << aQuat.y << " " << aQuat.z << " " << aQuat.w << ">";
+}
+
+void
+Quaternion::SetFromRotationMatrix(const Matrix4x4& m)
+{
+  // see http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
+  const Float trace = m._11 + m._22 + m._33;
+  if (trace > 0.0) {
+    const Float s = 0.5f / sqrt(trace + 1.0f);
+    w = 0.25f / s;
+    x = (m._32 - m._23) * s;
+    y = (m._13 - m._31) * s;
+    z = (m._21 - m._12) * s;
+  } else if (m._11 > m._22 && m._11 > m._33) {
+    const Float s = 2.0f * sqrt(1.0f + m._11 - m._22 - m._33);
+    w = (m._32 - m._23) / s;
+    x = 0.25f * s;
+    y = (m._12 + m._21) / s;
+    z = (m._13 + m._31) / s;
+  } else if (m._22 > m._33) {
+    const Float s = 2.0 * sqrt(1.0f + m._22 - m._11 - m._33);
+    w = (m._13 - m._31) / s;
+    x = (m._12 + m._21) / s;
+    y = 0.25f * s;
+    z = (m._23 + m._32) / s;
+  } else {
+    const Float s = 2.0 * sqrt(1.0f + m._33 - m._11 - m._22);
+    w = (m._21 - m._12) / s;
+    x = (m._13 + m._31) / s;
+    y = (m._23 + m._32) / s;
+    z = 0.25f * s;
+  }
+}
+
+}
+}
new file mode 100644
--- /dev/null
+++ b/gfx/2d/Quaternion.h
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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/. */
+
+#ifndef MOZILLA_GFX_QUATERNION_H_
+#define MOZILLA_GFX_QUATERNION_H_
+
+#include "Types.h"
+#include <math.h>
+#include "mozilla/Attributes.h"
+#include "mozilla/DebugOnly.h"
+
+namespace mozilla {
+namespace gfx {
+
+class Matrix4x4;
+
+class Quaternion
+{
+public:
+  Quaternion()
+    : x(0.0f), y(0.0f), z(0.0f), w(1.0f)
+  {}
+
+  Quaternion(Float aX, Float aY, Float aZ, Float aW)
+    : x(aX), y(aY), z(aZ), w(aW)
+  {}
+
+
+  Quaternion(const Quaternion& aOther)
+  {
+    memcpy(this, &aOther, sizeof(*this));
+  }
+
+  Float x, y, z, w;
+
+  friend std::ostream& operator<<(std::ostream& aStream, const Quaternion& aQuat);
+
+  void Set(Float aX, Float aY, Float aZ, Float aW)
+  {
+    x = aX; y = aY; z = aZ; w = aW;
+  }
+
+  // Assumes upper 3x3 of aMatrix is a pure rotation matrix (no scaling)
+  void SetFromRotationMatrix(const Matrix4x4& aMatrix);
+
+  // result = this * aQuat
+  Quaternion operator*(const Quaternion &aQuat) const
+  {
+    Quaternion o;
+    const Float bx = aQuat.x, by = aQuat.y, bz = aQuat.z, bw = aQuat.w;
+
+    o.x = x*bw + w*bx + y*bz - z*by;
+    o.y = y*bw + w*by + z*bx - x*bz;
+    o.z = z*bw + w*bz + x*by - y*bx;
+    o.w = w*bw - x*bx - y*by - z*bz;
+    return o;
+  }
+
+  Quaternion& operator*=(const Quaternion &aQuat)
+  {
+    *this = *this * aQuat;
+    return *this;
+  }
+
+  Float Length() const
+  {
+    return sqrt(x*x + y*y + z*z + w*w);
+  }
+
+  Quaternion& Conjugate()
+  {
+    x *= -1.f; y *= -1.f; z *= -1.f;
+    return *this;
+  }
+
+  Quaternion& Normalize()
+  {
+    Float l = Length();
+    if (l) {
+      l = 1.0f / l;
+      x *= l; y *= l; z *= l; w *= l;
+    } else {
+      x = y = z = 0.f;
+      w = 1.f;
+    }
+    return *this;
+  }
+
+  Quaternion& Invert()
+  {
+    return Conjugate().Normalize();
+  }
+};
+
+}
+}
+
+#endif
--- a/gfx/2d/moz.build
+++ b/gfx/2d/moz.build
@@ -24,16 +24,17 @@ EXPORTS.mozilla.gfx += [
     'DrawTargetTiled.h',
     'Filters.h',
     'Helpers.h',
     'Logging.h',
     'Matrix.h',
     'PathHelpers.h',
     'PatternHelpers.h',
     'Point.h',
+    'Quaternion.h',
     'Rect.h',
     'Scale.h',
     'ScaleFactor.h',
     'ScaleFactors2D.h',
     'SourceSurfaceCairo.h',
     'Tools.h',
     'Types.h',
     'UserData.h',
@@ -115,16 +116,17 @@ UNIFIED_SOURCES += [
     'FilterNodeSoftware.cpp',
     'FilterProcessing.cpp',
     'FilterProcessingScalar.cpp',
     'ImageScaling.cpp',
     'Matrix.cpp',
     'Path.cpp',
     'PathCairo.cpp',
     'PathRecording.cpp',
+    'Quaternion.cpp',
     'RecordedEvent.cpp',
     'Scale.cpp',
     'ScaledFontBase.cpp',
     'ScaledFontCairo.cpp',
     'SourceSurfaceCairo.cpp',
     'SourceSurfaceRawData.cpp',
 ]
 
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -68,27 +68,29 @@ struct DeviceAttachmentsD3D11
   RefPtr<ID3D11BlendState> mNonPremulBlendState;
   RefPtr<ID3D11BlendState> mComponentBlendState;
   RefPtr<ID3D11BlendState> mDisabledBlendState;
   RefPtr<IDXGIResource> mSyncTexture;
 
   //
   // VR pieces
   //
-  RefPtr<ID3D11InputLayout> mVRDistortionInputLayout;
-  RefPtr<ID3D11Buffer> mVRDistortionConstants;
-
+  typedef EnumeratedArray<VRHMDType, VRHMDType::NumHMDTypes, RefPtr<ID3D11InputLayout>>
+          VRDistortionInputLayoutArray;
   typedef EnumeratedArray<VRHMDType, VRHMDType::NumHMDTypes, RefPtr<ID3D11VertexShader>>
           VRVertexShaderArray;
   typedef EnumeratedArray<VRHMDType, VRHMDType::NumHMDTypes, RefPtr<ID3D11PixelShader>>
           VRPixelShaderArray;
 
+  VRDistortionInputLayoutArray mVRDistortionInputLayout;
   VRVertexShaderArray mVRDistortionVS;
   VRPixelShaderArray mVRDistortionPS;
 
+  RefPtr<ID3D11Buffer> mVRDistortionConstants;
+
   // These will be created/filled in as needed during rendering whenever the configuration
   // changes.
   VRHMDConfiguration mVRConfiguration;
   RefPtr<ID3D11Buffer> mVRDistortionVertices[2]; // one for each eye
   RefPtr<ID3D11Buffer> mVRDistortionIndices[2];
   uint32_t mVRDistortionIndexCount[2];
 };
 
@@ -329,17 +331,22 @@ CompositorD3D11::Initialize()
       { "TEXCOORD", 2, DXGI_FORMAT_R32G32_FLOAT,       0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
       { "COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
     };
 
     hr = mDevice->CreateInputLayout(vrlayout,
                                     sizeof(vrlayout) / sizeof(D3D11_INPUT_ELEMENT_DESC),
                                     OculusVRDistortionVS,
                                     sizeof(OculusVRDistortionVS),
-                                    byRef(mAttachments->mVRDistortionInputLayout));
+                                    byRef(mAttachments->mVRDistortionInputLayout[VRHMDType::Oculus]));
+
+    // XXX shared for now, rename
+    mAttachments->mVRDistortionInputLayout[VRHMDType::Cardboard] =
+      mAttachments->mVRDistortionInputLayout[VRHMDType::Oculus];
+
     cBufferDesc.ByteWidth = sizeof(gfx::VRDistortionConstants);
     hr = mDevice->CreateBuffer(&cBufferDesc, nullptr, byRef(mAttachments->mVRDistortionConstants));
     if (FAILED(hr)) {
       return false;
     }
   }
 
   nsRefPtr<IDXGIDevice> dxgiDevice;
@@ -656,16 +663,17 @@ CompositorD3D11::DrawVRDistortion(const 
 
   EffectVRDistortion* vrEffect =
     static_cast<EffectVRDistortion*>(aEffectChain.mPrimaryEffect.get());
 
   TextureSourceD3D11* source = vrEffect->mTexture->AsSourceD3D11();
   gfx::IntSize size = vrEffect->mRenderTarget->GetSize(); // XXX source->GetSize()
 
   VRHMDInfo* hmdInfo = vrEffect->mHMD;
+  VRHMDType hmdType = hmdInfo->GetType();
   VRDistortionConstants shaderConstants;
 
   // do we need to recreate the VR buffers, since the config has changed?
   if (hmdInfo->GetConfiguration() != mAttachments->mVRConfiguration) {
     D3D11_SUBRESOURCE_DATA sdata = { 0 };
     CD3D11_BUFFER_DESC desc(0, D3D11_BIND_VERTEX_BUFFER, D3D11_USAGE_IMMUTABLE);
 
     // XXX as an optimization, we should really pack the indices and vertices for both eyes
@@ -704,30 +712,27 @@ CompositorD3D11::DrawVRDistortion(const 
   scissor.left = aClipRect.x;
   scissor.right = aClipRect.XMost();
   scissor.top = aClipRect.y;
   scissor.bottom = aClipRect.YMost();
   mContext->RSSetScissorRects(1, &scissor);
 
   // Triangle lists and same layout for both eyes
   mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
-  mContext->IASetInputLayout(mAttachments->mVRDistortionInputLayout);
-
-  // Shaders for this HMD
-  mContext->VSSetShader(mAttachments->mVRDistortionVS[mAttachments->mVRConfiguration.hmdType], nullptr, 0);
-  mContext->PSSetShader(mAttachments->mVRDistortionPS[mAttachments->mVRConfiguration.hmdType], nullptr, 0);
+  mContext->IASetInputLayout(mAttachments->mVRDistortionInputLayout[hmdType]);
+  mContext->VSSetShader(mAttachments->mVRDistortionVS[hmdType], nullptr, 0);
+  mContext->PSSetShader(mAttachments->mVRDistortionPS[hmdType], nullptr, 0);
 
   // This is the source texture SRV for the pixel shader
-  // XXX, um should we cache this SRV?
+  // XXX, um should we cache this SRV on the source?
   RefPtr<ID3D11ShaderResourceView> view;
   mDevice->CreateShaderResourceView(source->GetD3D11Texture(), nullptr, byRef(view));
   ID3D11ShaderResourceView* srView = view;
   mContext->PSSetShaderResources(0, 1, &srView);
 
-
   gfx::IntSize vpSizeInt = mCurrentRT->GetSize();
   gfx::Size vpSize(vpSizeInt.width, vpSizeInt.height);
   ID3D11Buffer* vbuffer;
   UINT vsize, voffset;
 
   for (uint32_t eye = 0; eye < 2; eye++) {
     gfx::IntRect eyeViewport;
     eyeViewport.x = eye * size.width / 2;
@@ -1338,16 +1343,21 @@ CompositorD3D11::CreateShaders()
   hr = mDevice->CreatePixelShader(OculusVRDistortionPS,
                                   sizeof(OculusVRDistortionPS),
                                   nullptr,
                                   byRef(mAttachments->mVRDistortionPS[VRHMDType::Oculus]));
   if (FAILED(hr)) {
     return false;
   }
 
+  // These are shared
+  // XXX rename Oculus shaders to something more generic
+  mAttachments->mVRDistortionVS[VRHMDType::Cardboard] = mAttachments->mVRDistortionVS[VRHMDType::Oculus];
+  mAttachments->mVRDistortionPS[VRHMDType::Cardboard] = mAttachments->mVRDistortionPS[VRHMDType::Oculus];
+
   return true;
 }
 
 bool
 CompositorD3D11::UpdateConstantBuffers()
 {
   HRESULT hr;
   D3D11_MAPPED_SUBRESOURCE resource;
--- a/gfx/layers/d3d11/CompositorD3D11Shaders.h
+++ b/gfx/layers/d3d11/CompositorD3D11Shaders.h
@@ -1,14 +1,13 @@
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4x4 mLayerTransform;          // Offset:    0 Size:    64
 //   float4x4 mProjection;              // Offset:   64 Size:    64
 //   float4 vRenderTargetOffset;        // Offset:  128 Size:    16
@@ -99,20 +98,20 @@ mad r1.xyzw, cb0[6].xyzw, r0.zzzz, r1.xy
 mad o0.xyzw, cb0[7].xyzw, r0.wwww, r1.xyzw
 mad o1.xy, v0.xyxx, cb0[9].zwzz, cb0[9].xyxx
 ret 
 // Approximately 13 instruction slots used
 #endif
 
 const BYTE LayerQuadVS[] =
 {
-     68,  88,  66,  67,  67,  61, 
-     27, 151,  57,  33,  48,  19, 
-     55,   6,  95,  77, 254, 163, 
-    118, 237,   1,   0,   0,   0, 
+     68,  88,  66,  67, 200, 251, 
+     64, 251, 166, 240, 101, 137, 
+    191, 140,  75, 217,   9, 168, 
+     61, 163,   1,   0,   0,   0, 
     180,   6,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     152,   1,   0,   0, 160,   3, 
       0,   0,  28,   4,   0,   0, 
      40,   6,   0,   0,  92,   6, 
       0,   0,  65, 111, 110,  57, 
      88,   1,   0,   0,  88,   1, 
       0,   0,   0,   2, 254, 255, 
@@ -257,27 +256,27 @@ const BYTE LayerQuadVS[] =
     230, 138,  32,   0,   0,   0, 
       0,   0,   9,   0,   0,   0, 
      70, 128,  32,   0,   0,   0, 
       0,   0,   9,   0,   0,   0, 
      62,   0,   0,   1,  83,  84, 
      65,  84, 116,   0,   0,   0, 
      13,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   6,   0, 
+      3,   0,   0,   0,  12,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,  82,  68,  69,  70, 
       4,   2,   0,   0,   1,   0, 
@@ -358,20 +357,20 @@ const BYTE LayerQuadVS[] =
       0, 171,   0,   0,   3,   0, 
       1,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
      77, 105,  99, 114, 111, 115, 
     111, 102, 116,  32,  40,  82, 
      41,  32,  72,  76,  83,  76, 
      32,  83, 104,  97, 100, 101, 
     114,  32,  67, 111, 109, 112, 
-    105, 108, 101, 114,  32,  57, 
-     46,  51,  48,  46,  57,  50, 
-     48,  48,  46,  50,  48,  53, 
-     52,  54,   0, 171,  73,  83, 
+    105, 108, 101, 114,  32,  54, 
+     46,  51,  46,  57,  54,  48, 
+     48,  46,  49,  54,  51,  56, 
+     52,   0, 171, 171,  73,  83, 
      71,  78,  44,   0,   0,   0, 
       1,   0,   0,   0,   8,   0, 
       0,   0,  32,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,   3,   3, 
       0,   0,  80,  79,  83,  73, 
      84,  73,  79,  78,   0, 171, 
@@ -388,20 +387,19 @@ const BYTE LayerQuadVS[] =
       0,   0,   3,  12,   0,   0, 
      83,  86,  95,  80, 111, 115, 
     105, 116, 105, 111, 110,   0, 
      84,  69,  88,  67,  79,  79, 
      82,  68,   0, 171, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16
 //   float fLayerOpacity;               // Offset:   16 Size:     4 [unused]
 //   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
@@ -455,20 +453,20 @@ dcl_constantbuffer cb0[1], immediateInde
 dcl_output o0.xyzw
 mov o0.xyzw, cb0[0].xyzw
 ret 
 // Approximately 2 instruction slots used
 #endif
 
 const BYTE SolidColorShader[] =
 {
-     68,  88,  66,  67, 182,  98, 
-    102, 100, 187, 218,  19,  40, 
-     99,  74,  29, 228,  47, 107, 
-    160, 122,   1,   0,   0,   0, 
+     68,  88,  66,  67,  30, 148, 
+    104, 202, 165,  39,  58, 182, 
+    100, 205,  95, 195,  52, 137, 
+    197, 241,   1,   0,   0,   0, 
     224,   3,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     132,   0,   0,   0, 204,   0, 
       0,   0,  72,   1,   0,   0, 
      84,   3,   0,   0, 172,   3, 
       0,   0,  65, 111, 110,  57, 
      68,   0,   0,   0,  68,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -503,17 +501,17 @@ const BYTE SolidColorShader[] =
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  82,  68, 
      69,  70,   4,   2,   0,   0, 
       1,   0,   0,   0,  72,   0, 
@@ -594,19 +592,19 @@ const BYTE SolidColorShader[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  57,  46,  51,  48, 
-     46,  57,  50,  48,  48,  46, 
-     50,  48,  53,  52,  54,   0, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
      73,  83,  71,  78,  80,   0, 
       0,   0,   2,   0,   0,   0, 
       8,   0,   0,   0,  56,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  68,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -624,20 +622,19 @@ const BYTE SolidColorShader[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
 //   float fLayerOpacity;               // Offset:   16 Size:     4
 //   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
@@ -711,20 +708,20 @@ sample r0.xyzw, v1.xyxx, t0.xyzw, s0
 mul o0.xyz, r0.xyzx, cb0[1].xxxx
 mov o0.w, cb0[1].x
 ret 
 // Approximately 4 instruction slots used
 #endif
 
 const BYTE RGBShader[] =
 {
-     68,  88,  66,  67, 195,  54, 
-    227,  44,  79, 159, 121,  69, 
-     60, 252, 145,  90, 151, 241, 
-    175, 162,   1,   0,   0,   0, 
+     68,  88,  66,  67, 239, 198, 
+     87, 206,  69,  92, 245,  30, 
+    125, 195, 239,  77,  37, 241, 
+    175, 187,   1,   0,   0,   0, 
     232,   4,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     204,   0,   0,   0, 136,   1, 
       0,   0,   4,   2,   0,   0, 
      92,   4,   0,   0, 180,   4, 
       0,   0,  65, 111, 110,  57, 
     140,   0,   0,   0, 140,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -790,308 +787,16 @@ const BYTE RGBShader[] =
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     82,  68,  69,  70,  80,   2, 
-      0,   0,   1,   0,   0,   0, 
-    148,   0,   0,   0,   3,   0, 
-      0,   0,  28,   0,   0,   0, 
-      0,   4, 255, 255,   0,   1, 
-      0,   0,  29,   2,   0,   0, 
-    124,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   1,   0, 
-      0,   0, 133,   0,   0,   0, 
-      2,   0,   0,   0,   5,   0, 
-      0,   0,   4,   0,   0,   0, 
-    255, 255, 255, 255,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     12,   0,   0,   0, 138,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-    115,  83,  97, 109, 112, 108, 
-    101, 114,   0, 116,  82,  71, 
-     66,   0,  36,  71, 108, 111, 
-     98,  97, 108, 115,   0, 171, 
-    138,   0,   0,   0,   8,   0, 
-      0,   0, 172,   0,   0,   0, 
-    224,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    108,   1,   0,   0,   0,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0, 120,   1, 
-      0,   0,   0,   0,   0,   0, 
-    136,   1,   0,   0,  16,   0, 
-      0,   0,   4,   0,   0,   0, 
-      2,   0,   0,   0, 152,   1, 
-      0,   0,   0,   0,   0,   0, 
-    168,   1,   0,   0,  32,   0, 
-      0,   0,  64,   0,   0,   0, 
-      0,   0,   0,   0, 184,   1, 
-      0,   0,   0,   0,   0,   0, 
-    200,   1,   0,   0,  96,   0, 
-      0,   0,  64,   0,   0,   0, 
-      0,   0,   0,   0, 184,   1, 
-      0,   0,   0,   0,   0,   0, 
-    212,   1,   0,   0, 160,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0, 120,   1, 
-      0,   0,   0,   0,   0,   0, 
-    232,   1,   0,   0, 176,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0, 248,   1, 
-      0,   0,   0,   0,   0,   0, 
-      8,   2,   0,   0, 192,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0, 248,   1, 
-      0,   0,   0,   0,   0,   0, 
-     19,   2,   0,   0, 208,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0, 248,   1, 
-      0,   0,   0,   0,   0,   0, 
-    102,  76,  97, 121, 101, 114, 
-     67, 111, 108, 111, 114,   0, 
-      1,   0,   3,   0,   1,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 102,  76, 
-     97, 121, 101, 114,  79, 112, 
-     97,  99, 105, 116, 121,   0, 
-    171, 171,   0,   0,   3,   0, 
-      1,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    109,  76,  97, 121, 101, 114, 
-     84, 114,  97, 110, 115, 102, 
-    111, 114, 109,   0,   3,   0, 
-      3,   0,   4,   0,   4,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 109,  80, 114, 111, 
-    106, 101,  99, 116, 105, 111, 
-    110,   0, 118,  82, 101, 110, 
-    100, 101, 114,  84,  97, 114, 
-    103, 101, 116,  79, 102, 102, 
-    115, 101, 116,   0, 118,  84, 
-    101, 120, 116, 117, 114, 101, 
-     67, 111, 111, 114, 100, 115, 
-      0, 171,   1,   0,   3,   0, 
-      1,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    118,  76,  97, 121, 101, 114, 
-     81, 117,  97, 100,   0, 118, 
-     77,  97, 115, 107,  81, 117, 
-     97, 100,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  57,  46,  51,  48, 
-     46,  57,  50,  48,  48,  46, 
-     50,  48,  53,  52,  54,   0, 
-     73,  83,  71,  78,  80,   0, 
-      0,   0,   2,   0,   0,   0, 
-      8,   0,   0,   0,  56,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  68,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  83,  86, 
-     95,  80, 111, 115, 105, 116, 
-    105, 111, 110,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     97, 114, 103, 101, 116,   0, 
-    171, 171
-};
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
-// Buffer Definitions: 
-//
-// cbuffer $Globals
-// {
-//
-//   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
-//   float fLayerOpacity;               // Offset:   16 Size:     4
-//   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
-//   float4x4 mProjection;              // Offset:   96 Size:    64 [unused]
-//   float4 vRenderTargetOffset;        // Offset:  160 Size:    16 [unused]
-//   float4 vTextureCoords;             // Offset:  176 Size:    16 [unused]
-//   float4 vLayerQuad;                 // Offset:  192 Size:    16 [unused]
-//   float4 vMaskQuad;                  // Offset:  208 Size:    16 [unused]
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// sSampler                          sampler      NA          NA    0        1
-// tRGB                              texture  float4          2d    0        1
-// $Globals                          cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
-//
-//
-// Constant buffer to DX9 shader constant mappings:
-//
-// Target Reg Buffer  Start Reg # of Regs        Data Conversion
-// ---------- ------- --------- --------- ----------------------
-// c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
-//
-//
-// Sampler/Resource to DX9 shader sampler mappings:
-//
-// Target Sampler Source Sampler  Source Resource
-// -------------- --------------- ----------------
-// s0             s0              t0               
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    dcl t0.xy
-    dcl_2d s0
-    texld r0, t0, s0
-    mul r0, r0, c0.x
-    mov oC0, r0
-
-// approximately 3 instruction slots used (1 texture, 2 arithmetic)
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul o0.xyzw, r0.xyzw, cb0[1].xxxx
-ret 
-// Approximately 3 instruction slots used
-#endif
-
-const BYTE RGBAShader[] =
-{
-     68,  88,  66,  67, 124,  18, 
-      8, 218,  34, 168,  20, 218, 
-    144, 232, 183, 104, 152, 211, 
-      5,  26,   1,   0,   0,   0, 
-    196,   4,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    192,   0,   0,   0, 100,   1, 
-      0,   0, 224,   1,   0,   0, 
-     56,   4,   0,   0, 144,   4, 
-      0,   0,  65, 111, 110,  57, 
-    128,   0,   0,   0, 128,   0, 
-      0,   0,   0,   2, 255, 255, 
-     76,   0,   0,   0,  52,   0, 
-      0,   0,   1,   0,  40,   0, 
-      0,   0,  52,   0,   0,   0, 
-     52,   0,   1,   0,  36,   0, 
-      0,   0,  52,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   1,   2, 255, 255, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   0,   0,   3, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 144,   0,   8,  15, 160, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   0,   0, 228, 176, 
-      0,   8, 228, 160,   5,   0, 
-      0,   3,   0,   0,  15, 128, 
-      0,   0, 228, 128,   0,   0, 
-      0, 160,   1,   0,   0,   2, 
-      0,   8,  15, 128,   0,   0, 
-    228, 128, 255, 255,   0,   0, 
-     83,  72,  68,  82, 156,   0, 
-      0,   0,  64,   0,   0,   0, 
-     39,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  90,   0,   0,   3, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  85,  85,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0,  69,   0,   0,   9, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  56,   0,   0,   8, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0,   6, 128, 
-     32,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
      82,  68,  69,  70,  80,   2, 
@@ -1186,19 +891,19 @@ const BYTE RGBAShader[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  57,  46,  51,  48, 
-     46,  57,  50,  48,  48,  46, 
-     50,  48,  53,  52,  54,   0, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
      73,  83,  71,  78,  80,   0, 
       0,   0,   2,   0,   0,   0, 
       8,   0,   0,   0,  56,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  68,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -1216,20 +921,310 @@ const BYTE RGBAShader[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer $Globals
+// {
+//
+//   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
+//   float fLayerOpacity;               // Offset:   16 Size:     4
+//   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
+//   float4x4 mProjection;              // Offset:   96 Size:    64 [unused]
+//   float4 vRenderTargetOffset;        // Offset:  160 Size:    16 [unused]
+//   float4 vTextureCoords;             // Offset:  176 Size:    16 [unused]
+//   float4 vLayerQuad;                 // Offset:  192 Size:    16 [unused]
+//   float4 vMaskQuad;                  // Offset:  208 Size:    16 [unused]
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// sSampler                          sampler      NA          NA    0        1
+// tRGB                              texture  float4          2d    0        1
+// $Globals                          cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Constant buffer to DX9 shader constant mappings:
+//
+// Target Reg Buffer  Start Reg # of Regs        Data Conversion
+// ---------- ------- --------- --------- ----------------------
+// c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t0               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    dcl t0.xy
+    dcl_2d s0
+    texld r0, t0, s0
+    mul r0, r0, c0.x
+    mov oC0, r0
+
+// approximately 3 instruction slots used (1 texture, 2 arithmetic)
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul o0.xyzw, r0.xyzw, cb0[1].xxxx
+ret 
+// Approximately 3 instruction slots used
+#endif
+
+const BYTE RGBAShader[] =
+{
+     68,  88,  66,  67, 230,  59, 
+     90,  23,  60,  77,  18, 113, 
+     14, 129, 183, 152, 233,  55, 
+    111,  42,   1,   0,   0,   0, 
+    196,   4,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    192,   0,   0,   0, 100,   1, 
+      0,   0, 224,   1,   0,   0, 
+     56,   4,   0,   0, 144,   4, 
+      0,   0,  65, 111, 110,  57, 
+    128,   0,   0,   0, 128,   0, 
+      0,   0,   0,   2, 255, 255, 
+     76,   0,   0,   0,  52,   0, 
+      0,   0,   1,   0,  40,   0, 
+      0,   0,  52,   0,   0,   0, 
+     52,   0,   1,   0,  36,   0, 
+      0,   0,  52,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   1,   2, 255, 255, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   0,   0,   3, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 144,   0,   8,  15, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 176, 
+      0,   8, 228, 160,   5,   0, 
+      0,   3,   0,   0,  15, 128, 
+      0,   0, 228, 128,   0,   0, 
+      0, 160,   1,   0,   0,   2, 
+      0,   8,  15, 128,   0,   0, 
+    228, 128, 255, 255,   0,   0, 
+     83,  72,  68,  82, 156,   0, 
+      0,   0,  64,   0,   0,   0, 
+     39,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  90,   0,   0,   3, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  88,  24,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  85,  85,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  56,   0,   0,   8, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,   6, 128, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     82,  68,  69,  70,  80,   2, 
+      0,   0,   1,   0,   0,   0, 
+    148,   0,   0,   0,   3,   0, 
+      0,   0,  28,   0,   0,   0, 
+      0,   4, 255, 255,   0,   1, 
+      0,   0,  29,   2,   0,   0, 
+    124,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   1,   0, 
+      0,   0, 133,   0,   0,   0, 
+      2,   0,   0,   0,   5,   0, 
+      0,   0,   4,   0,   0,   0, 
+    255, 255, 255, 255,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     12,   0,   0,   0, 138,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+    115,  83,  97, 109, 112, 108, 
+    101, 114,   0, 116,  82,  71, 
+     66,   0,  36,  71, 108, 111, 
+     98,  97, 108, 115,   0, 171, 
+    138,   0,   0,   0,   8,   0, 
+      0,   0, 172,   0,   0,   0, 
+    224,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    108,   1,   0,   0,   0,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0, 120,   1, 
+      0,   0,   0,   0,   0,   0, 
+    136,   1,   0,   0,  16,   0, 
+      0,   0,   4,   0,   0,   0, 
+      2,   0,   0,   0, 152,   1, 
+      0,   0,   0,   0,   0,   0, 
+    168,   1,   0,   0,  32,   0, 
+      0,   0,  64,   0,   0,   0, 
+      0,   0,   0,   0, 184,   1, 
+      0,   0,   0,   0,   0,   0, 
+    200,   1,   0,   0,  96,   0, 
+      0,   0,  64,   0,   0,   0, 
+      0,   0,   0,   0, 184,   1, 
+      0,   0,   0,   0,   0,   0, 
+    212,   1,   0,   0, 160,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0, 120,   1, 
+      0,   0,   0,   0,   0,   0, 
+    232,   1,   0,   0, 176,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0, 248,   1, 
+      0,   0,   0,   0,   0,   0, 
+      8,   2,   0,   0, 192,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0, 248,   1, 
+      0,   0,   0,   0,   0,   0, 
+     19,   2,   0,   0, 208,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0, 248,   1, 
+      0,   0,   0,   0,   0,   0, 
+    102,  76,  97, 121, 101, 114, 
+     67, 111, 108, 111, 114,   0, 
+      1,   0,   3,   0,   1,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 102,  76, 
+     97, 121, 101, 114,  79, 112, 
+     97,  99, 105, 116, 121,   0, 
+    171, 171,   0,   0,   3,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    109,  76,  97, 121, 101, 114, 
+     84, 114,  97, 110, 115, 102, 
+    111, 114, 109,   0,   3,   0, 
+      3,   0,   4,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 109,  80, 114, 111, 
+    106, 101,  99, 116, 105, 111, 
+    110,   0, 118,  82, 101, 110, 
+    100, 101, 114,  84,  97, 114, 
+    103, 101, 116,  79, 102, 102, 
+    115, 101, 116,   0, 118,  84, 
+    101, 120, 116, 117, 114, 101, 
+     67, 111, 111, 114, 100, 115, 
+      0, 171,   1,   0,   3,   0, 
+      1,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    118,  76,  97, 121, 101, 114, 
+     81, 117,  97, 100,   0, 118, 
+     77,  97, 115, 107,  81, 117, 
+     97, 100,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78,  80,   0, 
+      0,   0,   2,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  68,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  83,  86, 
+     95,  80, 111, 115, 105, 116, 
+    105, 111, 110,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     97, 114, 103, 101, 116,   0, 
+    171, 171
+};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
 //   float fLayerOpacity;               // Offset:   16 Size:     4
 //   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
@@ -1319,20 +1314,20 @@ mov r1.w, r0.y
 mul o1.xyzw, r0.xyzw, cb0[1].xxxx
 mul o0.xyzw, r1.xyzw, cb0[1].xxxx
 ret 
 // Approximately 8 instruction slots used
 #endif
 
 const BYTE ComponentAlphaShader[] =
 {
-     68,  88,  66,  67, 152,  37, 
-    117,  77,  87, 153,  20,  62, 
-     92, 142,  77, 134, 246, 203, 
-    174,  59,   1,   0,   0,   0, 
+     68,  88,  66,  67, 186, 162, 
+     72,  42,  69,  36, 160,  68, 
+    108, 121, 216, 238, 108,  37, 
+      6, 145,   1,   0,   0,   0, 
      68,   6,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      64,   1,   0,   0, 160,   2, 
       0,   0,  28,   3,   0,   0, 
     160,   5,   0,   0, 248,   5, 
       0,   0,  65, 111, 110,  57, 
       0,   1,   0,   0,   0,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -1445,17 +1440,17 @@ const BYTE ComponentAlphaShader[] =
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  82,  68, 
      69,  70, 124,   2,   0,   0, 
       1,   0,   0,   0, 192,   0, 
@@ -1556,19 +1551,19 @@ const BYTE ComponentAlphaShader[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  57,  46,  51,  48, 
-     46,  57,  50,  48,  48,  46, 
-     50,  48,  53,  52,  54,   0, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
      73,  83,  71,  78,  80,   0, 
       0,   0,   2,   0,   0,   0, 
       8,   0,   0,   0,  56,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  68,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -1590,20 +1585,19 @@ const BYTE ComponentAlphaShader[] =
       0,   0,   3,   0,   0,   0, 
       1,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
 //   float fLayerOpacity;               // Offset:   16 Size:     4
 //   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
@@ -1709,20 +1703,20 @@ mad r1.z, r0.z, l(1.164380), r0.x
 mov r1.w, l(1.000000)
 mul o0.xyzw, r1.xyzw, cb0[1].xxxx
 ret 
 // Approximately 15 instruction slots used
 #endif
 
 const BYTE YCbCrShader[] =
 {
-     68,  88,  66,  67,  26, 187, 
-     43, 127,  28, 135, 212,  40, 
-     57, 230, 160, 198, 151, 242, 
-    106, 110,   1,   0,   0,   0, 
+     68,  88,  66,  67, 181, 118, 
+    100,  53, 248, 120, 136,  92, 
+     59, 190,  18, 201, 139, 224, 
+     32, 141,   1,   0,   0,   0, 
     212,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     220,   1,   0,   0,  44,   4, 
       0,   0, 168,   4,   0,   0, 
      72,   7,   0,   0, 160,   7, 
       0,   0,  65, 111, 110,  57, 
     156,   1,   0,   0, 156,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -1891,27 +1885,27 @@ const BYTE YCbCrShader[] =
      70,  14,  16,   0,   1,   0, 
       0,   0,   6, 128,  32,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,  62,   0,   0,   1, 
      83,  84,  65,  84, 116,   0, 
       0,   0,  15,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,   2,   0,   0,   0, 
-      6,   0,   0,   0,   0,   0, 
+     10,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  82,  68, 
      69,  70, 152,   2,   0,   0, 
       1,   0,   0,   0, 220,   0, 
@@ -2017,19 +2011,19 @@ const BYTE YCbCrShader[] =
      97, 100,   0, 118,  77,  97, 
     115, 107,  81, 117,  97, 100, 
       0,  77, 105,  99, 114, 111, 
     115, 111, 102, 116,  32,  40, 
      82,  41,  32,  72,  76,  83, 
      76,  32,  83, 104,  97, 100, 
     101, 114,  32,  67, 111, 109, 
     112, 105, 108, 101, 114,  32, 
-     57,  46,  51,  48,  46,  57, 
-     50,  48,  48,  46,  50,  48, 
-     53,  52,  54,   0,  73,  83, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
      71,  78,  80,   0,   0,   0, 
       2,   0,   0,   0,   8,   0, 
       0,   0,  56,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  68,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2046,20 +2040,19 @@ const BYTE YCbCrShader[] =
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,  15,   0,   0,   0, 
      83,  86,  95,  84,  97, 114, 
     103, 101, 116,   0, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4x4 mLayerTransform;          // Offset:    0 Size:    64
 //   float4x4 mProjection;              // Offset:   64 Size:    64
 //   float4 vRenderTargetOffset;        // Offset:  128 Size:    16
@@ -2160,20 +2153,20 @@ mad r1.xyzw, cb0[6].xyzw, r0.zzzz, r1.xy
 mad o0.xyzw, cb0[7].xyzw, r0.wwww, r1.xyzw
 mad o1.xy, v0.xyxx, cb0[9].zwzz, cb0[9].xyxx
 ret 
 // Approximately 16 instruction slots used
 #endif
 
 const BYTE LayerQuadMaskVS[] =
 {
-     68,  88,  66,  67, 229,  18, 
-    238, 182, 176, 120, 118,  84, 
-     74, 135, 103, 188, 146,  51, 
-    229, 207,   1,   0,   0,   0, 
+     68,  88,  66,  67, 223, 251, 
+     10,  17,  13,  90,  47,  25, 
+    119, 198,  20, 157, 124, 193, 
+    251, 234,   1,   0,   0,   0, 
     120,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     224,   1,   0,   0,  76,   4, 
       0,   0, 200,   4,   0,   0, 
     212,   6,   0,   0,   8,   7, 
       0,   0,  65, 111, 110,  57, 
     160,   1,   0,   0, 160,   1, 
       0,   0,   0,   2, 254, 255, 
@@ -2347,27 +2340,27 @@ const BYTE LayerQuadMaskVS[] =
      32,   0,   0,   0,   0,   0, 
       9,   0,   0,   0,  70, 128, 
      32,   0,   0,   0,   0,   0, 
       9,   0,   0,   0,  62,   0, 
       0,   1,  83,  84,  65,  84, 
     116,   0,   0,   0,  16,   0, 
       0,   0,   2,   0,   0,   0, 
       0,   0,   0,   0,   4,   0, 
-      0,   0,   8,   0,   0,   0, 
+      0,   0,  14,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
      82,  68,  69,  70,   4,   2, 
       0,   0,   1,   0,   0,   0, 
@@ -2448,20 +2441,20 @@ const BYTE LayerQuadMaskVS[] =
       0,   0,   3,   0,   1,   0, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  77, 105, 
      99, 114, 111, 115, 111, 102, 
     116,  32,  40,  82,  41,  32, 
      72,  76,  83,  76,  32,  83, 
     104,  97, 100, 101, 114,  32, 
      67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  57,  46,  51, 
-     48,  46,  57,  50,  48,  48, 
-     46,  50,  48,  53,  52,  54, 
-      0, 171,  73,  83,  71,  78, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
      44,   0,   0,   0,   1,   0, 
       0,   0,   8,   0,   0,   0, 
      32,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,   3,   3,   0,   0, 
      80,  79,  83,  73,  84,  73, 
      79,  78,   0, 171, 171, 171, 
@@ -2482,20 +2475,19 @@ const BYTE LayerQuadMaskVS[] =
      12,   3,   0,   0,  83,  86, 
      95,  80, 111, 115, 105, 116, 
     105, 111, 110,   0,  84,  69, 
      88,  67,  79,  79,  82,  68, 
       0, 171, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4x4 mLayerTransform;          // Offset:    0 Size:    64
 //   float4x4 mProjection;              // Offset:   64 Size:    64
 //   float4 vRenderTargetOffset;        // Offset:  128 Size:    16
@@ -2600,20 +2592,20 @@ mad o1.xy, v0.xyxx, cb0[9].zwzz, cb0[9].
 mov r0.z, l(1.000000)
 mul o2.xyz, r0.wwww, r0.xyzx
 ret 
 // Approximately 17 instruction slots used
 #endif
 
 const BYTE LayerQuadMask3DVS[] =
 {
-     68,  88,  66,  67,  81, 198, 
-     45,  88, 207, 133,  27,  66, 
-      4, 235, 107, 238,  69,  93, 
-     43, 232,   1,   0,   0,   0, 
+     68,  88,  66,  67, 151, 141, 
+     11,  11, 111, 244,  17, 242, 
+    119, 116, 248,  53, 235, 192, 
+     38, 193,   1,   0,   0,   0, 
     204,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      24,   2,   0,   0, 160,   4, 
       0,   0,  28,   5,   0,   0, 
      40,   7,   0,   0,  92,   7, 
       0,   0,  65, 111, 110,  57, 
     216,   1,   0,   0, 216,   1, 
       0,   0,   0,   2, 254, 255, 
@@ -2801,27 +2793,27 @@ const BYTE LayerQuadMask3DVS[] =
      16,   0,   2,   0,   0,   0, 
     246,  15,  16,   0,   0,   0, 
       0,   0,  70,   2,  16,   0, 
       0,   0,   0,   0,  62,   0, 
       0,   1,  83,  84,  65,  84, 
     116,   0,   0,   0,  17,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,   4,   0, 
-      0,   0,   9,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
      82,  68,  69,  70,   4,   2, 
       0,   0,   1,   0,   0,   0, 
@@ -2902,20 +2894,20 @@ const BYTE LayerQuadMask3DVS[] =
       0,   0,   3,   0,   1,   0, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  77, 105, 
      99, 114, 111, 115, 111, 102, 
     116,  32,  40,  82,  41,  32, 
      72,  76,  83,  76,  32,  83, 
     104,  97, 100, 101, 114,  32, 
      67, 111, 109, 112, 105, 108, 
-    101, 114,  32,  57,  46,  51, 
-     48,  46,  57,  50,  48,  48, 
-     46,  50,  48,  53,  52,  54, 
-      0, 171,  73,  83,  71,  78, 
+    101, 114,  32,  54,  46,  51, 
+     46,  57,  54,  48,  48,  46, 
+     49,  54,  51,  56,  52,   0, 
+    171, 171,  73,  83,  71,  78, 
      44,   0,   0,   0,   1,   0, 
       0,   0,   8,   0,   0,   0, 
      32,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,   3,   3,   0,   0, 
      80,  79,  83,  73,  84,  73, 
      79,  78,   0, 171, 171, 171, 
@@ -2936,20 +2928,19 @@ const BYTE LayerQuadMask3DVS[] =
       7,   8,   0,   0,  83,  86, 
      95,  80, 111, 115, 105, 116, 
     105, 111, 110,   0,  84,  69, 
      88,  67,  79,  79,  82,  68, 
       0, 171, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16
 //   float fLayerOpacity;               // Offset:   16 Size:     4 [unused]
 //   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
@@ -3023,20 +3014,20 @@ dcl_temps 1
 sample r0.xyzw, v1.zwzz, t3.xyzw, s0
 mul o0.xyzw, r0.wwww, cb0[0].xyzw
 ret 
 // Approximately 3 instruction slots used
 #endif
 
 const BYTE SolidColorShaderMask[] =
 {
-     68,  88,  66,  67, 110, 173, 
-    179, 170, 121,  56,  16,  38, 
-    131, 202, 191, 200, 149, 158, 
-    191, 136,   1,   0,   0,   0, 
+     68,  88,  66,  67, 236, 109, 
+     19, 151,  23, 187, 157, 205, 
+    112, 188,  91, 187, 108, 106, 
+    138,  14,   1,   0,   0,   0, 
     232,   4,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     204,   0,   0,   0, 112,   1, 
       0,   0, 236,   1,   0,   0, 
      68,   4,   0,   0, 180,   4, 
       0,   0,  65, 111, 110,  57, 
     140,   0,   0,   0, 140,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -3098,17 +3089,17 @@ const BYTE SolidColorShaderMask[] =
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
      82,  68,  69,  70,  80,   2, 
       0,   0,   1,   0,   0,   0, 
@@ -3202,19 +3193,19 @@ const BYTE SolidColorShaderMask[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  57,  46,  51,  48, 
-     46,  57,  50,  48,  48,  46, 
-     50,  48,  53,  52,  54,   0, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
      73,  83,  71,  78, 104,   0, 
       0,   0,   3,   0,   0,   0, 
       8,   0,   0,   0,  80,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  92,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -3236,20 +3227,19 @@ const BYTE SolidColorShaderMask[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
 //   float fLayerOpacity;               // Offset:   16 Size:     4
 //   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
@@ -3334,20 +3324,20 @@ sample r1.xyzw, v1.zwzz, t3.xyzw, s0
 mov r0.w, cb0[1].x
 mul o0.xyzw, r0.xyzw, r1.wwww
 ret 
 // Approximately 6 instruction slots used
 #endif
 
 const BYTE RGBShaderMask[] =
 {
-     68,  88,  66,  67,  90, 156, 
-    108, 215,   2, 184,  95, 225, 
-    139, 102,  23,  57, 234, 197, 
-     48,  52,   1,   0,   0,   0, 
+     68,  88,  66,  67,  30,  30, 
+     87,  58, 114, 156, 251, 151, 
+     29,  94,  34, 100, 228, 250, 
+     37, 251,   1,   0,   0,   0, 
     192,   5,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
       8,   1,   0,   0,  32,   2, 
       0,   0, 156,   2,   0,   0, 
      28,   5,   0,   0, 140,   5, 
       0,   0,  65, 111, 110,  57, 
     200,   0,   0,   0, 200,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -3438,355 +3428,16 @@ const BYTE RGBShaderMask[] =
       0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   2,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  82,  68,  69,  70, 
-    120,   2,   0,   0,   1,   0, 
-      0,   0, 188,   0,   0,   0, 
-      4,   0,   0,   0,  28,   0, 
-      0,   0,   0,   4, 255, 255, 
-      0,   1,   0,   0,  69,   2, 
-      0,   0, 156,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      1,   0,   0,   0, 165,   0, 
-      0,   0,   2,   0,   0,   0, 
-      5,   0,   0,   0,   4,   0, 
-      0,   0, 255, 255, 255, 255, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  12,   0,   0,   0, 
-    170,   0,   0,   0,   2,   0, 
-      0,   0,   5,   0,   0,   0, 
-      4,   0,   0,   0, 255, 255, 
-    255, 255,   3,   0,   0,   0, 
-      1,   0,   0,   0,  13,   0, 
-      0,   0, 176,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0, 115,  83, 
-     97, 109, 112, 108, 101, 114, 
-      0, 116,  82,  71,  66,   0, 
-    116,  77,  97, 115, 107,   0, 
-     36,  71, 108, 111,  98,  97, 
-    108, 115,   0, 171, 171, 171, 
-    176,   0,   0,   0,   8,   0, 
-      0,   0, 212,   0,   0,   0, 
-    224,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    148,   1,   0,   0,   0,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0, 160,   1, 
-      0,   0,   0,   0,   0,   0, 
-    176,   1,   0,   0,  16,   0, 
-      0,   0,   4,   0,   0,   0, 
-      2,   0,   0,   0, 192,   1, 
-      0,   0,   0,   0,   0,   0, 
-    208,   1,   0,   0,  32,   0, 
-      0,   0,  64,   0,   0,   0, 
-      0,   0,   0,   0, 224,   1, 
-      0,   0,   0,   0,   0,   0, 
-    240,   1,   0,   0,  96,   0, 
-      0,   0,  64,   0,   0,   0, 
-      0,   0,   0,   0, 224,   1, 
-      0,   0,   0,   0,   0,   0, 
-    252,   1,   0,   0, 160,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0, 160,   1, 
-      0,   0,   0,   0,   0,   0, 
-     16,   2,   0,   0, 176,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,  32,   2, 
-      0,   0,   0,   0,   0,   0, 
-     48,   2,   0,   0, 192,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,  32,   2, 
-      0,   0,   0,   0,   0,   0, 
-     59,   2,   0,   0, 208,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,  32,   2, 
-      0,   0,   0,   0,   0,   0, 
-    102,  76,  97, 121, 101, 114, 
-     67, 111, 108, 111, 114,   0, 
-      1,   0,   3,   0,   1,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0, 102,  76, 
-     97, 121, 101, 114,  79, 112, 
-     97,  99, 105, 116, 121,   0, 
-    171, 171,   0,   0,   3,   0, 
-      1,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    109,  76,  97, 121, 101, 114, 
-     84, 114,  97, 110, 115, 102, 
-    111, 114, 109,   0,   3,   0, 
-      3,   0,   4,   0,   4,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 109,  80, 114, 111, 
-    106, 101,  99, 116, 105, 111, 
-    110,   0, 118,  82, 101, 110, 
-    100, 101, 114,  84,  97, 114, 
-    103, 101, 116,  79, 102, 102, 
-    115, 101, 116,   0, 118,  84, 
-    101, 120, 116, 117, 114, 101, 
-     67, 111, 111, 114, 100, 115, 
-      0, 171,   1,   0,   3,   0, 
-      1,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    118,  76,  97, 121, 101, 114, 
-     81, 117,  97, 100,   0, 118, 
-     77,  97, 115, 107,  81, 117, 
-     97, 100,   0,  77, 105,  99, 
-    114, 111, 115, 111, 102, 116, 
-     32,  40,  82,  41,  32,  72, 
-     76,  83,  76,  32,  83, 104, 
-     97, 100, 101, 114,  32,  67, 
-    111, 109, 112, 105, 108, 101, 
-    114,  32,  57,  46,  51,  48, 
-     46,  57,  50,  48,  48,  46, 
-     50,  48,  53,  52,  54,   0, 
-     73,  83,  71,  78, 104,   0, 
-      0,   0,   3,   0,   0,   0, 
-      8,   0,   0,   0,  80,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0,  92,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0,  92,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-     12,  12,   0,   0,  83,  86, 
-     95,  80, 111, 115, 105, 116, 
-    105, 111, 110,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0, 171, 171, 171,  79,  83, 
-     71,  78,  44,   0,   0,   0, 
-      1,   0,   0,   0,   8,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  84, 
-     97, 114, 103, 101, 116,   0, 
-    171, 171
-};
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
-// Buffer Definitions: 
-//
-// cbuffer $Globals
-// {
-//
-//   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
-//   float fLayerOpacity;               // Offset:   16 Size:     4
-//   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
-//   float4x4 mProjection;              // Offset:   96 Size:    64 [unused]
-//   float4 vRenderTargetOffset;        // Offset:  160 Size:    16 [unused]
-//   float4 vTextureCoords;             // Offset:  176 Size:    16 [unused]
-//   float4 vLayerQuad;                 // Offset:  192 Size:    16 [unused]
-//   float4 vMaskQuad;                  // Offset:  208 Size:    16 [unused]
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// sSampler                          sampler      NA          NA    0        1
-// tRGB                              texture  float4          2d    0        1
-// tMask                             texture  float4          2d    3        1
-// $Globals                          cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1     zw        1     NONE   float     zw
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
-//
-//
-// Constant buffer to DX9 shader constant mappings:
-//
-// Target Reg Buffer  Start Reg # of Regs        Data Conversion
-// ---------- ------- --------- --------- ----------------------
-// c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
-//
-//
-// Sampler/Resource to DX9 shader sampler mappings:
-//
-// Target Sampler Source Sampler  Source Resource
-// -------------- --------------- ----------------
-// s0             s0              t3               
-// s1             s0              t0               
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    dcl t0
-    dcl_2d s0
-    dcl_2d s1
-    mov r0.xy, t0.wzzw
-    texld r1, t0, s1
-    texld r0, r0, s0
-    mul r1, r1, c0.x
-    mul r0, r0.w, r1
-    mov oC0, r0
-
-// approximately 6 instruction slots used (2 texture, 4 arithmetic)
-ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_resource_texture2d (float,float,float,float) t3
-dcl_input_ps linear v1.xy
-dcl_input_ps linear v1.zw
-dcl_output o0.xyzw
-dcl_temps 2
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul r0.xyzw, r0.xyzw, cb0[1].xxxx
-sample r1.xyzw, v1.zwzz, t3.xyzw, s0
-mul o0.xyzw, r0.xyzw, r1.wwww
-ret 
-// Approximately 5 instruction slots used
-#endif
-
-const BYTE RGBAShaderMask[] =
-{
-     68,  88,  66,  67, 106,  15, 
-     51,  47, 230,  18,  55,  40, 
-     97,  21, 143,  67,  32,  99, 
-    176,  32,   1,   0,   0,   0, 
-    156,   5,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    252,   0,   0,   0, 252,   1, 
-      0,   0, 120,   2,   0,   0, 
-    248,   4,   0,   0, 104,   5, 
-      0,   0,  65, 111, 110,  57, 
-    188,   0,   0,   0, 188,   0, 
-      0,   0,   0,   2, 255, 255, 
-    132,   0,   0,   0,  56,   0, 
-      0,   0,   1,   0,  44,   0, 
-      0,   0,  56,   0,   0,   0, 
-     56,   0,   2,   0,  36,   0, 
-      0,   0,  56,   0,   3,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   1,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   2, 255, 255,  31,   0, 
-      0,   2,   0,   0,   0, 128, 
-      0,   0,  15, 176,  31,   0, 
-      0,   2,   0,   0,   0, 144, 
-      0,   8,  15, 160,  31,   0, 
-      0,   2,   0,   0,   0, 144, 
-      1,   8,  15, 160,   1,   0, 
-      0,   2,   0,   0,   3, 128, 
-      0,   0, 235, 176,  66,   0, 
-      0,   3,   1,   0,  15, 128, 
-      0,   0, 228, 176,   1,   8, 
-    228, 160,  66,   0,   0,   3, 
-      0,   0,  15, 128,   0,   0, 
-    228, 128,   0,   8, 228, 160, 
-      5,   0,   0,   3,   1,   0, 
-     15, 128,   1,   0, 228, 128, 
-      0,   0,   0, 160,   5,   0, 
-      0,   3,   0,   0,  15, 128, 
-      0,   0, 255, 128,   1,   0, 
-    228, 128,   1,   0,   0,   2, 
-      0,   8,  15, 128,   0,   0, 
-    228, 128, 255, 255,   0,   0, 
-     83,  72,  68,  82, 248,   0, 
-      0,   0,  64,   0,   0,   0, 
-     62,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  90,   0,   0,   3, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  85,  85,   0,   0, 
-     88,  24,   0,   4,   0, 112, 
-     16,   0,   3,   0,   0,   0, 
-     85,  85,   0,   0,  98,  16, 
-      0,   3,  50,  16,  16,   0, 
-      1,   0,   0,   0,  98,  16, 
-      0,   3, 194,  16,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      0,   0,   0,   0, 104,   0, 
-      0,   2,   2,   0,   0,   0, 
-     69,   0,   0,   9, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,  16,  16,   0,   1,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,   0,  96, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   8, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,  14,  16,   0,   0,   0, 
-      0,   0,   6, 128,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  69,   0,   0,   9, 
-    242,   0,  16,   0,   1,   0, 
-      0,   0, 230,  26,  16,   0, 
-      1,   0,   0,   0,  70, 126, 
-     16,   0,   3,   0,   0,   0, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  56,   0,   0,   7, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      0,   0,   0,   0, 246,  15, 
-     16,   0,   1,   0,   0,   0, 
-     62,   0,   0,   1,  83,  84, 
-     65,  84, 116,   0,   0,   0, 
-      5,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   2,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,  82,  68,  69,  70, 
@@ -3888,19 +3539,19 @@ const BYTE RGBAShaderMask[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  57,  46,  51,  48, 
-     46,  57,  50,  48,  48,  46, 
-     50,  48,  53,  52,  54,   0, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
      73,  83,  71,  78, 104,   0, 
       0,   0,   3,   0,   0,   0, 
       8,   0,   0,   0,  80,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  92,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -3922,20 +3573,357 @@ const BYTE RGBAShaderMask[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer $Globals
+// {
+//
+//   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
+//   float fLayerOpacity;               // Offset:   16 Size:     4
+//   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
+//   float4x4 mProjection;              // Offset:   96 Size:    64 [unused]
+//   float4 vRenderTargetOffset;        // Offset:  160 Size:    16 [unused]
+//   float4 vTextureCoords;             // Offset:  176 Size:    16 [unused]
+//   float4 vLayerQuad;                 // Offset:  192 Size:    16 [unused]
+//   float4 vMaskQuad;                  // Offset:  208 Size:    16 [unused]
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// sSampler                          sampler      NA          NA    0        1
+// tRGB                              texture  float4          2d    0        1
+// tMask                             texture  float4          2d    3        1
+// $Globals                          cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+// TEXCOORD                 1     zw        1     NONE   float     zw
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Constant buffer to DX9 shader constant mappings:
+//
+// Target Reg Buffer  Start Reg # of Regs        Data Conversion
+// ---------- ------- --------- --------- ----------------------
+// c0         cb0             1         1  ( FLT, FLT, FLT, FLT)
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t3               
+// s1             s0              t0               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    dcl t0
+    dcl_2d s0
+    dcl_2d s1
+    mov r0.xy, t0.wzzw
+    texld r1, t0, s1
+    texld r0, r0, s0
+    mul r1, r1, c0.x
+    mul r0, r0.w, r1
+    mov oC0, r0
+
+// approximately 6 instruction slots used (2 texture, 4 arithmetic)
+ps_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_resource_texture2d (float,float,float,float) t3
+dcl_input_ps linear v1.xy
+dcl_input_ps linear v1.zw
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul r0.xyzw, r0.xyzw, cb0[1].xxxx
+sample r1.xyzw, v1.zwzz, t3.xyzw, s0
+mul o0.xyzw, r0.xyzw, r1.wwww
+ret 
+// Approximately 5 instruction slots used
+#endif
+
+const BYTE RGBAShaderMask[] =
+{
+     68,  88,  66,  67, 188,  13, 
+    191, 168, 231, 201,  42, 209, 
+     88, 243,  29,  35, 226,  31, 
+    145,  20,   1,   0,   0,   0, 
+    156,   5,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    252,   0,   0,   0, 252,   1, 
+      0,   0, 120,   2,   0,   0, 
+    248,   4,   0,   0, 104,   5, 
+      0,   0,  65, 111, 110,  57, 
+    188,   0,   0,   0, 188,   0, 
+      0,   0,   0,   2, 255, 255, 
+    132,   0,   0,   0,  56,   0, 
+      0,   0,   1,   0,  44,   0, 
+      0,   0,  56,   0,   0,   0, 
+     56,   0,   2,   0,  36,   0, 
+      0,   0,  56,   0,   3,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   1,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   2, 255, 255,  31,   0, 
+      0,   2,   0,   0,   0, 128, 
+      0,   0,  15, 176,  31,   0, 
+      0,   2,   0,   0,   0, 144, 
+      0,   8,  15, 160,  31,   0, 
+      0,   2,   0,   0,   0, 144, 
+      1,   8,  15, 160,   1,   0, 
+      0,   2,   0,   0,   3, 128, 
+      0,   0, 235, 176,  66,   0, 
+      0,   3,   1,   0,  15, 128, 
+      0,   0, 228, 176,   1,   8, 
+    228, 160,  66,   0,   0,   3, 
+      0,   0,  15, 128,   0,   0, 
+    228, 128,   0,   8, 228, 160, 
+      5,   0,   0,   3,   1,   0, 
+     15, 128,   1,   0, 228, 128, 
+      0,   0,   0, 160,   5,   0, 
+      0,   3,   0,   0,  15, 128, 
+      0,   0, 255, 128,   1,   0, 
+    228, 128,   1,   0,   0,   2, 
+      0,   8,  15, 128,   0,   0, 
+    228, 128, 255, 255,   0,   0, 
+     83,  72,  68,  82, 248,   0, 
+      0,   0,  64,   0,   0,   0, 
+     62,   0,   0,   0,  89,   0, 
+      0,   4,  70, 142,  32,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  90,   0,   0,   3, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  88,  24,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  85,  85,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   3,   0,   0,   0, 
+     85,  85,   0,   0,  98,  16, 
+      0,   3,  50,  16,  16,   0, 
+      1,   0,   0,   0,  98,  16, 
+      0,   3, 194,  16,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   2,   0,   0,   0, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  16,  16,   0,   1,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   8, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  14,  16,   0,   0,   0, 
+      0,   0,   6, 128,  32,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   1,   0, 
+      0,   0, 230,  26,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   3,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  56,   0,   0,   7, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0, 246,  15, 
+     16,   0,   1,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      5,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  82,  68,  69,  70, 
+    120,   2,   0,   0,   1,   0, 
+      0,   0, 188,   0,   0,   0, 
+      4,   0,   0,   0,  28,   0, 
+      0,   0,   0,   4, 255, 255, 
+      0,   1,   0,   0,  69,   2, 
+      0,   0, 156,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      1,   0,   0,   0, 165,   0, 
+      0,   0,   2,   0,   0,   0, 
+      5,   0,   0,   0,   4,   0, 
+      0,   0, 255, 255, 255, 255, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,  12,   0,   0,   0, 
+    170,   0,   0,   0,   2,   0, 
+      0,   0,   5,   0,   0,   0, 
+      4,   0,   0,   0, 255, 255, 
+    255, 255,   3,   0,   0,   0, 
+      1,   0,   0,   0,  13,   0, 
+      0,   0, 176,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0, 115,  83, 
+     97, 109, 112, 108, 101, 114, 
+      0, 116,  82,  71,  66,   0, 
+    116,  77,  97, 115, 107,   0, 
+     36,  71, 108, 111,  98,  97, 
+    108, 115,   0, 171, 171, 171, 
+    176,   0,   0,   0,   8,   0, 
+      0,   0, 212,   0,   0,   0, 
+    224,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    148,   1,   0,   0,   0,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0, 160,   1, 
+      0,   0,   0,   0,   0,   0, 
+    176,   1,   0,   0,  16,   0, 
+      0,   0,   4,   0,   0,   0, 
+      2,   0,   0,   0, 192,   1, 
+      0,   0,   0,   0,   0,   0, 
+    208,   1,   0,   0,  32,   0, 
+      0,   0,  64,   0,   0,   0, 
+      0,   0,   0,   0, 224,   1, 
+      0,   0,   0,   0,   0,   0, 
+    240,   1,   0,   0,  96,   0, 
+      0,   0,  64,   0,   0,   0, 
+      0,   0,   0,   0, 224,   1, 
+      0,   0,   0,   0,   0,   0, 
+    252,   1,   0,   0, 160,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0, 160,   1, 
+      0,   0,   0,   0,   0,   0, 
+     16,   2,   0,   0, 176,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0,  32,   2, 
+      0,   0,   0,   0,   0,   0, 
+     48,   2,   0,   0, 192,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0,  32,   2, 
+      0,   0,   0,   0,   0,   0, 
+     59,   2,   0,   0, 208,   0, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0,  32,   2, 
+      0,   0,   0,   0,   0,   0, 
+    102,  76,  97, 121, 101, 114, 
+     67, 111, 108, 111, 114,   0, 
+      1,   0,   3,   0,   1,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0, 102,  76, 
+     97, 121, 101, 114,  79, 112, 
+     97,  99, 105, 116, 121,   0, 
+    171, 171,   0,   0,   3,   0, 
+      1,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    109,  76,  97, 121, 101, 114, 
+     84, 114,  97, 110, 115, 102, 
+    111, 114, 109,   0,   3,   0, 
+      3,   0,   4,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 109,  80, 114, 111, 
+    106, 101,  99, 116, 105, 111, 
+    110,   0, 118,  82, 101, 110, 
+    100, 101, 114,  84,  97, 114, 
+    103, 101, 116,  79, 102, 102, 
+    115, 101, 116,   0, 118,  84, 
+    101, 120, 116, 117, 114, 101, 
+     67, 111, 111, 114, 100, 115, 
+      0, 171,   1,   0,   3,   0, 
+      1,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+    118,  76,  97, 121, 101, 114, 
+     81, 117,  97, 100,   0, 118, 
+     77,  97, 115, 107,  81, 117, 
+     97, 100,   0,  77, 105,  99, 
+    114, 111, 115, 111, 102, 116, 
+     32,  40,  82,  41,  32,  72, 
+     76,  83,  76,  32,  83, 104, 
+     97, 100, 101, 114,  32,  67, 
+    111, 109, 112, 105, 108, 101, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
+     73,  83,  71,  78, 104,   0, 
+      0,   0,   3,   0,   0,   0, 
+      8,   0,   0,   0,  80,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0,  92,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0,  92,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+     12,  12,   0,   0,  83,  86, 
+     95,  80, 111, 115, 105, 116, 
+    105, 111, 110,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0, 171, 171, 171,  79,  83, 
+     71,  78,  44,   0,   0,   0, 
+      1,   0,   0,   0,   8,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  84, 
+     97, 114, 103, 101, 116,   0, 
+    171, 171
+};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
 //   float fLayerOpacity;               // Offset:   16 Size:     4
 //   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
@@ -4023,20 +4011,20 @@ sample r1.xyzw, v1.xyxx, t0.xyzw, s0
 mul r1.xyzw, r1.xyzw, cb0[1].xxxx
 mul o0.xyzw, r0.wwww, r1.xyzw
 ret 
 // Approximately 6 instruction slots used
 #endif
 
 const BYTE RGBAShaderMask3D[] =
 {
-     68,  88,  66,  67, 176, 186, 
-     72,  64, 199, 228, 205, 219, 
-     97, 152, 199, 132, 157, 124, 
-    226, 212,   1,   0,   0,   0, 
+     68,  88,  66,  67, 113, 141, 
+     78,  23, 128, 223, 235,  10, 
+      0,  97,  49, 111,  47,  53, 
+    229,  55,   1,   0,   0,   0, 
      24,   6,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      24,   1,   0,   0,  64,   2, 
       0,   0, 188,   2,   0,   0, 
     116,   5,   0,   0, 228,   5, 
       0,   0,  65, 111, 110,  57, 
     216,   0,   0,   0, 216,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -4133,17 +4121,17 @@ const BYTE RGBAShaderMask3D[] =
       1,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   2,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,  82,  68, 
      69,  70, 176,   2,   0,   0, 
       1,   0,   0,   0, 244,   0, 
@@ -4253,19 +4241,19 @@ const BYTE RGBAShaderMask3D[] =
      97, 100,   0, 118,  77,  97, 
     115, 107,  81, 117,  97, 100, 
       0,  77, 105,  99, 114, 111, 
     115, 111, 102, 116,  32,  40, 
      82,  41,  32,  72,  76,  83, 
      76,  32,  83, 104,  97, 100, 
     101, 114,  32,  67, 111, 109, 
     112, 105, 108, 101, 114,  32, 
-     57,  46,  51,  48,  46,  57, 
-     50,  48,  48,  46,  50,  48, 
-     53,  52,  54,   0,  73,  83, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
      71,  78, 104,   0,   0,   0, 
       3,   0,   0,   0,   8,   0, 
       0,   0,  80,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  92,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -4286,20 +4274,19 @@ const BYTE RGBAShaderMask3D[] =
       0,   0,   0,   0,   0,   0, 
       3,   0,   0,   0,   0,   0, 
       0,   0,  15,   0,   0,   0, 
      83,  86,  95,  84,  97, 114, 
     103, 101, 116,   0, 171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
 //   float fLayerOpacity;               // Offset:   16 Size:     4
 //   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
@@ -4416,20 +4403,20 @@ mul r0.xyzw, r1.xyzw, cb0[1].xxxx
 sample r1.xyzw, v1.zwzz, t3.xyzw, s0
 mul o0.xyzw, r0.xyzw, r1.wwww
 ret 
 // Approximately 17 instruction slots used
 #endif
 
 const BYTE YCbCrShaderMask[] =
 {
-     68,  88,  66,  67, 115,  10, 
-     33,  43, 108, 217,  72,  92, 
-    140,  65,  97,  68, 194, 221, 
-     95,  25,   1,   0,   0,   0, 
+     68,  88,  66,  67, 103, 162, 
+    223, 236, 236, 142, 143, 151, 
+     73, 154, 187, 112,  81, 114, 
+    229, 251,   1,   0,   0,   0, 
     168,   8,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      24,   2,   0,   0, 196,   4, 
       0,   0,  64,   5,   0,   0, 
       4,   8,   0,   0, 116,   8, 
       0,   0,  65, 111, 110,  57, 
     216,   1,   0,   0, 216,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -4623,27 +4610,27 @@ const BYTE YCbCrShaderMask[] =
      16,   0,   0,   0,   0,   0, 
      70,  14,  16,   0,   0,   0, 
       0,   0, 246,  15,  16,   0, 
       1,   0,   0,   0,  62,   0, 
       0,   1,  83,  84,  65,  84, 
     116,   0,   0,   0,  17,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,   3,   0, 
-      0,   0,   7,   0,   0,   0, 
+      0,   0,  11,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       4,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
      82,  68,  69,  70, 188,   2, 
       0,   0,   1,   0,   0,   0, 
@@ -4755,19 +4742,19 @@ const BYTE YCbCrShaderMask[] =
      81, 117,  97, 100,   0, 118, 
      77,  97, 115, 107,  81, 117, 
      97, 100,   0,  77, 105,  99, 
     114, 111, 115, 111, 102, 116, 
      32,  40,  82,  41,  32,  72, 
      76,  83,  76,  32,  83, 104, 
      97, 100, 101, 114,  32,  67, 
     111, 109, 112, 105, 108, 101, 
-    114,  32,  57,  46,  51,  48, 
-     46,  57,  50,  48,  48,  46, 
-     50,  48,  53,  52,  54,   0, 
+    114,  32,  54,  46,  51,  46, 
+     57,  54,  48,  48,  46,  49, 
+     54,  51,  56,  52,   0, 171, 
      73,  83,  71,  78, 104,   0, 
       0,   0,   3,   0,   0,   0, 
       8,   0,   0,   0,  80,   0, 
       0,   0,   0,   0,   0,   0, 
       1,   0,   0,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  92,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -4789,20 +4776,19 @@ const BYTE YCbCrShaderMask[] =
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  83,  86,  95,  84, 
      97, 114, 103, 101, 116,   0, 
     171, 171
 };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
 //   float fLayerOpacity;               // Offset:   16 Size:     4
 //   float4x4 mLayerTransform;          // Offset:   32 Size:    64 [unused]
@@ -4903,20 +4889,20 @@ mul r2.x, r2.w, cb0[1].x
 mul o0.xyzw, r1.xyzw, r2.xxxx
 mul o1.xyzw, r0.xyzw, r2.xxxx
 ret 
 // Approximately 10 instruction slots used
 #endif
 
 const BYTE ComponentAlphaShaderMask[] =
 {
-     68,  88,  66,  67,  66, 175, 
-    106, 103, 136,  76, 200,  80, 
-     95, 179,  74, 140, 138, 144, 
-     12,  21,   1,   0,   0,   0, 
+     68,  88,  66,  67, 245,  71, 
+    211, 223, 156, 101, 223, 204, 
+    145, 138,  53,  12,  16, 220, 
+    106,  83,   1,   0,   0,   0, 
      20,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     124,   1,   0,   0,  52,   3, 
       0,   0, 176,   3,   0,   0, 
      88,   6,   0,   0, 200,   6, 
       0,   0,  65, 111, 110,  57, 
      60,   1,   0,   0,  60,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -5053,17 +5039,17 @@ const BYTE ComponentAlphaShaderMask[] =
       0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
       0,   0,  82,  68,  69,  70, 
     160,   2,   0,   0,   1,   0, 
@@ -5171,19 +5157,19 @@ const BYTE ComponentAlphaShaderMask[] =
      97, 100,   0, 118,  77,  97, 
     115, 107,  81, 117,  97, 100, 
       0,  77, 105,  99, 114, 111, 
     115, 111, 102, 116,  32,  40, 
      82,  41,  32,  72,  76,  83, 
      76,  32,  83, 104,  97, 100, 
     101, 114,  32,  67, 111, 109, 
     112, 105, 108, 101, 114,  32, 
-     57,  46,  51,  48,  46,  57, 
-     50,  48,  48,  46,  50,  48, 
-     53,  52,  54,   0,  73,  83, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171,  73,  83, 
      71,  78, 104,   0,   0,   0, 
       3,   0,   0,   0,   8,   0, 
       0,   0,  80,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
       0,   0,   3,   0,   0,   0, 
       0,   0,   0,   0,  15,   0, 
       0,   0,  92,   0,   0,   0, 
       0,   0,   0,   0,   0,   0, 
--- a/gfx/layers/d3d11/CompositorD3D11ShadersVR.h
+++ b/gfx/layers/d3d11/CompositorD3D11ShadersVR.h
@@ -1,638 +1,636 @@
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
-// Buffer Definitions: 
-//
-// cbuffer $Globals
-// {
-//
-//   float4 VREyeToSource;              // Offset:    0 Size:    16
-//   float4 VRDestinationScaleAndOffset;// Offset:   16 Size:    16
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// $Globals                          cbuffer      NA          NA    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// POSITION                 0   xy          0     NONE   float   xy  
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1   xy          2     NONE   float   xy  
-// TEXCOORD                 2   xy          3     NONE   float   xy  
-// COLOR                    0   xyzw        4     NONE   float   xyzw
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   xyz         1     NONE   float   xyz 
-// TEXCOORD                 1   xyz         2     NONE   float   xyz 
-// TEXCOORD                 2   xyz         3     NONE   float   xyz 
-// COLOR                    0   xyzw        4     NONE   float   xyzw
-//
-//
-// Constant buffer to DX9 shader constant mappings:
-//
-// Target Reg Buffer  Start Reg # of Regs        Data Conversion
-// ---------- ------- --------- --------- ----------------------
-// c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
-//
-//
-// Runtime generated constant mappings:
-//
-// Target Reg                               Constant Description
-// ---------- --------------------------------------------------
-// c0                              Vertex Shader position offset
-//
-//
-// Level9 shader bytecode:
-//
-    vs_2_x
-    def c3, 0.5, 1, 0, 0
-    dcl_texcoord v0
-    dcl_texcoord1 v1
-    dcl_texcoord2 v2
-    dcl_texcoord3 v3
-    dcl_texcoord4 v4
-    mad oT0.xy, c1, v1, c1.zwzw
-    mad oT1.xy, c1, v2, c1.zwzw
-    mad oT2.xy, c1, v3, c1.zwzw
-    mad r0.xy, v0, c2.zwzw, c2
-    add oPos.xy, r0, c0
-    mov oPos.zw, c3.xyxy
-    mov oT0.z, c3.y
-    mov oT1.z, c3.y
-    mov oT2.z, c3.y
-    mov oT3, v4
-
-// approximately 10 instruction slots used
-vs_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
-dcl_input v0.xy
-dcl_input v1.xy
-dcl_input v2.xy
-dcl_input v3.xy
-dcl_input v4.xyzw
-dcl_output_siv o0.xyzw, position
-dcl_output o1.xyz
-dcl_output o2.xyz
-dcl_output o3.xyz
-dcl_output o4.xyzw
-mad o0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx
-mov o0.zw, l(0,0,0.500000,1.000000)
-mad o1.xy, cb0[0].xyxx, v1.xyxx, cb0[0].zwzz
-mov o1.z, l(1.000000)
-mad o2.xy, cb0[0].xyxx, v2.xyxx, cb0[0].zwzz
-mov o2.z, l(1.000000)
-mad o3.xy, cb0[0].xyxx, v3.xyxx, cb0[0].zwzz
-mov o3.z, l(1.000000)
-mov o4.xyzw, v4.xyzw
-ret 
-// Approximately 10 instruction slots used
-#endif
-
-const BYTE OculusVRDistortionVS[] =
-{
-     68,  88,  66,  67, 146, 215, 
-     61, 238,  94,   6,  58,  25, 
-     65, 203, 120, 251,  26,  22, 
-    109,   4,   1,   0,   0,   0, 
-    244,   5,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    108,   1,   0,   0,  44,   3, 
-      0,   0, 168,   3,   0,   0, 
-    176,   4,   0,   0,  80,   5, 
-      0,   0,  65, 111, 110,  57, 
-     44,   1,   0,   0,  44,   1, 
-      0,   0,   0,   2, 254, 255, 
-    248,   0,   0,   0,  52,   0, 
-      0,   0,   1,   0,  36,   0, 
-      0,   0,  48,   0,   0,   0, 
-     48,   0,   0,   0,  36,   0, 
-      1,   0,  48,   0,   0,   0, 
-      0,   0,   2,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   2, 254, 255, 
-     81,   0,   0,   5,   3,   0, 
-     15, 160,   0,   0,   0,  63, 
-      0,   0, 128,  63,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     31,   0,   0,   2,   5,   0, 
-      0, 128,   0,   0,  15, 144, 
-     31,   0,   0,   2,   5,   0, 
-      1, 128,   1,   0,  15, 144, 
-     31,   0,   0,   2,   5,   0, 
-      2, 128,   2,   0,  15, 144, 
-     31,   0,   0,   2,   5,   0, 
-      3, 128,   3,   0,  15, 144, 
-     31,   0,   0,   2,   5,   0, 
-      4, 128,   4,   0,  15, 144, 
-      4,   0,   0,   4,   0,   0, 
-      3, 224,   1,   0, 228, 160, 
-      1,   0, 228, 144,   1,   0, 
-    238, 160,   4,   0,   0,   4, 
-      1,   0,   3, 224,   1,   0, 
-    228, 160,   2,   0, 228, 144, 
-      1,   0, 238, 160,   4,   0, 
-      0,   4,   2,   0,   3, 224, 
-      1,   0, 228, 160,   3,   0, 
-    228, 144,   1,   0, 238, 160, 
-      4,   0,   0,   4,   0,   0, 
-      3, 128,   0,   0, 228, 144, 
-      2,   0, 238, 160,   2,   0, 
-    228, 160,   2,   0,   0,   3, 
-      0,   0,   3, 192,   0,   0, 
-    228, 128,   0,   0, 228, 160, 
-      1,   0,   0,   2,   0,   0, 
-     12, 192,   3,   0,  68, 160, 
-      1,   0,   0,   2,   0,   0, 
-      4, 224,   3,   0,  85, 160, 
-      1,   0,   0,   2,   1,   0, 
-      4, 224,   3,   0,  85, 160, 
-      1,   0,   0,   2,   2,   0, 
-      4, 224,   3,   0,  85, 160, 
-      1,   0,   0,   2,   3,   0, 
-     15, 224,   4,   0, 228, 144, 
-    255, 255,   0,   0,  83,  72, 
-     68,  82, 184,   1,   0,   0, 
-     64,   0,   1,   0, 110,   0, 
-      0,   0,  89,   0,   0,   4, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-     95,   0,   0,   3,  50,  16, 
-     16,   0,   0,   0,   0,   0, 
-     95,   0,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-     95,   0,   0,   3,  50,  16, 
-     16,   0,   2,   0,   0,   0, 
-     95,   0,   0,   3,  50,  16, 
-     16,   0,   3,   0,   0,   0, 
-     95,   0,   0,   3, 242,  16, 
-     16,   0,   4,   0,   0,   0, 
-    103,   0,   0,   4, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 114,  32,  16,   0, 
-      1,   0,   0,   0, 101,   0, 
-      0,   3, 114,  32,  16,   0, 
-      2,   0,   0,   0, 101,   0, 
-      0,   3, 114,  32,  16,   0, 
-      3,   0,   0,   0, 101,   0, 
-      0,   3, 242,  32,  16,   0, 
-      4,   0,   0,   0,  50,   0, 
-      0,  11,  50,  32,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   0,   0,   0,   0, 
-    230, 138,  32,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     70, 128,  32,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     54,   0,   0,   8, 194,  32, 
-     16,   0,   0,   0,   0,   0, 
-      2,  64,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,  63,   0,   0, 
-    128,  63,  50,   0,   0,  11, 
-     50,  32,  16,   0,   1,   0, 
-      0,   0,  70, 128,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0, 230, 138, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5,  66,  32,  16,   0, 
-      1,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0, 128,  63, 
-     50,   0,   0,  11,  50,  32, 
-     16,   0,   2,   0,   0,   0, 
-     70, 128,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     70,  16,  16,   0,   2,   0, 
-      0,   0, 230, 138,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  54,   0,   0,   5, 
-     66,  32,  16,   0,   2,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0, 128,  63,  50,   0, 
-      0,  11,  50,  32,  16,   0, 
-      3,   0,   0,   0,  70, 128, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   3,   0,   0,   0, 
-    230, 138,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     54,   0,   0,   5,  66,  32, 
-     16,   0,   3,   0,   0,   0, 
-      1,  64,   0,   0,   0,   0, 
-    128,  63,  54,   0,   0,   5, 
-    242,  32,  16,   0,   4,   0, 
-      0,   0,  70,  30,  16,   0, 
-      4,   0,   0,   0,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,  10,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  10,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     82,  68,  69,  70,   0,   1, 
-      0,   0,   1,   0,   0,   0, 
-     72,   0,   0,   0,   1,   0, 
-      0,   0,  28,   0,   0,   0, 
-      0,   4, 254, 255,   0,   1, 
-      0,   0, 204,   0,   0,   0, 
-     60,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,  36,  71, 108, 111, 
-     98,  97, 108, 115,   0, 171, 
-    171, 171,  60,   0,   0,   0, 
-      2,   0,   0,   0,  96,   0, 
-      0,   0,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0, 144,   0,   0,   0, 
-      0,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    160,   0,   0,   0,   0,   0, 
-      0,   0, 176,   0,   0,   0, 
-     16,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    160,   0,   0,   0,   0,   0, 
-      0,   0,  86,  82,  69, 121, 
-    101,  84, 111,  83, 111, 117, 
-    114,  99, 101,   0, 171, 171, 
-      1,   0,   3,   0,   1,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,  86,  82, 
-     68, 101, 115, 116, 105, 110, 
-     97, 116, 105, 111, 110,  83, 
-     99,  97, 108, 101,  65, 110, 
-    100,  79, 102, 102, 115, 101, 
-    116,   0,  77, 105,  99, 114, 
-    111, 115, 111, 102, 116,  32, 
-     40,  82,  41,  32,  72,  76, 
-     83,  76,  32,  83, 104,  97, 
-    100, 101, 114,  32,  67, 111, 
-    109, 112, 105, 108, 101, 114, 
-     32,  57,  46,  51,  48,  46, 
-     57,  50,  48,  48,  46,  50, 
-     48,  53,  52,  54,   0, 171, 
-     73,  83,  71,  78, 152,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 128,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   3,   0,   0, 137,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      3,   3,   0,   0, 137,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      3,   3,   0,   0, 137,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   3,   0,   0,   0, 
-      3,   3,   0,   0, 146,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   4,   0,   0,   0, 
-     15,  15,   0,   0,  80,  79, 
-     83,  73,  84,  73,  79,  78, 
-      0,  84,  69,  88,  67,  79, 
-     79,  82,  68,   0,  67,  79, 
-     76,  79,  82,   0,  79,  83, 
-     71,  78, 156,   0,   0,   0, 
-      5,   0,   0,   0,   8,   0, 
-      0,   0, 128,   0,   0,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,  15,   0, 
-      0,   0, 140,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   7,   8, 
-      0,   0, 140,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   7,   8, 
-      0,   0, 140,   0,   0,   0, 
-      2,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      3,   0,   0,   0,   7,   8, 
-      0,   0, 149,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      4,   0,   0,   0,  15,   0, 
-      0,   0,  83,  86,  95,  80, 
-    111, 115, 105, 116, 105, 111, 
-    110,   0,  84,  69,  88,  67, 
-     79,  79,  82,  68,   0,  67, 
-     79,  76,  79,  82,   0, 171
-};
-#if 0
-//
-// Generated by Microsoft (R) HLSL Shader Compiler 9.30.9200.20546
-//
-//
-///
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// Linear                            sampler      NA          NA    0        1
-// Texture                           texture  float4          2d    0        1
-//
-//
-//
-// Input signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float       
-// TEXCOORD                 0   xyz         1     NONE   float   xy  
-// TEXCOORD                 1   xyz         2     NONE   float   xy  
-// TEXCOORD                 2   xyz         3     NONE   float   xy  
-// COLOR                    0   xyzw        4     NONE   float   x   
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Target                0   xyzw        0   TARGET   float   xyzw
-//
-//
-// Sampler/Resource to DX9 shader sampler mappings:
-//
-// Target Sampler Source Sampler  Source Resource
-// -------------- --------------- ----------------
-// s0             s0              t0               
-//
-//
-// Level9 shader bytecode:
-//
-    ps_2_x
-    def c0, 1, 0, 0, 0
-    dcl t0.xyz
-    dcl t1.xyz
-    dcl t2.xyz
-    dcl t3
-    dcl_2d s0
-    texld r0, t1, s0
-    texld r1, t0, s0
-    mul r1.x, r1.x, t3.x
-    mul r1.y, r0.y, t3.x
-    texld r0, t2, s0
-    mul r1.z, r0.z, t3.x
-    mov r1.w, c0.x
-    mov oC0, r1
-
-// approximately 8 instruction slots used (3 texture, 5 arithmetic)
-ps_4_0
-dcl_sampler s0, mode_default
-dcl_resource_texture2d (float,float,float,float) t0
-dcl_input_ps linear v1.xy
-dcl_input_ps linear v2.xy
-dcl_input_ps linear v3.xy
-dcl_input_ps linear v4.x
-dcl_output o0.xyzw
-dcl_temps 1
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul o0.x, r0.x, v4.x
-sample r0.xyzw, v2.xyxx, t0.xyzw, s0
-mul o0.y, r0.y, v4.x
-sample r0.xyzw, v3.xyxx, t0.xyzw, s0
-mul o0.z, r0.z, v4.x
-mov o0.w, l(1.000000)
-ret 
-// Approximately 8 instruction slots used
-#endif
-
-const BYTE OculusVRDistortionPS[] =
-{
-     68,  88,  66,  67, 150, 176, 
-     84, 101, 196,  27,  87, 110, 
-    226, 144, 161,  15,  69,  81, 
-     48, 158,   1,   0,   0,   0, 
-    128,   4,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-     60,   1,   0,   0, 132,   2, 
-      0,   0,   0,   3,   0,   0, 
-    168,   3,   0,   0,  76,   4, 
-      0,   0,  65, 111, 110,  57, 
-    252,   0,   0,   0, 252,   0, 
-      0,   0,   0,   2, 255, 255, 
-    212,   0,   0,   0,  40,   0, 
-      0,   0,   0,   0,  40,   0, 
-      0,   0,  40,   0,   0,   0, 
-     40,   0,   1,   0,  36,   0, 
-      0,   0,  40,   0,   0,   0, 
-      0,   0,   1,   2, 255, 255, 
-     81,   0,   0,   5,   0,   0, 
-     15, 160,   0,   0, 128,  63, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   0,   0,   7, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   1,   0,   7, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   2,   0,   7, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 128,   3,   0,  15, 176, 
-     31,   0,   0,   2,   0,   0, 
-      0, 144,   0,   8,  15, 160, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   1,   0, 228, 176, 
-      0,   8, 228, 160,  66,   0, 
-      0,   3,   1,   0,  15, 128, 
-      0,   0, 228, 176,   0,   8, 
-    228, 160,   5,   0,   0,   3, 
-      1,   0,   1, 128,   1,   0, 
-      0, 128,   3,   0,   0, 176, 
-      5,   0,   0,   3,   1,   0, 
-      2, 128,   0,   0,  85, 128, 
-      3,   0,   0, 176,  66,   0, 
-      0,   3,   0,   0,  15, 128, 
-      2,   0, 228, 176,   0,   8, 
-    228, 160,   5,   0,   0,   3, 
-      1,   0,   4, 128,   0,   0, 
-    170, 128,   3,   0,   0, 176, 
-      1,   0,   0,   2,   1,   0, 
-      8, 128,   0,   0,   0, 160, 
-      1,   0,   0,   2,   0,   8, 
-     15, 128,   1,   0, 228, 128, 
-    255, 255,   0,   0,  83,  72, 
-     68,  82,  64,   1,   0,   0, 
-     64,   0,   0,   0,  80,   0, 
-      0,   0,  90,   0,   0,   3, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   0,   0, 
-      0,   0,  85,  85,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   1,   0,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   2,   0,   0,   0, 
-     98,  16,   0,   3,  50,  16, 
-     16,   0,   3,   0,   0,   0, 
-     98,  16,   0,   3,  18,  16, 
-     16,   0,   4,   0,   0,   0, 
-    101,   0,   0,   3, 242,  32, 
-     16,   0,   0,   0,   0,   0, 
-    104,   0,   0,   2,   1,   0, 
-      0,   0,  69,   0,   0,   9, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      1,   0,   0,   0,  70, 126, 
-     16,   0,   0,   0,   0,   0, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  56,   0,   0,   7, 
-     18,  32,  16,   0,   0,   0, 
-      0,   0,  10,   0,  16,   0, 
-      0,   0,   0,   0,  10,  16, 
-     16,   0,   4,   0,   0,   0, 
-     69,   0,   0,   9, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,  16,  16,   0,   2,   0, 
-      0,   0,  70, 126,  16,   0, 
-      0,   0,   0,   0,   0,  96, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   7,  34,  32, 
-     16,   0,   0,   0,   0,   0, 
-     26,   0,  16,   0,   0,   0, 
-      0,   0,  10,  16,  16,   0, 
-      4,   0,   0,   0,  69,   0, 
-      0,   9, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
-     16,   0,   3,   0,   0,   0, 
-     70, 126,  16,   0,   0,   0, 
-      0,   0,   0,  96,  16,   0, 
-      0,   0,   0,   0,  56,   0, 
-      0,   7,  66,  32,  16,   0, 
-      0,   0,   0,   0,  42,   0, 
-     16,   0,   0,   0,   0,   0, 
-     10,  16,  16,   0,   4,   0, 
-      0,   0,  54,   0,   0,   5, 
-    130,  32,  16,   0,   0,   0, 
-      0,   0,   1,  64,   0,   0, 
-      0,   0, 128,  63,  62,   0, 
-      0,   1,  83,  84,  65,  84, 
-    116,   0,   0,   0,   8,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   5,   0, 
-      0,   0,   3,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-     82,  68,  69,  70, 160,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   2,   0, 
-      0,   0,  28,   0,   0,   0, 
-      0,   4, 255, 255,   0,   1, 
-      0,   0, 107,   0,   0,   0, 
-     92,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,  99,   0,   0,   0, 
-      2,   0,   0,   0,   5,   0, 
-      0,   0,   4,   0,   0,   0, 
-    255, 255, 255, 255,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     13,   0,   0,   0,  76, 105, 
-    110, 101,  97, 114,   0,  84, 
-    101, 120, 116, 117, 114, 101, 
-      0,  77, 105,  99, 114, 111, 
-    115, 111, 102, 116,  32,  40, 
-     82,  41,  32,  72,  76,  83, 
-     76,  32,  83, 104,  97, 100, 
-    101, 114,  32,  67, 111, 109, 
-    112, 105, 108, 101, 114,  32, 
-     57,  46,  51,  48,  46,  57, 
-     50,  48,  48,  46,  50,  48, 
-     53,  52,  54,   0, 171, 171, 
-     73,  83,  71,  78, 156,   0, 
-      0,   0,   5,   0,   0,   0, 
-      8,   0,   0,   0, 128,   0, 
-      0,   0,   0,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-     15,   0,   0,   0, 140,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   1,   0,   0,   0, 
-      7,   3,   0,   0, 140,   0, 
-      0,   0,   1,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   2,   0,   0,   0, 
-      7,   3,   0,   0, 140,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   3,   0,   0,   0, 
-      7,   3,   0,   0, 149,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,   4,   0,   0,   0, 
-     15,   1,   0,   0,  83,  86, 
-     95,  80, 111, 115, 105, 116, 
-    105, 111, 110,   0,  84,  69, 
-     88,  67,  79,  79,  82,  68, 
-      0,  67,  79,  76,  79,  82, 
-      0, 171,  79,  83,  71,  78, 
-     44,   0,   0,   0,   1,   0, 
-      0,   0,   8,   0,   0,   0, 
-     32,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   0,   0,   0,   0, 
-      0,   0,  15,   0,   0,   0, 
-     83,  86,  95,  84,  97, 114, 
-    103, 101, 116,   0, 171, 171
-};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer $Globals
+// {
+//
+//   float4 VREyeToSource;              // Offset:    0 Size:    16
+//   float4 VRDestinationScaleAndOffset;// Offset:   16 Size:    16
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// $Globals                          cbuffer      NA          NA    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// POSITION                 0   xy          0     NONE   float   xy  
+// TEXCOORD                 0   xy          1     NONE   float   xy  
+// TEXCOORD                 1   xy          2     NONE   float   xy  
+// TEXCOORD                 2   xy          3     NONE   float   xy  
+// COLOR                    0   xyzw        4     NONE   float   xyzw
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float   xyzw
+// TEXCOORD                 0   xyz         1     NONE   float   xyz 
+// TEXCOORD                 1   xyz         2     NONE   float   xyz 
+// TEXCOORD                 2   xyz         3     NONE   float   xyz 
+// COLOR                    0   xyzw        4     NONE   float   xyzw
+//
+//
+// Constant buffer to DX9 shader constant mappings:
+//
+// Target Reg Buffer  Start Reg # of Regs        Data Conversion
+// ---------- ------- --------- --------- ----------------------
+// c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
+//
+//
+// Runtime generated constant mappings:
+//
+// Target Reg                               Constant Description
+// ---------- --------------------------------------------------
+// c0                              Vertex Shader position offset
+//
+//
+// Level9 shader bytecode:
+//
+    vs_2_x
+    def c3, 0.5, 1, 0, 0
+    dcl_texcoord v0
+    dcl_texcoord1 v1
+    dcl_texcoord2 v2
+    dcl_texcoord3 v3
+    dcl_texcoord4 v4
+    mad oT0.xy, v1, c1.zwzw, c1
+    mad oT1.xy, v2, c1.zwzw, c1
+    mad oT2.xy, v3, c1.zwzw, c1
+    mad r0.xy, v0, c2.zwzw, c2
+    add oPos.xy, r0, c0
+    mov oPos.zw, c3.xyxy
+    mov oT0.z, c3.y
+    mov oT1.z, c3.y
+    mov oT2.z, c3.y
+    mov oT3, v4
+
+// approximately 10 instruction slots used
+vs_4_0
+dcl_constantbuffer cb0[2], immediateIndexed
+dcl_input v0.xy
+dcl_input v1.xy
+dcl_input v2.xy
+dcl_input v3.xy
+dcl_input v4.xyzw
+dcl_output_siv o0.xyzw, position
+dcl_output o1.xyz
+dcl_output o2.xyz
+dcl_output o3.xyz
+dcl_output o4.xyzw
+mad o0.xy, v0.xyxx, cb0[1].zwzz, cb0[1].xyxx
+mov o0.zw, l(0,0,0.500000,1.000000)
+mad o1.xy, v1.xyxx, cb0[0].zwzz, cb0[0].xyxx
+mov o1.z, l(1.000000)
+mad o2.xy, v2.xyxx, cb0[0].zwzz, cb0[0].xyxx
+mov o2.z, l(1.000000)
+mad o3.xy, v3.xyxx, cb0[0].zwzz, cb0[0].xyxx
+mov o3.z, l(1.000000)
+mov o4.xyzw, v4.xyzw
+ret 
+// Approximately 10 instruction slots used
+#endif
+
+const BYTE OculusVRDistortionVS[] =
+{
+     68,  88,  66,  67,   3,  61, 
+    196, 122,  10,  53,  44, 234, 
+     18, 242, 195, 238,  42,  90, 
+     72, 193,   1,   0,   0,   0, 
+    244,   5,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+    108,   1,   0,   0,  44,   3, 
+      0,   0, 168,   3,   0,   0, 
+    176,   4,   0,   0,  80,   5, 
+      0,   0,  65, 111, 110,  57, 
+     44,   1,   0,   0,  44,   1, 
+      0,   0,   0,   2, 254, 255, 
+    248,   0,   0,   0,  52,   0, 
+      0,   0,   1,   0,  36,   0, 
+      0,   0,  48,   0,   0,   0, 
+     48,   0,   0,   0,  36,   0, 
+      1,   0,  48,   0,   0,   0, 
+      0,   0,   2,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   2, 254, 255, 
+     81,   0,   0,   5,   3,   0, 
+     15, 160,   0,   0,   0,  63, 
+      0,   0, 128,  63,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     31,   0,   0,   2,   5,   0, 
+      0, 128,   0,   0,  15, 144, 
+     31,   0,   0,   2,   5,   0, 
+      1, 128,   1,   0,  15, 144, 
+     31,   0,   0,   2,   5,   0, 
+      2, 128,   2,   0,  15, 144, 
+     31,   0,   0,   2,   5,   0, 
+      3, 128,   3,   0,  15, 144, 
+     31,   0,   0,   2,   5,   0, 
+      4, 128,   4,   0,  15, 144, 
+      4,   0,   0,   4,   0,   0, 
+      3, 224,   1,   0, 228, 144, 
+      1,   0, 238, 160,   1,   0, 
+    228, 160,   4,   0,   0,   4, 
+      1,   0,   3, 224,   2,   0, 
+    228, 144,   1,   0, 238, 160, 
+      1,   0, 228, 160,   4,   0, 
+      0,   4,   2,   0,   3, 224, 
+      3,   0, 228, 144,   1,   0, 
+    238, 160,   1,   0, 228, 160, 
+      4,   0,   0,   4,   0,   0, 
+      3, 128,   0,   0, 228, 144, 
+      2,   0, 238, 160,   2,   0, 
+    228, 160,   2,   0,   0,   3, 
+      0,   0,   3, 192,   0,   0, 
+    228, 128,   0,   0, 228, 160, 
+      1,   0,   0,   2,   0,   0, 
+     12, 192,   3,   0,  68, 160, 
+      1,   0,   0,   2,   0,   0, 
+      4, 224,   3,   0,  85, 160, 
+      1,   0,   0,   2,   1,   0, 
+      4, 224,   3,   0,  85, 160, 
+      1,   0,   0,   2,   2,   0, 
+      4, 224,   3,   0,  85, 160, 
+      1,   0,   0,   2,   3,   0, 
+     15, 224,   4,   0, 228, 144, 
+    255, 255,   0,   0,  83,  72, 
+     68,  82, 184,   1,   0,   0, 
+     64,   0,   1,   0, 110,   0, 
+      0,   0,  89,   0,   0,   4, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,   2,   0,   0,   0, 
+     95,   0,   0,   3,  50,  16, 
+     16,   0,   0,   0,   0,   0, 
+     95,   0,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+     95,   0,   0,   3,  50,  16, 
+     16,   0,   2,   0,   0,   0, 
+     95,   0,   0,   3,  50,  16, 
+     16,   0,   3,   0,   0,   0, 
+     95,   0,   0,   3, 242,  16, 
+     16,   0,   4,   0,   0,   0, 
+    103,   0,   0,   4, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 114,  32,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 114,  32,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 114,  32,  16,   0, 
+      3,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      4,   0,   0,   0,  50,   0, 
+      0,  11,  50,  32,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   0,   0,   0,   0, 
+    230, 138,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     70, 128,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     54,   0,   0,   8, 194,  32, 
+     16,   0,   0,   0,   0,   0, 
+      2,  64,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,  63,   0,   0, 
+    128,  63,  50,   0,   0,  11, 
+     50,  32,  16,   0,   1,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0, 230, 138, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  70, 128, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   5,  66,  32,  16,   0, 
+      1,   0,   0,   0,   1,  64, 
+      0,   0,   0,   0, 128,  63, 
+     50,   0,   0,  11,  50,  32, 
+     16,   0,   2,   0,   0,   0, 
+     70,  16,  16,   0,   2,   0, 
+      0,   0, 230, 138,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  70, 128,  32,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+     66,  32,  16,   0,   2,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128,  63,  50,   0, 
+      0,  11,  50,  32,  16,   0, 
+      3,   0,   0,   0,  70,  16, 
+     16,   0,   3,   0,   0,   0, 
+    230, 138,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     70, 128,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     54,   0,   0,   5,  66,  32, 
+     16,   0,   3,   0,   0,   0, 
+      1,  64,   0,   0,   0,   0, 
+    128,  63,  54,   0,   0,   5, 
+    242,  32,  16,   0,   4,   0, 
+      0,   0,  70,  30,  16,   0, 
+      4,   0,   0,   0,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,  10,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  10,   0, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   5,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     82,  68,  69,  70,   0,   1, 
+      0,   0,   1,   0,   0,   0, 
+     72,   0,   0,   0,   1,   0, 
+      0,   0,  28,   0,   0,   0, 
+      0,   4, 254, 255,   0,   1, 
+      0,   0, 204,   0,   0,   0, 
+     60,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,  36,  71, 108, 111, 
+     98,  97, 108, 115,   0, 171, 
+    171, 171,  60,   0,   0,   0, 
+      2,   0,   0,   0,  96,   0, 
+      0,   0,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 144,   0,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   0,   2,   0,   0,   0, 
+    160,   0,   0,   0,   0,   0, 
+      0,   0, 176,   0,   0,   0, 
+     16,   0,   0,   0,  16,   0, 
+      0,   0,   2,   0,   0,   0, 
+    160,   0,   0,   0,   0,   0, 
+      0,   0,  86,  82,  69, 121, 
+    101,  84, 111,  83, 111, 117, 
+    114,  99, 101,   0, 171, 171, 
+      1,   0,   3,   0,   1,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,  86,  82, 
+     68, 101, 115, 116, 105, 110, 
+     97, 116, 105, 111, 110,  83, 
+     99,  97, 108, 101,  65, 110, 
+    100,  79, 102, 102, 115, 101, 
+    116,   0,  77, 105,  99, 114, 
+    111, 115, 111, 102, 116,  32, 
+     40,  82,  41,  32,  72,  76, 
+     83,  76,  32,  83, 104,  97, 
+    100, 101, 114,  32,  67, 111, 
+    109, 112, 105, 108, 101, 114, 
+     32,  54,  46,  51,  46,  57, 
+     54,  48,  48,  46,  49,  54, 
+     51,  56,  52,   0, 171, 171, 
+     73,  83,  71,  78, 152,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 128,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   3,   0,   0, 137,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      3,   3,   0,   0, 137,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      3,   3,   0,   0, 137,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   3,   0,   0,   0, 
+      3,   3,   0,   0, 146,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   4,   0,   0,   0, 
+     15,  15,   0,   0,  80,  79, 
+     83,  73,  84,  73,  79,  78, 
+      0,  84,  69,  88,  67,  79, 
+     79,  82,  68,   0,  67,  79, 
+     76,  79,  82,   0,  79,  83, 
+     71,  78, 156,   0,   0,   0, 
+      5,   0,   0,   0,   8,   0, 
+      0,   0, 128,   0,   0,   0, 
+      0,   0,   0,   0,   1,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,  15,   0, 
+      0,   0, 140,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      1,   0,   0,   0,   7,   8, 
+      0,   0, 140,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      2,   0,   0,   0,   7,   8, 
+      0,   0, 140,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      3,   0,   0,   0,   7,   8, 
+      0,   0, 149,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   3,   0,   0,   0, 
+      4,   0,   0,   0,  15,   0, 
+      0,   0,  83,  86,  95,  80, 
+    111, 115, 105, 116, 105, 111, 
+    110,   0,  84,  69,  88,  67, 
+     79,  79,  82,  68,   0,  67, 
+     79,  76,  79,  82,   0, 171
+};
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim Slot Elements
+// ------------------------------ ---------- ------- ----------- ---- --------
+// Linear                            sampler      NA          NA    0        1
+// Texture                           texture  float4          2d    0        1
+//
+//
+//
+// Input signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Position              0   xyzw        0      POS   float       
+// TEXCOORD                 0   xyz         1     NONE   float   xy  
+// TEXCOORD                 1   xyz         2     NONE   float   xy  
+// TEXCOORD                 2   xyz         3     NONE   float   xy  
+// COLOR                    0   xyzw        4     NONE   float   x   
+//
+//
+// Output signature:
+//
+// Name                 Index   Mask Register SysValue  Format   Used
+// -------------------- ----- ------ -------- -------- ------- ------
+// SV_Target                0   xyzw        0   TARGET   float   xyzw
+//
+//
+// Sampler/Resource to DX9 shader sampler mappings:
+//
+// Target Sampler Source Sampler  Source Resource
+// -------------- --------------- ----------------
+// s0             s0              t0               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    def c0, 1, 0, 0, 0
+    dcl t0.xyz
+    dcl t1.xyz
+    dcl t2.xyz
+    dcl t3
+    dcl_2d s0
+    texld r0, t1, s0
+    texld r1, t0, s0
+    mul r1.x, r1.x, t3.x
+    mul r1.y, r0.y, t3.x
+    texld r0, t2, s0
+    mul r1.z, r0.z, t3.x
+    mov r1.w, c0.x
+    mov oC0, r1
+
+// approximately 8 instruction slots used (3 texture, 5 arithmetic)
+ps_4_0
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t0
+dcl_input_ps linear v1.xy
+dcl_input_ps linear v2.xy
+dcl_input_ps linear v3.xy
+dcl_input_ps linear v4.x
+dcl_output o0.xyzw
+dcl_temps 1
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul o0.x, r0.x, v4.x
+sample r0.xyzw, v2.xyxx, t0.xyzw, s0
+mul o0.y, r0.y, v4.x
+sample r0.xyzw, v3.xyxx, t0.xyzw, s0
+mul o0.z, r0.z, v4.x
+mov o0.w, l(1.000000)
+ret 
+// Approximately 8 instruction slots used
+#endif
+
+const BYTE OculusVRDistortionPS[] =
+{
+     68,  88,  66,  67, 108, 219, 
+     61, 216,  27,   0,  27, 222, 
+    242, 132, 183,  21, 166, 141, 
+    130,  39,   1,   0,   0,   0, 
+    128,   4,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+     60,   1,   0,   0, 132,   2, 
+      0,   0,   0,   3,   0,   0, 
+    168,   3,   0,   0,  76,   4, 
+      0,   0,  65, 111, 110,  57, 
+    252,   0,   0,   0, 252,   0, 
+      0,   0,   0,   2, 255, 255, 
+    212,   0,   0,   0,  40,   0, 
+      0,   0,   0,   0,  40,   0, 
+      0,   0,  40,   0,   0,   0, 
+     40,   0,   1,   0,  36,   0, 
+      0,   0,  40,   0,   0,   0, 
+      0,   0,   1,   2, 255, 255, 
+     81,   0,   0,   5,   0,   0, 
+     15, 160,   0,   0, 128,  63, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   0,   0,   7, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   1,   0,   7, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   2,   0,   7, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 128,   3,   0,  15, 176, 
+     31,   0,   0,   2,   0,   0, 
+      0, 144,   0,   8,  15, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   1,   0, 228, 176, 
+      0,   8, 228, 160,  66,   0, 
+      0,   3,   1,   0,  15, 128, 
+      0,   0, 228, 176,   0,   8, 
+    228, 160,   5,   0,   0,   3, 
+      1,   0,   1, 128,   1,   0, 
+      0, 128,   3,   0,   0, 176, 
+      5,   0,   0,   3,   1,   0, 
+      2, 128,   0,   0,  85, 128, 
+      3,   0,   0, 176,  66,   0, 
+      0,   3,   0,   0,  15, 128, 
+      2,   0, 228, 176,   0,   8, 
+    228, 160,   5,   0,   0,   3, 
+      1,   0,   4, 128,   0,   0, 
+    170, 128,   3,   0,   0, 176, 
+      1,   0,   0,   2,   1,   0, 
+      8, 128,   0,   0,   0, 160, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   1,   0, 228, 128, 
+    255, 255,   0,   0,  83,  72, 
+     68,  82,  64,   1,   0,   0, 
+     64,   0,   0,   0,  80,   0, 
+      0,   0,  90,   0,   0,   3, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  88,  24,   0,   4, 
+      0, 112,  16,   0,   0,   0, 
+      0,   0,  85,  85,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   1,   0,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   2,   0,   0,   0, 
+     98,  16,   0,   3,  50,  16, 
+     16,   0,   3,   0,   0,   0, 
+     98,  16,   0,   3,  18,  16, 
+     16,   0,   4,   0,   0,   0, 
+    101,   0,   0,   3, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+    104,   0,   0,   2,   1,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  16,  16,   0, 
+      1,   0,   0,   0,  70, 126, 
+     16,   0,   0,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  56,   0,   0,   7, 
+     18,  32,  16,   0,   0,   0, 
+      0,   0,  10,   0,  16,   0, 
+      0,   0,   0,   0,  10,  16, 
+     16,   0,   4,   0,   0,   0, 
+     69,   0,   0,   9, 242,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  16,  16,   0,   2,   0, 
+      0,   0,  70, 126,  16,   0, 
+      0,   0,   0,   0,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     56,   0,   0,   7,  34,  32, 
+     16,   0,   0,   0,   0,   0, 
+     26,   0,  16,   0,   0,   0, 
+      0,   0,  10,  16,  16,   0, 
+      4,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   3,   0,   0,   0, 
+     70, 126,  16,   0,   0,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  56,   0, 
+      0,   7,  66,  32,  16,   0, 
+      0,   0,   0,   0,  42,   0, 
+     16,   0,   0,   0,   0,   0, 
+     10,  16,  16,   0,   4,   0, 
+      0,   0,  54,   0,   0,   5, 
+    130,  32,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128,  63,  62,   0, 
+      0,   1,  83,  84,  65,  84, 
+    116,   0,   0,   0,   8,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   5,   0, 
+      0,   0,   3,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     82,  68,  69,  70, 160,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   2,   0, 
+      0,   0,  28,   0,   0,   0, 
+      0,   4, 255, 255,   0,   1, 
+      0,   0, 107,   0,   0,   0, 
+     92,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   0,   0, 
+      0,   0,  99,   0,   0,   0, 
+      2,   0,   0,   0,   5,   0, 
+      0,   0,   4,   0,   0,   0, 
+    255, 255, 255, 255,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     13,   0,   0,   0,  76, 105, 
+    110, 101,  97, 114,   0,  84, 
+    101, 120, 116, 117, 114, 101, 
+      0,  77, 105,  99, 114, 111, 
+    115, 111, 102, 116,  32,  40, 
+     82,  41,  32,  72,  76,  83, 
+     76,  32,  83, 104,  97, 100, 
+    101, 114,  32,  67, 111, 109, 
+    112, 105, 108, 101, 114,  32, 
+     54,  46,  51,  46,  57,  54, 
+     48,  48,  46,  49,  54,  51, 
+     56,  52,   0, 171, 171, 171, 
+     73,  83,  71,  78, 156,   0, 
+      0,   0,   5,   0,   0,   0, 
+      8,   0,   0,   0, 128,   0, 
+      0,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,   3,   0, 
+      0,   0,   0,   0,   0,   0, 
+     15,   0,   0,   0, 140,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   1,   0,   0,   0, 
+      7,   3,   0,   0, 140,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   3,   0,   0, 140,   0, 
+      0,   0,   2,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   3,   0,   0,   0, 
+      7,   3,   0,   0, 149,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   4,   0,   0,   0, 
+     15,   1,   0,   0,  83,  86, 
+     95,  80, 111, 115, 105, 116, 
+    105, 111, 110,   0,  84,  69, 
+     88,  67,  79,  79,  82,  68, 
+      0,  67,  79,  76,  79,  82, 
+      0, 171,  79,  83,  71,  78, 
+     44,   0,   0,   0,   1,   0, 
+      0,   0,   8,   0,   0,   0, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   0,   0, 
+      0,   0,  15,   0,   0,   0, 
+     83,  86,  95,  84,  97, 114, 
+    103, 101, 116,   0, 171, 171
+};
--- a/gfx/layers/d3d11/CompositorD3D11VR.hlsl
+++ b/gfx/layers/d3d11/CompositorD3D11VR.hlsl
@@ -32,23 +32,26 @@ struct VS_VR_OUTPUT {
 
 SamplerState Linear
 {
   Filter = MIN_MAG_MIP_LINEAR;
   AddressU = Clamp;
   AddressV = Clamp;
 };
 
+/*
+ * Oculus basic distortion, with chroma aberration correction
+ */
 VS_VR_OUTPUT OculusVRDistortionVS(const VS_VR_INPUT aVertex)
 {
   VS_VR_OUTPUT res;
 
-  float2 tc0 = VREyeToSource.xy * aVertex.vTexCoord0 + VREyeToSource.zw;
-  float2 tc1 = VREyeToSource.xy * aVertex.vTexCoord1 + VREyeToSource.zw;
-  float2 tc2 = VREyeToSource.xy * aVertex.vTexCoord2 + VREyeToSource.zw;
+  float2 tc0 = aVertex.vTexCoord0 * VREyeToSource.zw + VREyeToSource.xy;
+  float2 tc1 = aVertex.vTexCoord1 * VREyeToSource.zw + VREyeToSource.xy;
+  float2 tc2 = aVertex.vTexCoord2 * VREyeToSource.zw + VREyeToSource.xy;
 
   //res.vPosition.xy = aVertex.vPosition.xy;
   res.vPosition.xy = aVertex.vPosition.xy * VRDestinationScaleAndOffset.zw + VRDestinationScaleAndOffset.xy;
   res.vPosition.zw = float2(0.5, 1.0);
 
   res.vTexCoord0 = float3(tc0, 1);
   res.vTexCoord1 = float3(tc1, 1);
   res.vTexCoord2 = float3(tc2, 1);
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -173,16 +173,17 @@ struct CompositorOGLVRObjects {
   // (in this case Oculus only).  We'll need to extend this to support
   // other device types in the future.
 
   // 0 = TEXTURE_2D, 1 = TEXTURE_RECTANGLE for source
   GLuint mDistortionProgram[2];
   GLint mUTexture[2];
   GLint mUVREyeToSource[2];
   GLint mUVRDestionatinScaleAndOffset[2];
+  GLint mUHeight[2];
 };
 
 // If you want to make this class not final, first remove calls to virtual
 // methods (Destroy) that are made in the destructor.
 class CompositorOGL final : public Compositor
 {
   typedef mozilla::gl::GLContext GLContext;
 
--- a/gfx/layers/opengl/CompositorOGLVR.cpp
+++ b/gfx/layers/opengl/CompositorOGLVR.cpp
@@ -50,33 +50,34 @@ CompositorOGL::InitializeVR()
   mVR.mATexCoord1 = 2;
   mVR.mATexCoord2 = 3;
   mVR.mAGenericAttribs = 4;
 
   ostringstream vs;
 
   vs << "uniform vec4 uVREyeToSource;\n";
   vs << "uniform vec4 uVRDestinationScaleAndOffset;\n";
+  vs << "uniform float uHeight;\n";
   vs << "attribute vec2 aPosition;\n";
   vs << "attribute vec2 aTexCoord0;\n";
   vs << "attribute vec2 aTexCoord1;\n";
   vs << "attribute vec2 aTexCoord2;\n";
   vs << "attribute vec4 aGenericAttribs;\n";
   vs << "varying vec2 vTexCoord0;\n";
   vs << "varying vec2 vTexCoord1;\n";
   vs << "varying vec2 vTexCoord2;\n";
   vs << "varying vec4 vGenericAttribs;\n";
   vs << "void main() {\n";
   vs << "  gl_Position = vec4(aPosition.xy * uVRDestinationScaleAndOffset.zw + uVRDestinationScaleAndOffset.xy, 0.5, 1.0);\n";
-  vs << "  vTexCoord0 = uVREyeToSource.xy * aTexCoord0 + uVREyeToSource.zw;\n";
-  vs << "  vTexCoord1 = uVREyeToSource.xy * aTexCoord1 + uVREyeToSource.zw;\n";
-  vs << "  vTexCoord2 = uVREyeToSource.xy * aTexCoord2 + uVREyeToSource.zw;\n";
-  vs << "  vTexCoord0.y = 1.0 - vTexCoord0.y;\n";
-  vs << "  vTexCoord1.y = 1.0 - vTexCoord1.y;\n";
-  vs << "  vTexCoord2.y = 1.0 - vTexCoord2.y;\n";
+  vs << "  vTexCoord0 = uVREyeToSource.zw * aTexCoord0 + uVREyeToSource.xy;\n";
+  vs << "  vTexCoord1 = uVREyeToSource.zw * aTexCoord1 + uVREyeToSource.xy;\n";
+  vs << "  vTexCoord2 = uVREyeToSource.zw * aTexCoord2 + uVREyeToSource.xy;\n";
+  vs << "  vTexCoord0.y = uHeight - vTexCoord0.y;\n";
+  vs << "  vTexCoord1.y = uHeight - vTexCoord1.y;\n";
+  vs << "  vTexCoord2.y = uHeight - vTexCoord2.y;\n";
   vs << "  vGenericAttribs = aGenericAttribs;\n";
   vs << "}\n";
 
   std::string vsSrcString(vs.str());
   const char *vsSrc = vsSrcString.c_str();
 
   for (int programIndex = 0; programIndex < 2; programIndex++) {
     GLenum textureTarget = programIndex == 0 ? LOCAL_GL_TEXTURE_2D : LOCAL_GL_TEXTURE_RECTANGLE;
@@ -92,17 +93,16 @@ CompositorOGL::InitializeVR()
       texture2D = "texture2DRect";
     }
 
     if (gl()->IsGLES()) {
       fs << "precision highp float;\n";
     }
 
     fs << "uniform " << sampler2D << " uTexture;\n";
-
     fs << "varying vec2 vTexCoord0;\n";
     fs << "varying vec2 vTexCoord1;\n";
     fs << "varying vec2 vTexCoord2;\n";
     fs << "varying vec4 vGenericAttribs;\n";
     fs << "void main() {\n";
     fs << "  float resR = " << texture2D << "(uTexture, vTexCoord0.xy).r;\n";
     fs << "  float resG = " << texture2D << "(uTexture, vTexCoord1.xy).g;\n";
     fs << "  float resB = " << texture2D << "(uTexture, vTexCoord2.xy).b;\n";
@@ -174,16 +174,17 @@ CompositorOGL::InitializeVR()
       gl()->fDeleteShader(shaders[1]);
 
       return false;
     }
 
     mVR.mUTexture[programIndex] = gl()->fGetUniformLocation(prog, "uTexture");
     mVR.mUVREyeToSource[programIndex] = gl()->fGetUniformLocation(prog, "uVREyeToSource");
     mVR.mUVRDestionatinScaleAndOffset[programIndex] = gl()->fGetUniformLocation(prog, "uVRDestinationScaleAndOffset");
+    mVR.mUHeight[programIndex] = gl()->fGetUniformLocation(prog, "uHeight");
 
     mVR.mDistortionProgram[programIndex] = prog;
 
     gl()->fDeleteShader(shaders[0]);
     gl()->fDeleteShader(shaders[1]);
   }
 
   mVR.mInitialized = true;
@@ -262,16 +263,20 @@ CompositorOGL::DrawVRDistortion(const gf
                  aClipRect.width, aClipRect.height);
 
   // Clear out the entire area that we want to render; this ensures that
   // the layer will be opaque, even though the mesh geometry we'll be
   // drawing below won't cover the full rectangle.
   gl()->fClearColor(0.0, 0.0, 0.0, 1.0);
   gl()->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);
 
+  // Make sure that the cached current program is reset for the
+  // rest of the compositor, since we're using a custom program here
+  ResetProgram();
+
   gl()->fUseProgram(mVR.mDistortionProgram[programIndex]);
 
   gl()->fEnableVertexAttribArray(mVR.mAPosition);
   gl()->fEnableVertexAttribArray(mVR.mATexCoord0);
   gl()->fEnableVertexAttribArray(mVR.mATexCoord1);
   gl()->fEnableVertexAttribArray(mVR.mATexCoord2);
   gl()->fEnableVertexAttribArray(mVR.mAGenericAttribs);
 
@@ -288,31 +293,42 @@ CompositorOGL::DrawVRDistortion(const gf
     eyeViewport.width = size.width / 2;
     eyeViewport.height = size.height;
 
     hmdInfo->FillDistortionConstants(eye,
                                      size, eyeViewport,
                                      vpSize, aRect,
                                      shaderConstants);
 
+    float height = 1.0f;
+    float texScaleAndOffset[4] = { shaderConstants.eyeToSourceScaleAndOffset[0],
+                                   shaderConstants.eyeToSourceScaleAndOffset[1],
+                                   shaderConstants.eyeToSourceScaleAndOffset[2],
+                                   shaderConstants.eyeToSourceScaleAndOffset[3] };
+    if (textureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB) {
+      texScaleAndOffset[0] *= size.width;
+      texScaleAndOffset[1] *= size.height;
+      texScaleAndOffset[2] *= size.width;
+      texScaleAndOffset[3] *= size.height;
+      height = size.height;
+    }
+
     gl()->fUniform4fv(mVR.mUVRDestionatinScaleAndOffset[programIndex], 1, shaderConstants.destinationScaleAndOffset);
-    gl()->fUniform4fv(mVR.mUVREyeToSource[programIndex], 1, shaderConstants.eyeToSourceScaleAndOffset);
+    gl()->fUniform4fv(mVR.mUVREyeToSource[programIndex], 1, texScaleAndOffset);
+    gl()->fUniform1f(mVR.mUHeight[programIndex], height);
 
     gl()->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mVR.mDistortionVertices[eye]);
 
-    gl()->fVertexAttribPointer(mVR.mAPosition, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex),
-                               (void*) offsetof(gfx::VRDistortionVertex, pos));
-    gl()->fVertexAttribPointer(mVR.mATexCoord0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex),
-                               (void*) offsetof(gfx::VRDistortionVertex, texR));
-    gl()->fVertexAttribPointer(mVR.mATexCoord1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex),
-                               (void*) offsetof(gfx::VRDistortionVertex, texG));
-    gl()->fVertexAttribPointer(mVR.mATexCoord2, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex),
-                               (void*) offsetof(gfx::VRDistortionVertex, texB));
-    gl()->fVertexAttribPointer(mVR.mAGenericAttribs, 4, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex),
-                               (void*) offsetof(gfx::VRDistortionVertex, genericAttribs));
+    /* This is for Oculus DistortionVertex */
+
+    gl()->fVertexAttribPointer(mVR.mAPosition,  2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), (void*) (sizeof(float) * 0));
+    gl()->fVertexAttribPointer(mVR.mATexCoord0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), (void*) (sizeof(float) * 2));
+    gl()->fVertexAttribPointer(mVR.mATexCoord1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), (void*) (sizeof(float) * 4));
+    gl()->fVertexAttribPointer(mVR.mATexCoord2, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex), (void*) (sizeof(float) * 6));
+    gl()->fVertexAttribPointer(mVR.mAGenericAttribs, 4, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, sizeof(gfx::VRDistortionVertex),  (void*) (sizeof(float) * 8));
 
     gl()->fBindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, mVR.mDistortionIndices[eye]);
     gl()->fDrawElements(LOCAL_GL_TRIANGLES, mVR.mDistortionIndexCount[eye], LOCAL_GL_UNSIGNED_SHORT, 0);
   }
 
   // Not clear if I should disable all of this; but going to do it and hope that
   // any later code will enable what it needs.
   gl()->fDisableVertexAttribArray(mVR.mAPosition);
--- a/gfx/moz.build
+++ b/gfx/moz.build
@@ -18,16 +18,17 @@ DIRS += [
     'qcms',
     'gl',
     'layers',
     'graphite2/src',
     'harfbuzz/src',
     'ots/src',
     'thebes',
     'ipc',
+    'vr',
 ]
 
 if CONFIG['MOZ_ENABLE_SKIA']:
     DIRS += ['skia']
 
 if CONFIG['ENABLE_TESTS']:
     DIRS += ['tests/gtest']
 
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -398,19 +398,18 @@ gfxPlatform::gfxPlatform()
     mSkiaGlue = nullptr;
 
     uint32_t canvasMask = BackendTypeBit(BackendType::CAIRO) | BackendTypeBit(BackendType::SKIA);
     uint32_t contentMask = BackendTypeBit(BackendType::CAIRO);
     InitBackendPrefs(canvasMask, BackendType::CAIRO,
                      contentMask, BackendType::CAIRO);
     mTotalSystemMemory = mozilla::hal::GetTotalSystemMemory();
 
-    // give ovr_Initialize a chance to be called very early on; we don't
-    // care if it succeeds or not
-    VRHMDManagerOculus::PlatformInit();
+    // give HMDs a chance to be initialized very early on
+    VRHMDManager::ManagerInit();
 }
 
 gfxPlatform*
 gfxPlatform::GetPlatform()
 {
     if (!gPlatform) {
         Init();
     }
@@ -695,17 +694,17 @@ gfxPlatform::ShutdownLayersIPC()
 }
 
 gfxPlatform::~gfxPlatform()
 {
     mScreenReferenceSurface = nullptr;
     mScreenReferenceDrawTarget = nullptr;
 
     // Clean up any VR stuff
-    VRHMDManagerOculus::Destroy();
+    VRHMDManager::ManagerDestroy();
 
     // The cairo folks think we should only clean up in debug builds,
     // but we're generally in the habit of trying to shut down as
     // cleanly as possible even in production code, so call this
     // cairo_debug_* function unconditionally.
     //
     // because cairo can assert and thus crash on shutdown, don't do this in release builds
 #if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) || defined(MOZ_VALGRIND)
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -924,18 +924,25 @@ gfxTextRun::BreakAndMeasureText(uint32_t
         trimmableChars = lastBreakTrimmableChars;
         trimmableAdvance = lastBreakTrimmableAdvance;
         usedHyphenation = lastBreakUsedHyphenation;
     } else {
         charsFit = aMaxLength;
     }
 
     if (aMetrics) {
-        *aMetrics = MeasureText(aStart, charsFit - trimmableChars,
+        *aMetrics = MeasureText(aStart, charsFit,
             aBoundingBoxType, aRefContext, aProvider);
+        if (trimmableChars) {
+            Metrics trimMetrics =
+                MeasureText(aStart + charsFit - trimmableChars,
+                            trimmableChars, aBoundingBoxType,
+                            aRefContext, aProvider);
+            aMetrics->mAdvanceWidth -= trimMetrics.mAdvanceWidth;
+        }
     }
     if (aTrimWhitespace) {
         *aTrimWhitespace = trimmableAdvance;
     }
     if (aUsedHyphenation) {
         *aUsedHyphenation = usedHyphenation;
     }
     if (aLastBreak && charsFit == aMaxLength) {
deleted file mode 100644
--- a/gfx/thebes/gfxVR.cpp
+++ /dev/null
@@ -1,658 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * 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 <math.h>
-
-#include "prlink.h"
-#include "prmem.h"
-#include "prenv.h"
-#include "gfxPrefs.h"
-#include "gfxVR.h"
-#include "nsString.h"
-#include "mozilla/Preferences.h"
-
-#include "ovr_capi_dynamic.h"
-
-#include "nsServiceManagerUtils.h"
-#include "nsIScreenManager.h"
-
-#ifdef XP_WIN
-#include "gfxWindowsPlatform.h" // for gfxWindowsPlatform::GetDPIScale
-#endif
-
-#ifndef M_PI
-# define M_PI 3.14159265358979323846
-#endif
-
-namespace {
-
-#ifdef OVR_CAPI_LIMITED_MOZILLA
-static pfn_ovr_Initialize ovr_Initialize = nullptr;
-static pfn_ovr_Shutdown ovr_Shutdown = nullptr;
-static pfn_ovrHmd_Detect ovrHmd_Detect = nullptr;
-static pfn_ovrHmd_Create ovrHmd_Create = nullptr;
-static pfn_ovrHmd_Destroy ovrHmd_Destroy = nullptr;
-static pfn_ovrHmd_CreateDebug ovrHmd_CreateDebug = nullptr;
-static pfn_ovrHmd_GetLastError ovrHmd_GetLastError = nullptr;
-static pfn_ovrHmd_AttachToWindow ovrHmd_AttachToWindow = nullptr;
-static pfn_ovrHmd_GetEnabledCaps ovrHmd_GetEnabledCaps = nullptr;
-static pfn_ovrHmd_SetEnabledCaps ovrHmd_SetEnabledCaps = nullptr;
-static pfn_ovrHmd_ConfigureTracking ovrHmd_ConfigureTracking = nullptr;
-static pfn_ovrHmd_RecenterPose ovrHmd_RecenterPose = nullptr;
-static pfn_ovrHmd_GetTrackingState ovrHmd_GetTrackingState = nullptr;
-static pfn_ovrHmd_GetFovTextureSize ovrHmd_GetFovTextureSize = nullptr;
-static pfn_ovrHmd_GetRenderDesc ovrHmd_GetRenderDesc = nullptr;
-static pfn_ovrHmd_CreateDistortionMesh ovrHmd_CreateDistortionMesh = nullptr;
-static pfn_ovrHmd_DestroyDistortionMesh ovrHmd_DestroyDistortionMesh = nullptr;
-static pfn_ovrHmd_GetRenderScaleAndOffset ovrHmd_GetRenderScaleAndOffset = nullptr;
-static pfn_ovrHmd_GetFrameTiming ovrHmd_GetFrameTiming = nullptr;
-static pfn_ovrHmd_BeginFrameTiming ovrHmd_BeginFrameTiming = nullptr;
-static pfn_ovrHmd_EndFrameTiming ovrHmd_EndFrameTiming = nullptr;
-static pfn_ovrHmd_ResetFrameTiming ovrHmd_ResetFrameTiming = nullptr;
-static pfn_ovrHmd_GetEyePoses ovrHmd_GetEyePoses = nullptr;
-static pfn_ovrHmd_GetHmdPosePerEye ovrHmd_GetHmdPosePerEye = nullptr;
-static pfn_ovrHmd_GetEyeTimewarpMatrices ovrHmd_GetEyeTimewarpMatrices = nullptr;
-static pfn_ovrMatrix4f_Projection ovrMatrix4f_Projection = nullptr;
-static pfn_ovrMatrix4f_OrthoSubProjection ovrMatrix4f_OrthoSubProjection = nullptr;
-static pfn_ovr_GetTimeInSeconds ovr_GetTimeInSeconds = nullptr;
-
-#if defined(XP_WIN)
-# ifdef HAVE_64BIT_BUILD
-#  define OVR_LIB_NAME "libovr64.dll"
-# else
-#  define OVR_LIB_NAME "libovr.dll"
-# endif
-#elif defined(XP_MACOSX)
-# define OVR_LIB_NAME "libovr.dylib"
-#else
-# define OVR_LIB_NAME 0
-#endif
-
-static bool
-InitializeOculusCAPI()
-{
-  static PRLibrary *ovrlib = nullptr;
-
-  if (!ovrlib) {
-    const char *libName = OVR_LIB_NAME;
-
-    // If the pref is present, we override libName
-    nsAdoptingCString prefLibName = mozilla::Preferences::GetCString("dom.vr.ovr_lib_path");
-    if (prefLibName && prefLibName.get()) {
-      libName = prefLibName.get();
-    }
-
-    // If the env var is present, we override libName
-    if (PR_GetEnv("OVR_LIB_NAME")) {
-      libName = PR_GetEnv("OVR_LIB_NAME");
-    }
-
-    if (!libName) {
-      printf_stderr("Don't know how to find Oculus VR library; missing dom.vr.ovr_lib_path or OVR_LIB_NAME\n");
-      return false;
-    }
-
-    ovrlib = PR_LoadLibrary(libName);
-
-    if (!ovrlib) {
-      // Not found? Try harder. Needed mainly on OSX/etc. where
-      // the binary location is not in the search path.
-      const char *xulName = "libxul.so";
-#if defined(XP_MACOSX)
-      xulName = "XUL";
-#endif
-
-      char *xulpath = PR_GetLibraryFilePathname(xulName, (PRFuncPtr) &InitializeOculusCAPI);
-      if (xulpath) {
-        char *xuldir = strrchr(xulpath, '/');
-        if (xuldir) {
-          *xuldir = 0;
-          xuldir = xulpath;
-
-          char *ovrpath = PR_GetLibraryName(xuldir, libName);
-          ovrlib = PR_LoadLibrary(ovrpath);
-          PR_Free(ovrpath);
-        }
-        PR_Free(xulpath);
-      }
-    }
-
-    if (!ovrlib) {
-      printf_stderr("Failed to load Oculus VR library, tried '%s'\n", libName);
-      return false;
-    }
-  }
-
-  // was it already initialized?
-  if (ovr_Initialize)
-    return true;
-
-#define REQUIRE_FUNCTION(_x) do { \
-    *(void **)&_x = (void *) PR_FindSymbol(ovrlib, #_x);                \
-    if (!_x) { printf_stderr(#_x " symbol missing\n"); goto fail; }       \
-  } while (0)
-
-  REQUIRE_FUNCTION(ovr_Initialize);
-  REQUIRE_FUNCTION(ovr_Shutdown);
-  REQUIRE_FUNCTION(ovrHmd_Detect);
-  REQUIRE_FUNCTION(ovrHmd_Create);
-  REQUIRE_FUNCTION(ovrHmd_Destroy);
-  REQUIRE_FUNCTION(ovrHmd_CreateDebug);
-  REQUIRE_FUNCTION(ovrHmd_GetLastError);
-  REQUIRE_FUNCTION(ovrHmd_AttachToWindow);
-  REQUIRE_FUNCTION(ovrHmd_GetEnabledCaps);
-  REQUIRE_FUNCTION(ovrHmd_SetEnabledCaps);
-  REQUIRE_FUNCTION(ovrHmd_ConfigureTracking);
-  REQUIRE_FUNCTION(ovrHmd_RecenterPose);
-  REQUIRE_FUNCTION(ovrHmd_GetTrackingState);
-
-  REQUIRE_FUNCTION(ovrHmd_GetFovTextureSize);
-  REQUIRE_FUNCTION(ovrHmd_GetRenderDesc);
-  REQUIRE_FUNCTION(ovrHmd_CreateDistortionMesh);
-  REQUIRE_FUNCTION(ovrHmd_DestroyDistortionMesh);
-  REQUIRE_FUNCTION(ovrHmd_GetRenderScaleAndOffset);
-  REQUIRE_FUNCTION(ovrHmd_GetFrameTiming);
-  REQUIRE_FUNCTION(ovrHmd_BeginFrameTiming);
-  REQUIRE_FUNCTION(ovrHmd_EndFrameTiming);
-  REQUIRE_FUNCTION(ovrHmd_ResetFrameTiming);
-  REQUIRE_FUNCTION(ovrHmd_GetEyePoses);
-  REQUIRE_FUNCTION(ovrHmd_GetHmdPosePerEye);
-  REQUIRE_FUNCTION(ovrHmd_GetEyeTimewarpMatrices);
-  REQUIRE_FUNCTION(ovrMatrix4f_Projection);
-  REQUIRE_FUNCTION(ovrMatrix4f_OrthoSubProjection);
-  REQUIRE_FUNCTION(ovr_GetTimeInSeconds);
-
-#undef REQUIRE_FUNCTION
-
-  return true;
-
- fail:
-  ovr_Initialize = nullptr;
-  return false;
-}
-
-#else
-// we're statically linked; it's available
-static bool InitializeOculusCAPI()
-{
-  return true;
-}
-#endif
-
-} // anonymous namespace
-
-using namespace mozilla::gfx;
-
-// Dummy nsIScreen implementation, for when we just need to specify a size
-class FakeScreen : public nsIScreen
-{
-public:
-  explicit FakeScreen(const IntRect& aScreenRect)
-    : mScreenRect(aScreenRect)
-  { }
-
-  NS_DECL_ISUPPORTS
-
-  NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
-    *l = mScreenRect.x;
-    *t = mScreenRect.y;
-    *w = mScreenRect.width;
-    *h = mScreenRect.height;
-    return NS_OK;
-  }
-  NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
-    return GetRect(l, t, w, h);
-  }
-  NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
-    return GetRect(l, t, w, h);
-  }
-  NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
-    return GetAvailRect(l, t, w, h);
-  }
-
-  NS_IMETHOD GetId(uint32_t* aId) override { *aId = (uint32_t)-1; return NS_OK; }
-  NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override { *aPixelDepth = 24; return NS_OK; }
-  NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override { *aColorDepth = 24; return NS_OK; }
-
-  NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
-  NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
-  NS_IMETHOD GetRotation(uint32_t* aRotation) override {
-    *aRotation = nsIScreen::ROTATION_0_DEG;
-    return NS_OK;
-  }
-  NS_IMETHOD SetRotation(uint32_t aRotation) override { return NS_ERROR_NOT_AVAILABLE; }
-  NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) override {
-    *aContentsScaleFactor = 1.0;
-    return NS_OK;
-  }
-
-protected:
-  virtual ~FakeScreen() {}
-
-  IntRect mScreenRect;
-};
-
-NS_IMPL_ISUPPORTS(FakeScreen, nsIScreen)
-
-class HMDInfoOculus : public VRHMDInfo {
-  friend class VRHMDManagerOculusImpl;
-public:
-  explicit HMDInfoOculus(ovrHmd aHMD);
-
-  bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
-              double zNear, double zFar) override;
-
-  bool StartSensorTracking() override;
-  VRHMDSensorState GetSensorState(double timeOffset) override;
-  void StopSensorTracking() override;
-  void ZeroSensor() override;
-
-  void FillDistortionConstants(uint32_t whichEye,
-                               const IntSize& textureSize, const IntRect& eyeViewport,
-                               const Size& destViewport, const Rect& destRect,
-                               VRDistortionConstants& values) override;
-
-  void Destroy();
-
-protected:
-  virtual ~HMDInfoOculus() {
-      Destroy();
-      MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
-  }
-
-  ovrHmd mHMD;
-  ovrFovPort mFOVPort[2];
-  uint32_t mStartCount;
-};
-
-static ovrFovPort
-ToFovPort(const VRFieldOfView& aFOV)
-{
-  ovrFovPort fovPort;
-  fovPort.LeftTan = tan(aFOV.leftDegrees * M_PI / 180.0);
-  fovPort.RightTan = tan(aFOV.rightDegrees * M_PI / 180.0);
-  fovPort.UpTan = tan(aFOV.upDegrees * M_PI / 180.0);
-  fovPort.DownTan = tan(aFOV.downDegrees * M_PI / 180.0);
-  return fovPort;
-}
-
-static VRFieldOfView
-FromFovPort(const ovrFovPort& aFOV)
-{
-  VRFieldOfView fovInfo;
-  fovInfo.leftDegrees = atan(aFOV.LeftTan) * 180.0 / M_PI;
-  fovInfo.rightDegrees = atan(aFOV.RightTan) * 180.0 / M_PI;
-  fovInfo.upDegrees = atan(aFOV.UpTan) * 180.0 / M_PI;
-  fovInfo.downDegrees = atan(aFOV.DownTan) * 180.0 / M_PI;
-  return fovInfo;
-}
-
-HMDInfoOculus::HMDInfoOculus(ovrHmd aHMD)
-  : VRHMDInfo(VRHMDType::Oculus)
-  , mHMD(aHMD)
-  , mStartCount(0)
-{
-  MOZ_COUNT_CTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
-
-  mSupportedSensorBits = 0;
-  if (mHMD->TrackingCaps & ovrTrackingCap_Orientation)
-    mSupportedSensorBits |= State_Orientation;
-  if (mHMD->TrackingCaps & ovrTrackingCap_Position)
-    mSupportedSensorBits |= State_Position;
-
-  mRecommendedEyeFOV[Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]);
-  mRecommendedEyeFOV[Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]);
-
-  mMaximumEyeFOV[Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]);
-  mMaximumEyeFOV[Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]);
-
-  SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0);
-
-  nsCOMPtr<nsIScreenManager> screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
-  if (screenmgr) {
-    screenmgr->ScreenForRect(mHMD->WindowsPos.x, mHMD->WindowsPos.y,
-                             mHMD->Resolution.w, mHMD->Resolution.h,
-                             getter_AddRefs(mScreen));
-  }
-}
-
-void
-HMDInfoOculus::Destroy()
-{
-  if (mHMD) {
-    ovrHmd_Destroy(mHMD);
-    mHMD = nullptr;
-  }
-}
-
-bool
-HMDInfoOculus::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
-                      double zNear, double zFar)
-{
-  float pixelsPerDisplayPixel = 1.0;
-  ovrSizei texSize[2];
-
-  uint32_t caps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette; // XXX TODO add TimeWarp
-
-  // get eye parameters and create the mesh
-  for (uint32_t eye = 0; eye < NumEyes; eye++) {
-    mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight;
-    mFOVPort[eye] = ToFovPort(mEyeFOV[eye]);
-
-    ovrEyeRenderDesc renderDesc = ovrHmd_GetRenderDesc(mHMD, (ovrEyeType) eye, mFOVPort[eye]);
-
-    // these values are negated so that content can add the adjustment to its camera position,
-    // instead of subtracting
-    mEyeTranslation[eye] = Point3D(-renderDesc.ViewAdjust.x, -renderDesc.ViewAdjust.y, -renderDesc.ViewAdjust.z);
-
-    // note that we are using a right-handed coordinate system here, to match CSS
-    ovrMatrix4f projMatrix = ovrMatrix4f_Projection(mFOVPort[eye], zNear, zFar, true);
-
-    // XXX this is gross, we really need better methods on Matrix4x4
-    memcpy(&mEyeProjectionMatrix[eye], projMatrix.M, sizeof(ovrMatrix4f));
-    mEyeProjectionMatrix[eye].Transpose();
-
-    texSize[eye] = ovrHmd_GetFovTextureSize(mHMD, (ovrEyeType) eye, mFOVPort[eye], pixelsPerDisplayPixel);
-
-    ovrDistortionMesh mesh;
-    bool ok = ovrHmd_CreateDistortionMesh(mHMD, (ovrEyeType) eye, mFOVPort[eye], caps, &mesh);
-    if (!ok)
-      return false;
-
-    mDistortionMesh[eye].mVertices.SetLength(mesh.VertexCount);
-    mDistortionMesh[eye].mIndices.SetLength(mesh.IndexCount);
-
-    ovrDistortionVertex *srcv = mesh.pVertexData;
-    VRDistortionVertex *destv = mDistortionMesh[eye].mVertices.Elements();
-    memset(destv, 0, mesh.VertexCount * sizeof(VRDistortionVertex));
-    for (uint32_t i = 0; i < mesh.VertexCount; ++i) {
-      destv[i].pos[0] = srcv[i].ScreenPosNDC.x;
-      destv[i].pos[1] = srcv[i].ScreenPosNDC.y;
-
-      destv[i].texR[0] = srcv[i].TanEyeAnglesR.x;
-      destv[i].texR[1] = srcv[i].TanEyeAnglesR.y;
-      destv[i].texG[0] = srcv[i].TanEyeAnglesG.x;
-      destv[i].texG[1] = srcv[i].TanEyeAnglesG.y;
-      destv[i].texB[0] = srcv[i].TanEyeAnglesB.x;
-      destv[i].texB[1] = srcv[i].TanEyeAnglesB.y;
-
-      destv[i].genericAttribs[0] = srcv[i].VignetteFactor;
-      destv[i].genericAttribs[1] = srcv[i].TimeWarpFactor;
-    }
-
-    memcpy(mDistortionMesh[eye].mIndices.Elements(), mesh.pIndexData, mesh.IndexCount * sizeof(uint16_t));
-    ovrHmd_DestroyDistortionMesh(&mesh);
-  }
-
-  // take the max of both for eye resolution
-  mEyeResolution.width = std::max(texSize[Eye_Left].w, texSize[Eye_Right].w);
-  mEyeResolution.height = std::max(texSize[Eye_Left].h, texSize[Eye_Right].h);
-
-  mConfiguration.hmdType = mType;
-  mConfiguration.value = 0;
-  mConfiguration.fov[0] = aFOVLeft;
-  mConfiguration.fov[1] = aFOVRight;
-
-  return true;
-  //* need to call this during rendering each frame I think? */
-  //ovrHmd_GetRenderScaleAndOffset(fovPort, texSize, renderViewport, uvScaleOffsetOut);
-}
-
-void
-HMDInfoOculus::FillDistortionConstants(uint32_t whichEye,
-                                       const IntSize& textureSize,
-                                       const IntRect& eyeViewport,
-                                       const Size& destViewport,
-                                       const Rect& destRect,
-                                       VRDistortionConstants& values)
-{
-  ovrSizei texSize = { textureSize.width, textureSize.height };
-  ovrRecti eyePort = { { eyeViewport.x, eyeViewport.y }, { eyeViewport.width, eyeViewport.height } };
-  ovrVector2f scaleOut[2];
-
-  ovrHmd_GetRenderScaleAndOffset(mFOVPort[whichEye], texSize, eyePort, scaleOut);
-
-  values.eyeToSourceScaleAndOffset[0] = scaleOut[0].x;
-  values.eyeToSourceScaleAndOffset[1] = scaleOut[0].y;
-  values.eyeToSourceScaleAndOffset[2] = scaleOut[1].x;
-  values.eyeToSourceScaleAndOffset[3] = scaleOut[1].y;
-
-  // These values are in clip space [-1..1] range, but we're providing
-  // scaling in the 0..2 space for sanity.
-
-  // this is the destRect in clip space
-  float x0 = destRect.x / destViewport.width * 2.0 - 1.0;
-  float x1 = (destRect.x + destRect.width) / destViewport.width * 2.0 - 1.0;
-
-  float y0 = destRect.y / destViewport.height * 2.0 - 1.0;
-  float y1 = (destRect.y + destRect.height) / destViewport.height * 2.0 - 1.0;
-
-  // offset
-  values.destinationScaleAndOffset[0] = (x0+x1) / 2.0;
-  values.destinationScaleAndOffset[1] = (y0+y1) / 2.0;
-  // scale
-  values.destinationScaleAndOffset[2] = destRect.width / destViewport.width;
-  values.destinationScaleAndOffset[3] = destRect.height / destViewport.height;
-}
-
-bool
-HMDInfoOculus::StartSensorTracking()
-{
-  if (mStartCount == 0) {
-    bool ok = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0);
-    if (!ok)
-      return false;
-  }
-
-  mStartCount++;
-  return true;
-}
-
-void
-HMDInfoOculus::StopSensorTracking()
-{
-  if (--mStartCount == 0) {
-    ovrHmd_ConfigureTracking(mHMD, 0, 0);
-  }
-}
-
-void
-HMDInfoOculus::ZeroSensor()
-{
-  ovrHmd_RecenterPose(mHMD);
-}
-
-VRHMDSensorState
-HMDInfoOculus::GetSensorState(double timeOffset)
-{
-  VRHMDSensorState result;
-  result.Clear();
-
-  // XXX this is the wrong time base for timeOffset; we need to figure out how to synchronize
-  // the Oculus time base and the browser one.
-  ovrTrackingState state = ovrHmd_GetTrackingState(mHMD, ovr_GetTimeInSeconds() + timeOffset);
-  ovrPoseStatef& pose(state.HeadPose);
-
-  result.timestamp = pose.TimeInSeconds;
-
-  if (state.StatusFlags & ovrStatus_OrientationTracked) {
-    result.flags |= State_Orientation;
-
-    result.orientation[0] = pose.ThePose.Orientation.x;
-    result.orientation[1] = pose.ThePose.Orientation.y;
-    result.orientation[2] = pose.ThePose.Orientation.z;
-    result.orientation[3] = pose.ThePose.Orientation.w;
-    
-    result.angularVelocity[0] = pose.AngularVelocity.x;
-    result.angularVelocity[1] = pose.AngularVelocity.y;
-    result.angularVelocity[2] = pose.AngularVelocity.z;
-
-    result.angularAcceleration[0] = pose.AngularAcceleration.x;
-    result.angularAcceleration[1] = pose.AngularAcceleration.y;
-    result.angularAcceleration[2] = pose.AngularAcceleration.z;
-  }
-
-  if (state.StatusFlags & ovrStatus_PositionTracked) {
-    result.flags |= State_Position;
-
-    result.position[0] = pose.ThePose.Position.x;
-    result.position[1] = pose.ThePose.Position.y;
-    result.position[2] = pose.ThePose.Position.z;
-    
-    result.linearVelocity[0] = pose.LinearVelocity.x;
-    result.linearVelocity[1] = pose.LinearVelocity.y;
-    result.linearVelocity[2] = pose.LinearVelocity.z;
-
-    result.linearAcceleration[0] = pose.LinearAcceleration.x;
-    result.linearAcceleration[1] = pose.LinearAcceleration.y;
-    result.linearAcceleration[2] = pose.LinearAcceleration.z;
-  }
-
-  return result;
-}
-
-namespace mozilla {
-namespace gfx {
-
-class VRHMDManagerOculusImpl {
-public:
-  VRHMDManagerOculusImpl() : mOculusInitialized(false), mOculusPlatformInitialized(false)
-  { }
-
-  bool PlatformInit();
-  bool Init();
-  void Destroy();
-  void GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo> >& aHMDResult);
-protected:
-  nsTArray<nsRefPtr<HMDInfoOculus>> mOculusHMDs;
-  bool mOculusInitialized;
-  bool mOculusPlatformInitialized;
-};
-
-} // namespace gfx
-} // namespace mozilla
-
-VRHMDManagerOculusImpl *VRHMDManagerOculus::mImpl = nullptr;
-
-// These just forward to the Impl class, to have a non-static container for various
-// objects.
-
-bool
-VRHMDManagerOculus::PlatformInit()
-{
-  if (!mImpl) {
-    mImpl = new VRHMDManagerOculusImpl;
-  }
-  return mImpl->PlatformInit();
-}
-
-bool
-VRHMDManagerOculus::Init()
-{
-  if (!mImpl) {
-    mImpl = new VRHMDManagerOculusImpl;
-  }
-  return mImpl->Init();
-}
-
-void
-VRHMDManagerOculus::GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult)
-{
-  if (!mImpl) {
-    mImpl = new VRHMDManagerOculusImpl;
-  }
-  mImpl->GetOculusHMDs(aHMDResult);
-}
-
-void
-VRHMDManagerOculus::Destroy()
-{
-  if (!mImpl)
-    return;
-  mImpl->Destroy();
-  delete mImpl;
-  mImpl = nullptr;
-}
-
-bool
-VRHMDManagerOculusImpl::PlatformInit()
-{
-  if (mOculusPlatformInitialized)
-    return true;
-
-  if (!gfxPrefs::VREnabled())
-    return false;
-
-  if (!InitializeOculusCAPI())
-    return false;
-
-  bool ok = ovr_Initialize();
-
-  if (!ok)
-    return false;
-
-  mOculusPlatformInitialized = true;
-  return true;
-}
-
-bool
-VRHMDManagerOculusImpl::Init()
-{
-  if (mOculusInitialized)
-    return true;
-
-  if (!PlatformInit())
-    return false;
-
-  int count = ovrHmd_Detect();
-
-  for (int i = 0; i < count; ++i) {
-    ovrHmd hmd = ovrHmd_Create(i);
-    if (!hmd)
-      continue;
-    nsRefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
-    mOculusHMDs.AppendElement(oc);
-  }
-
-  // VRAddTestDevices == 1: add test device only if no real devices present
-  // VRAddTestDevices == 2: add test device always
-  if ((count == 0 && gfxPrefs::VRAddTestDevices() == 1) ||
-      (gfxPrefs::VRAddTestDevices() == 2))
-  {
-    ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
-    if (hmd) {
-      nsRefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
-      mOculusHMDs.AppendElement(oc);
-    }
-  }
-
-  mOculusInitialized = true;
-  return true;
-}
-
-void
-VRHMDManagerOculusImpl::Destroy()
-{
-  if (!mOculusInitialized)
-    return;
-
-  for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
-    mOculusHMDs[i]->Destroy();
-  }
-
-  mOculusHMDs.Clear();
-
-  ovr_Shutdown();
-  mOculusInitialized = false;
-}
-
-void
-VRHMDManagerOculusImpl::GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult)
-{
-  Init();
-  for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
-    aHMDResult.AppendElement(mOculusHMDs[i]);
-  }
-}
deleted file mode 100644
--- a/gfx/thebes/gfxVR.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * 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/. */
-
-#ifndef GFX_VR_H
-#define GFX_VR_H
-
-#include "nsTArray.h"
-#include "nsIScreen.h"
-#include "nsCOMPtr.h"
-#include "nsRefPtr.h"
-
-#include "mozilla/gfx/2D.h"
-#include "mozilla/EnumeratedArray.h"
-
-namespace mozilla {
-namespace gfx {
-
-enum class VRHMDType : uint16_t {
-  Oculus,
-  NumHMDTypes
-};
-
-struct VRFieldOfView {
-  static VRFieldOfView FromCSSPerspectiveInfo(double aPerspectiveDistance,
-                                              const Point& aPerspectiveOrigin,
-                                              const Point& aTransformOrigin,
-                                              const Rect& aContentRectangle)
-  {
-    /**/
-    return VRFieldOfView();
-  }
-
-  VRFieldOfView() {}
-  VRFieldOfView(double up, double right, double down, double left)
-    : upDegrees(up), rightDegrees(right), downDegrees(down), leftDegrees(left)
-  {}
-
-  bool operator==(const VRFieldOfView& other) const {
-    return other.upDegrees == upDegrees &&
-           other.downDegrees == downDegrees &&
-           other.rightDegrees == rightDegrees &&
-           other.leftDegrees == leftDegrees;
-  }
-
-  bool operator!=(const VRFieldOfView& other) const {
-    return !(*this == other);
-  }
-
-  bool IsZero() const {
-    return upDegrees == 0.0 ||
-      rightDegrees == 0.0 ||
-      downDegrees == 0.0 ||
-      leftDegrees == 0.0;
-  }
-
-  double upDegrees;
-  double rightDegrees;
-  double downDegrees;
-  double leftDegrees;
-};
-
-// 12 floats per vertex. Position, tex coordinates
-// for each channel, and 4 generic attributes
-struct VRDistortionConstants {
-  float eyeToSourceScaleAndOffset[4];
-  float destinationScaleAndOffset[4];
-};
-
-struct VRDistortionVertex {
-  float pos[2];
-  float texR[2];
-  float texG[2];
-  float texB[2];
-  float genericAttribs[4];
-};
-
-struct VRDistortionMesh {
-  nsTArray<VRDistortionVertex> mVertices;
-  nsTArray<uint16_t> mIndices;
-};
-
-struct VRHMDSensorState {
-  double timestamp;
-  uint32_t flags;
-  float orientation[4];
-  float position[3];
-  float angularVelocity[3];
-  float angularAcceleration[3];
-  float linearVelocity[3];
-  float linearAcceleration[3];
-
-  void Clear() {
-    memset(this, 0, sizeof(VRHMDSensorState));
-  }
-};
-
-/* A pure data struct that can be used to see if
- * the configuration of one HMDInfo matches another; for rendering purposes,
- * really asking "can the rendering details of this one be used for the other"
- */
-struct VRHMDConfiguration {
-  VRHMDConfiguration() : hmdType(VRHMDType::NumHMDTypes) {}
-
-  bool operator==(const VRHMDConfiguration& other) const {
-    return hmdType == other.hmdType &&
-      value == other.value &&
-      fov[0] == other.fov[0] &&
-      fov[1] == other.fov[1];
-  }
-
-  bool operator!=(const VRHMDConfiguration& other) const {
-    return hmdType != other.hmdType ||
-      value != other.value ||
-      fov[0] != other.fov[0] ||
-      fov[1] != other.fov[1];
-  }
-
-  bool IsValid() const {
-    return hmdType != VRHMDType::NumHMDTypes;
-  }
-
-  VRHMDType hmdType;
-  uint32_t value;
-  VRFieldOfView fov[2];
-};
-
-class VRHMDInfo {
-public:
-  enum Eye {
-    Eye_Left,
-    Eye_Right,
-    NumEyes
-  };
-
-  enum StateValidFlags {
-    State_Position = 1 << 1,
-    State_Orientation = 1 << 2
-  };
-
-public:
-  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRHMDInfo)
-
-  VRHMDType GetType() const { return mType; }
-
-  virtual const VRFieldOfView& GetRecommendedEyeFOV(uint32_t whichEye) { return mRecommendedEyeFOV[whichEye]; }
-  virtual const VRFieldOfView& GetMaximumEyeFOV(uint32_t whichEye) { return mMaximumEyeFOV[whichEye]; }
-
-  const VRHMDConfiguration& GetConfiguration() const { return mConfiguration; }
-
-  /* set the FOV for this HMD unit; this triggers a computation of all the remaining bits.  Returns false if it fails */
-  virtual bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
-                      double zNear, double zFar) = 0;
-  const VRFieldOfView& GetEyeFOV(uint32_t whichEye)  { return mEyeFOV[whichEye]; }
-
-  /* Suggested resolution for rendering a single eye.
-   * Assumption is that left/right rendering will be 2x of this size.
-   * XXX fix this for vertical displays
-   */
-  const IntSize& SuggestedEyeResolution() const { return mEyeResolution; }
-  const Point3D& GetEyeTranslation(uint32_t whichEye) const { return mEyeTranslation[whichEye]; }
-  const Matrix4x4& GetEyeProjectionMatrix(uint32_t whichEye) const { return mEyeProjectionMatrix[whichEye]; }
-
-  virtual uint32_t GetSupportedSensorStateBits() { return mSupportedSensorBits; }
-  virtual bool StartSensorTracking() = 0;
-  virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0) = 0;
-  virtual void StopSensorTracking() = 0;
-
-  virtual void ZeroSensor() = 0;
-
-  virtual void FillDistortionConstants(uint32_t whichEye,
-                                       const IntSize& textureSize, // the full size of the texture
-                                       const IntRect& eyeViewport, // the viewport within the texture for the current eye
-                                       const Size& destViewport,   // the size of the destination viewport
-                                       const Rect& destRect,       // the rectangle within the dest viewport that this should be rendered
-                                       VRDistortionConstants& values) = 0;
-
-  virtual const VRDistortionMesh& GetDistortionMesh(uint32_t whichEye) const { return mDistortionMesh[whichEye]; }
-
-  // The nsIScreen that represents this device
-  virtual nsIScreen* GetScreen() { return mScreen; }
-
-protected:
-  explicit VRHMDInfo(VRHMDType aType) : mType(aType) { MOZ_COUNT_CTOR(VRHMDInfo); }
-  virtual ~VRHMDInfo() { MOZ_COUNT_DTOR(VRHMDInfo); }
-
-  VRHMDType mType;
-  VRHMDConfiguration mConfiguration;
-
-  VRFieldOfView mEyeFOV[NumEyes];
-  IntSize mEyeResolution;
-  Point3D mEyeTranslation[NumEyes];
-  Matrix4x4 mEyeProjectionMatrix[NumEyes];
-  VRDistortionMesh mDistortionMesh[NumEyes];
-  uint32_t mSupportedSensorBits;
-
-  VRFieldOfView mRecommendedEyeFOV[NumEyes];
-  VRFieldOfView mMaximumEyeFOV[NumEyes];
-
-  nsCOMPtr<nsIScreen> mScreen;
-};
-
-class VRHMDManagerOculusImpl;
-class VRHMDManagerOculus {
-  static VRHMDManagerOculusImpl *mImpl;
-public:
-  static bool PlatformInit();
-  static bool Init();
-  static void Destroy();
-  static void GetOculusHMDs(nsTArray<nsRefPtr<VRHMDInfo> >& aHMDResult);
-};
-
-} // namespace gfx
-} // namespace mozilla
-
-#endif /* GFX_VR_H */
--- a/gfx/thebes/gfxWindowsPlatform.cpp
+++ b/gfx/thebes/gfxWindowsPlatform.cpp
@@ -1870,17 +1870,16 @@ gfxWindowsPlatform::InitD3D11Devices()
   // to fallback to D3D9 or Basic layers. If WARP is not disabled it will use
   // a WARP device which should always be available on Windows 7 and higher.
 
   mD3D11DeviceInitialized = true;
 
   MOZ_ASSERT(!mD3D11Device);
 
   bool useWARP = false;
-  ScopedGfxFeatureReporter reporterWARP("D3D11-WARP", gfxPrefs::LayersD3D11ForceWARP());
 
   nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
   if (gfxInfo) {
     int32_t status;
     if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_DIRECT3D_11_LAYERS, &status))) {
       if (status != nsIGfxInfo::FEATURE_STATUS_OK) {
 
         if (gfxPrefs::LayersD3D11DisableWARP()) {
@@ -1957,16 +1956,17 @@ gfxWindowsPlatform::InitD3D11Devices()
     }
   }
 
   if (useWARP) {
     MOZ_ASSERT(!gfxPrefs::LayersD3D11DisableWARP());
     MOZ_ASSERT(!mD3D11Device);
     MOZ_ASSERT(!adapter);
 
+    ScopedGfxFeatureReporter reporterWARP("D3D11-WARP", gfxPrefs::LayersD3D11ForceWARP());
     hr = d3d11CreateDevice(nullptr, D3D_DRIVER_TYPE_WARP, nullptr,
                            // Use
                            // D3D11_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
                            // to prevent bug 1092260. IE 11 also uses this flag.
                            D3D11_CREATE_DEVICE_BGRA_SUPPORT,
                            featureLevels.Elements(), featureLevels.Length(),
                            D3D11_SDK_VERSION, byRef(mD3D11Device), nullptr, nullptr);
 
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -44,17 +44,16 @@ EXPORTS += [
     'gfxSharedQuartzSurface.h',
     'gfxSkipChars.h',
     'gfxSVGGlyphs.h',
     'gfxTeeSurface.h',
     'gfxTextRun.h',
     'gfxTypes.h',
     'gfxUserFontSet.h',
     'gfxUtils.h',
-    'gfxVR.h',
     'GraphicsFilter.h',
     'RoundedRect.h',
     'SoftwareVsyncSource.h',
     'VsyncSource.h',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     EXPORTS += [
@@ -239,17 +238,16 @@ UNIFIED_SOURCES += [
     'gfxReusableSharedImageSurfaceWrapper.cpp',
     'gfxScriptItemizer.cpp',
     'gfxSkipChars.cpp',
     'gfxSVGGlyphs.cpp',
     'gfxTeeSurface.cpp',
     'gfxTextRun.cpp',
     'gfxUserFontSet.cpp',
     'gfxUtils.cpp',
-    'gfxVR.cpp',
     'nsUnicodeRange.cpp',
     'SoftwareVsyncSource.cpp',
     'VsyncSource.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     UNIFIED_SOURCES += [
         'gfxMacPlatformFontList.mm',
deleted file mode 100644
--- a/gfx/thebes/ovr_capi_dynamic.h
+++ /dev/null
@@ -1,228 +0,0 @@
-/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
-/* 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/. */
-
-/* This file contains just the needed struct definitions for
- * interacting with the Oculus VR C API, without needing to #include
- * OVR_CAPI.h directly.  Note that it uses the same type names as the
- * CAPI, and cannot be #included at the same time as OVR_CAPI.h.  It
- * does not include the entire C API, just want's needed.
- */
-
-#ifdef OVR_CAPI_h
-#warning OVR_CAPI.h included before ovr_capi_dynamic.h, skpping this
-#define mozilla_ovr_capi_dynamic_h_
-#endif
-
-#ifndef mozilla_ovr_capi_dynamic_h_
-#define mozilla_ovr_capi_dynamic_h_
-
-#define OVR_CAPI_LIMITED_MOZILLA 1
-
-#ifdef __cplusplus 
-extern "C" {
-#endif
-
-typedef char ovrBool;
-typedef struct { int x, y; } ovrVector2i;
-typedef struct { int w, h; } ovrSizei;
-typedef struct { ovrVector2i Pos; ovrSizei Size; } ovrRecti;
-typedef struct { float x, y, z, w; } ovrQuatf;
-typedef struct { float x, y; } ovrVector2f;
-typedef struct { float x, y, z; } ovrVector3f;
-typedef struct { float M[4][4]; } ovrMatrix4f;
-
-typedef struct {
-  ovrQuatf Orientation;
-  ovrVector3f Position;
-} ovrPosef;
-
-typedef struct {
-  ovrPosef ThePose;
-  ovrVector3f AngularVelocity;
-  ovrVector3f LinearVelocity;
-  ovrVector3f AngularAcceleration;
-  ovrVector3f LinearAcceleration;
-  double TimeInSeconds;
-} ovrPoseStatef;
-
-typedef struct {
-  float UpTan;
-  float DownTan;
-  float LeftTan;
-  float RightTan;
-} ovrFovPort;
-
-typedef enum {
-  ovrHmd_None             = 0,    
-  ovrHmd_DK1              = 3,
-  ovrHmd_DKHD             = 4,
-  ovrHmd_DK2              = 6,
-  ovrHmd_Other
-} ovrHmdType;
-
-typedef enum {
-  ovrHmdCap_Present           = 0x0001,
-  ovrHmdCap_Available         = 0x0002,
-  ovrHmdCap_Captured          = 0x0004,
-  ovrHmdCap_ExtendDesktop     = 0x0008,
-  ovrHmdCap_DisplayOff        = 0x0040,
-  ovrHmdCap_LowPersistence    = 0x0080,
-  ovrHmdCap_DynamicPrediction = 0x0200,
-  ovrHmdCap_NoVSync           = 0x1000,
-  ovrHmdCap_NoMirrorToWindow  = 0x2000
-} ovrHmdCapBits;
-
-typedef enum
-{
-  ovrTrackingCap_Orientation      = 0x0010,
-  ovrTrackingCap_MagYawCorrection = 0x0020,
-  ovrTrackingCap_Position         = 0x0040,
-  ovrTrackingCap_Idle             = 0x0100
-} ovrTrackingCaps;
-
-typedef enum {
-  ovrDistortionCap_Chromatic = 0x01,
-  ovrDistortionCap_TimeWarp  = 0x02,
-  ovrDistortionCap_Vignette  = 0x08,
-  ovrDistortionCap_NoRestore = 0x10,
-  ovrDistortionCap_FlipInput = 0x20,
-  ovrDistortionCap_SRGB      = 0x40,
-  ovrDistortionCap_Overdrive = 0x80,
-  ovrDistortionCap_ProfileNoTimewarpSpinWaits = 0x10000
-} ovrDistortionCaps;
-
-typedef enum {
-  ovrEye_Left  = 0,
-  ovrEye_Right = 1,
-  ovrEye_Count = 2
-} ovrEyeType;
-
-typedef struct ovrHmdDesc_ {
-  void* Handle;
-  ovrHmdType  Type;
-  const char* ProductName;    
-  const char* Manufacturer;
-  short VendorId;
-  short ProductId;
-  char SerialNumber[24];
-  short FirmwareMajor;
-  short FirmwareMinor;
-  float CameraFrustumHFovInRadians;
-  float CameraFrustumVFovInRadians;
-  float CameraFrustumNearZInMeters;
-  float CameraFrustumFarZInMeters;
-
-  unsigned int HmdCaps;
-  unsigned int TrackingCaps;
-  unsigned int DistortionCaps;
-
-  ovrFovPort  DefaultEyeFov[ovrEye_Count];
-  ovrFovPort  MaxEyeFov[ovrEye_Count];
-  ovrEyeType  EyeRenderOrder[ovrEye_Count];
-
-  ovrSizei    Resolution;
-  ovrVector2i WindowsPos;
-
-  const char* DisplayDeviceName;
-  int         DisplayId;
-} ovrHmdDesc;
-
-typedef const ovrHmdDesc* ovrHmd;
-
-typedef enum {
-  ovrStatus_OrientationTracked    = 0x0001,
-  ovrStatus_PositionTracked       = 0x0002,
-  ovrStatus_CameraPoseTracked     = 0x0004,
-  ovrStatus_PositionConnected     = 0x0020,
-  ovrStatus_HmdConnected          = 0x0080
-} ovrStatusBits;
-
-typedef struct ovrSensorData_ {
-  ovrVector3f    Accelerometer;
-  ovrVector3f    Gyro;
-  ovrVector3f    Magnetometer;
-  float          Temperature;
-  float          TimeInSeconds;
-} ovrSensorData;
-
-
-typedef struct ovrTrackingState_ {
-  ovrPoseStatef HeadPose;
-  ovrPosef CameraPose;
-  ovrPosef LeveledCameraPose;
-  ovrSensorData RawSensorData;
-  unsigned int StatusFlags;
-  double LastVisionProcessingTime;
-  double LastVisionFrameLatency;
-  uint32_t LastCameraFrameCounter;
-} ovrTrackingState;
-
-typedef struct ovrFrameTiming_ {
-  float DeltaSeconds;
-  double ThisFrameSeconds;
-  double TimewarpPointSeconds;
-  double NextFrameSeconds;
-  double ScanoutMidpointSeconds;
-  double EyeScanoutSeconds[2];    
-} ovrFrameTiming;
-
-typedef struct ovrEyeRenderDesc_ {
-  ovrEyeType  Eye;        
-  ovrFovPort  Fov;
-  ovrRecti DistortedViewport;
-  ovrVector2f PixelsPerTanAngleAtCenter;
-  ovrVector3f ViewAdjust;
-} ovrEyeRenderDesc;
-
-typedef struct ovrDistortionVertex_ {
-  ovrVector2f ScreenPosNDC;
-  float       TimeWarpFactor;
-  float       VignetteFactor;
-  ovrVector2f TanEyeAnglesR;
-  ovrVector2f TanEyeAnglesG;
-  ovrVector2f TanEyeAnglesB;    
-} ovrDistortionVertex;
-
-typedef struct ovrDistortionMesh_ {
-  ovrDistortionVertex* pVertexData;
-  unsigned short*      pIndexData;
-  unsigned int         VertexCount;
-  unsigned int         IndexCount;
-} ovrDistortionMesh;
-
-typedef ovrBool (*pfn_ovr_Initialize)();
-typedef void (*pfn_ovr_Shutdown)();
-typedef int (*pfn_ovrHmd_Detect)();
-typedef ovrHmd (*pfn_ovrHmd_Create)(int index);
-typedef void (*pfn_ovrHmd_Destroy)(ovrHmd hmd);
-typedef ovrHmd (*pfn_ovrHmd_CreateDebug)(ovrHmdType type);
-typedef const char* (*pfn_ovrHmd_GetLastError)(ovrHmd hmd);
-typedef ovrBool (*pfn_ovrHmd_AttachToWindow)(ovrHmd hmd, void* window, const ovrRecti* destMirrorRect, const ovrRecti* sourceRenderTargetRect);
-typedef unsigned int (*pfn_ovrHmd_GetEnabledCaps)(ovrHmd hmd);
-typedef void (*pfn_ovrHmd_SetEnabledCaps)(ovrHmd hmd, unsigned int hmdCaps);
-typedef ovrBool (*pfn_ovrHmd_ConfigureTracking)(ovrHmd hmd, unsigned int supportedTrackingCaps, unsigned int requiredTrackingCaps); 
-typedef void (*pfn_ovrHmd_RecenterPose)(ovrHmd hmd);
-typedef ovrTrackingState (*pfn_ovrHmd_GetTrackingState)(ovrHmd hmd, double absTime);
-typedef ovrSizei (*pfn_ovrHmd_GetFovTextureSize)(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov, float pixelsPerDisplayPixel);
-typedef ovrEyeRenderDesc (*pfn_ovrHmd_GetRenderDesc)(ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov);
-typedef ovrBool (*pfn_ovrHmd_CreateDistortionMesh)(ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov, unsigned int distortionCaps, ovrDistortionMesh *meshData);
-typedef void (*pfn_ovrHmd_DestroyDistortionMesh)(ovrDistortionMesh* meshData);
-typedef void (*pfn_ovrHmd_GetRenderScaleAndOffset)(ovrFovPort fov, ovrSizei textureSize, ovrRecti renderViewport, ovrVector2f uvScaleOffsetOut[2]);
-typedef ovrFrameTiming (*pfn_ovrHmd_GetFrameTiming)(ovrHmd hmd, unsigned int frameIndex);
-typedef ovrFrameTiming (*pfn_ovrHmd_BeginFrameTiming)(ovrHmd hmd, unsigned int frameIndex);
-typedef void (*pfn_ovrHmd_EndFrameTiming)(ovrHmd hmd);
-typedef void (*pfn_ovrHmd_ResetFrameTiming)(ovrHmd hmd, unsigned int frameIndex, bool vsync);
-typedef void (*pfn_ovrHmd_GetEyePoses)(ovrHmd hmd, unsigned int frameIndex, ovrVector3f hmdToEyeViewOffset[2], ovrPosef outEyePoses[2], ovrTrackingState* outHmdTrackingState);
-typedef ovrPosef (*pfn_ovrHmd_GetHmdPosePerEye)(ovrHmd hmd, ovrEyeType eye);
-typedef void (*pfn_ovrHmd_GetEyeTimewarpMatrices)(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2]);
-typedef ovrMatrix4f (*pfn_ovrMatrix4f_Projection) (ovrFovPort fov, float znear, float zfar, ovrBool rightHanded );
-typedef ovrMatrix4f (*pfn_ovrMatrix4f_OrthoSubProjection) (ovrFovPort fov, ovrVector2f orthoScale, float orthoDistance, float eyeViewAdjustX);
-typedef double (*pfn_ovr_GetTimeInSeconds)();
-
-#ifdef __cplusplus 
-}
-#endif
-
-#endif /* mozilla_ovr_capi_dynamic_h_ */
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVR.cpp
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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 <math.h>
+
+#include "prlink.h"
+#include "prmem.h"
+#include "prenv.h"
+#include "nsString.h"
+
+#include "gfxPrefs.h"
+#include "gfxVR.h"
+#include "gfxVROculus.h"
+#include "gfxVRCardboard.h"
+
+#include "nsServiceManagerUtils.h"
+#include "nsIScreenManager.h"
+
+using namespace mozilla::gfx;
+
+// Dummy nsIScreen implementation, for when we just need to specify a size
+class FakeScreen : public nsIScreen
+{
+public:
+  explicit FakeScreen(const IntRect& aScreenRect)
+    : mScreenRect(aScreenRect)
+  { }
+
+  NS_DECL_ISUPPORTS
+
+  NS_IMETHOD GetRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
+    *l = mScreenRect.x;
+    *t = mScreenRect.y;
+    *w = mScreenRect.width;
+    *h = mScreenRect.height;
+    return NS_OK;
+  }
+  NS_IMETHOD GetAvailRect(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
+    return GetRect(l, t, w, h);
+  }
+  NS_IMETHOD GetRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
+    return GetRect(l, t, w, h);
+  }
+  NS_IMETHOD GetAvailRectDisplayPix(int32_t *l, int32_t *t, int32_t *w, int32_t *h) override {
+    return GetAvailRect(l, t, w, h);
+  }
+
+  NS_IMETHOD GetId(uint32_t* aId) override { *aId = (uint32_t)-1; return NS_OK; }
+  NS_IMETHOD GetPixelDepth(int32_t* aPixelDepth) override { *aPixelDepth = 24; return NS_OK; }
+  NS_IMETHOD GetColorDepth(int32_t* aColorDepth) override { *aColorDepth = 24; return NS_OK; }
+
+  NS_IMETHOD LockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
+  NS_IMETHOD UnlockMinimumBrightness(uint32_t aBrightness) override { return NS_ERROR_NOT_AVAILABLE; }
+  NS_IMETHOD GetRotation(uint32_t* aRotation) override {
+    *aRotation = nsIScreen::ROTATION_0_DEG;
+    return NS_OK;
+  }
+  NS_IMETHOD SetRotation(uint32_t aRotation) override { return NS_ERROR_NOT_AVAILABLE; }
+  NS_IMETHOD GetContentsScaleFactor(double* aContentsScaleFactor) override {
+    *aContentsScaleFactor = 1.0;
+    return NS_OK;
+  }
+
+protected:
+  virtual ~FakeScreen() {}
+
+  IntRect mScreenRect;
+};
+
+NS_IMPL_ISUPPORTS(FakeScreen, nsIScreen)
+
+VRHMDManager::VRHMDManagerArray *VRHMDManager::sManagers = nullptr;
+
+/* static */ void
+VRHMDManager::ManagerInit()
+{
+  if (sManagers)
+    return;
+
+  sManagers = new VRHMDManagerArray();
+
+  nsRefPtr<VRHMDManager> mgr;
+
+  mgr = new VRHMDManagerOculus();
+  if (mgr->PlatformInit())
+    sManagers->AppendElement(mgr);
+
+  mgr = new VRHMDManagerCardboard();
+  if (mgr->PlatformInit())
+    sManagers->AppendElement(mgr);
+}
+
+/* static */ void
+VRHMDManager::ManagerDestroy()
+{
+  if (!sManagers)
+    return;
+
+  for (uint32_t i = 0; i < sManagers->Length(); ++i) {
+    (*sManagers)[i]->Destroy();
+  }
+
+  delete sManagers;
+  sManagers = nullptr;
+}
+
+/* static */ void
+VRHMDManager::GetAllHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult)
+{
+  if (!sManagers)
+    return;
+
+  for (uint32_t i = 0; i < sManagers->Length(); ++i) {
+    (*sManagers)[i]->GetHMDs(aHMDResult);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVR.h
@@ -0,0 +1,227 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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/. */
+
+#ifndef GFX_VR_H
+#define GFX_VR_H
+
+#include "nsTArray.h"
+#include "nsIScreen.h"
+#include "nsCOMPtr.h"
+#include "nsRefPtr.h"
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/EnumeratedArray.h"
+
+namespace mozilla {
+namespace gfx {
+
+enum class VRHMDType : uint16_t {
+  Oculus,
+  Cardboard,
+  NumHMDTypes
+};
+
+struct VRFieldOfView {
+  static VRFieldOfView FromCSSPerspectiveInfo(double aPerspectiveDistance,
+                                              const Point& aPerspectiveOrigin,
+                                              const Point& aTransformOrigin,
+                                              const Rect& aContentRectangle)
+  {
+    /**/
+    return VRFieldOfView();
+  }
+
+  VRFieldOfView() {}
+  VRFieldOfView(double up, double right, double down, double left)
+    : upDegrees(up), rightDegrees(right), downDegrees(down), leftDegrees(left)
+  {}
+
+  bool operator==(const VRFieldOfView& other) const {
+    return other.upDegrees == upDegrees &&
+           other.downDegrees == downDegrees &&
+           other.rightDegrees == rightDegrees &&
+           other.leftDegrees == leftDegrees;
+  }
+
+  bool operator!=(const VRFieldOfView& other) const {
+    return !(*this == other);
+  }
+
+  bool IsZero() const {
+    return upDegrees == 0.0 ||
+      rightDegrees == 0.0 ||
+      downDegrees == 0.0 ||
+      leftDegrees == 0.0;
+  }
+
+  double upDegrees;
+  double rightDegrees;
+  double downDegrees;
+  double leftDegrees;
+};
+
+// 12 floats per vertex. Position, tex coordinates
+// for each channel, and 4 generic attributes
+struct VRDistortionConstants {
+  float eyeToSourceScaleAndOffset[4];
+  float destinationScaleAndOffset[4];
+};
+
+struct VRDistortionVertex {
+  float values[12];
+};
+
+struct VRDistortionMesh {
+  nsTArray<VRDistortionVertex> mVertices;
+  nsTArray<uint16_t> mIndices;
+};
+
+struct VRHMDSensorState {
+  double timestamp;
+  uint32_t flags;
+  float orientation[4];
+  float position[3];
+  float angularVelocity[3];
+  float angularAcceleration[3];
+  float linearVelocity[3];
+  float linearAcceleration[3];
+
+  void Clear() {
+    memset(this, 0, sizeof(VRHMDSensorState));
+  }
+};
+
+/* A pure data struct that can be used to see if
+ * the configuration of one HMDInfo matches another; for rendering purposes,
+ * really asking "can the rendering details of this one be used for the other"
+ */
+struct VRHMDConfiguration {
+  VRHMDConfiguration() : hmdType(VRHMDType::NumHMDTypes) {}
+
+  bool operator==(const VRHMDConfiguration& other) const {
+    return hmdType == other.hmdType &&
+      value == other.value &&
+      fov[0] == other.fov[0] &&
+      fov[1] == other.fov[1];
+  }
+
+  bool operator!=(const VRHMDConfiguration& other) const {
+    return hmdType != other.hmdType ||
+      value != other.value ||
+      fov[0] != other.fov[0] ||
+      fov[1] != other.fov[1];
+  }
+
+  bool IsValid() const {
+    return hmdType != VRHMDType::NumHMDTypes;
+  }
+
+  VRHMDType hmdType;
+  uint32_t value;
+  VRFieldOfView fov[2];
+};
+
+class VRHMDInfo {
+public:
+  enum Eye {
+    Eye_Left,
+    Eye_Right,
+    NumEyes
+  };
+
+  enum StateValidFlags {
+    State_Position = 1 << 1,
+    State_Orientation = 1 << 2
+  };
+
+public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRHMDInfo)
+
+  VRHMDType GetType() const { return mType; }
+
+  virtual const VRFieldOfView& GetRecommendedEyeFOV(uint32_t whichEye) { return mRecommendedEyeFOV[whichEye]; }
+  virtual const VRFieldOfView& GetMaximumEyeFOV(uint32_t whichEye) { return mMaximumEyeFOV[whichEye]; }
+
+  const VRHMDConfiguration& GetConfiguration() const { return mConfiguration; }
+
+  /* set the FOV for this HMD unit; this triggers a computation of all the remaining bits.  Returns false if it fails */
+  virtual bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
+                      double zNear, double zFar) = 0;
+  const VRFieldOfView& GetEyeFOV(uint32_t whichEye)  { return mEyeFOV[whichEye]; }
+
+  /* Suggested resolution for rendering a single eye.
+   * Assumption is that left/right rendering will be 2x of this size.
+   * XXX fix this for vertical displays
+   */
+  const IntSize& SuggestedEyeResolution() const { return mEyeResolution; }
+  const Point3D& GetEyeTranslation(uint32_t whichEye) const { return mEyeTranslation[whichEye]; }
+  const Matrix4x4& GetEyeProjectionMatrix(uint32_t whichEye) const { return mEyeProjectionMatrix[whichEye]; }
+
+  virtual uint32_t GetSupportedSensorStateBits() { return mSupportedSensorBits; }
+  virtual bool StartSensorTracking() = 0;
+  virtual VRHMDSensorState GetSensorState(double timeOffset = 0.0) = 0;
+  virtual void StopSensorTracking() = 0;
+
+  virtual void ZeroSensor() = 0;
+
+  virtual void FillDistortionConstants(uint32_t whichEye,
+                                       const IntSize& textureSize, // the full size of the texture
+                                       const IntRect& eyeViewport, // the viewport within the texture for the current eye
+                                       const Size& destViewport,   // the size of the destination viewport
+                                       const Rect& destRect,       // the rectangle within the dest viewport that this should be rendered
+                                       VRDistortionConstants& values) = 0;
+
+  virtual const VRDistortionMesh& GetDistortionMesh(uint32_t whichEye) const { return mDistortionMesh[whichEye]; }
+
+  // The nsIScreen that represents this device
+  virtual nsIScreen* GetScreen() { return mScreen; }
+
+protected:
+  explicit VRHMDInfo(VRHMDType aType) : mType(aType) { MOZ_COUNT_CTOR(VRHMDInfo); }
+  virtual ~VRHMDInfo() { MOZ_COUNT_DTOR(VRHMDInfo); }
+
+  VRHMDType mType;
+  VRHMDConfiguration mConfiguration;
+
+  VRFieldOfView mEyeFOV[NumEyes];
+  IntSize mEyeResolution;
+  Point3D mEyeTranslation[NumEyes];
+  Matrix4x4 mEyeProjectionMatrix[NumEyes];
+  VRDistortionMesh mDistortionMesh[NumEyes];
+  uint32_t mSupportedSensorBits;
+
+  VRFieldOfView mRecommendedEyeFOV[NumEyes];
+  VRFieldOfView mMaximumEyeFOV[NumEyes];
+
+  nsCOMPtr<nsIScreen> mScreen;
+};
+
+class VRHMDManager {
+public:
+  static void ManagerInit();
+  static void ManagerDestroy();
+  static void GetAllHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult);
+
+protected:
+  typedef nsTArray<nsRefPtr<VRHMDManager>> VRHMDManagerArray;
+  static VRHMDManagerArray *sManagers;
+
+public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VRHMDManager)
+
+  virtual bool PlatformInit() = 0;
+  virtual bool Init() = 0;
+  virtual void Destroy() = 0;
+  virtual void GetHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult) = 0;
+
+protected:
+  VRHMDManager() { }
+  virtual ~VRHMDManager() { }
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif /* GFX_VR_H */
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVRCardboard.cpp
@@ -0,0 +1,382 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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 <math.h>
+
+#include "prlink.h"
+#include "prmem.h"
+#include "prenv.h"
+#include "gfxPrefs.h"
+#include "nsString.h"
+#include "mozilla/dom/ScreenOrientation.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Hal.h"
+
+#include "gfxVRCardboard.h"
+
+#include "nsServiceManagerUtils.h"
+#include "nsIScreenManager.h"
+
+#ifdef ANDROID
+#include <android/log.h>
+#define LOG(args...)  __android_log_print(ANDROID_LOG_INFO, "GeckoVR" , ## args)
+#else
+#define LOG(...) do { } while(0)
+#endif
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif
+
+// 1/sqrt(2) (aka sqrt(2)/2)
+#ifndef M_SQRT1_2
+# define M_SQRT1_2	0.70710678118654752440
+#endif
+
+using namespace mozilla::dom;
+using namespace mozilla::gfx;
+using namespace mozilla::gfx::impl;
+
+namespace {
+// some utility functions
+
+// This remaps axes in the given matrix to a new configuration based on the
+// screen orientation.  Similar to what Android SensorManager.remapCoordinateSystem
+// does, except only for a fixed number of transforms that we need.
+Matrix4x4
+RemapMatrixForOrientation(ScreenOrientation screenConfig, const Matrix4x4& aMatrix)
+{
+  Matrix4x4 out;
+  const float *in = &aMatrix._11;
+  float *o = &out._11;
+
+  if (screenConfig == eScreenOrientation_LandscapePrimary) {
+    // remap X,Y -> Y,-X
+    o[0] = -in[1]; o[1] = in[0]; o[2] = in[2];
+    o[4] = -in[5]; o[5] = in[4]; o[6] = in[6];
+    o[8] = -in[9]; o[9] = in[8]; o[10] = in[10];
+  } else if (screenConfig == eScreenOrientation_LandscapeSecondary) {
+    // remap X,Y -> -Y,X
+    o[0] = in[1]; o[1] = -in[0]; o[2] = in[2];
+    o[4] = in[5]; o[5] = -in[4]; o[6] = in[6];
+    o[8] = in[9]; o[9] = -in[8]; o[10] = in[10];
+  } else if (screenConfig == eScreenOrientation_PortraitPrimary ||
+             screenConfig == eScreenOrientation_PortraitSecondary)
+  {
+    // remap X,Y -> X,-Z
+    o[0] = in[0]; o[1] = in[2]; o[2] = -in[1];
+    o[4] = in[4]; o[5] = in[6]; o[6] = -in[5];
+    o[8] = in[8]; o[9] = in[10]; o[10] = -in[9];
+  } else {
+    MOZ_ASSERT(0, "gfxVRCardboard::RemapMatrixForOrientation invalid screenConfig");
+  }
+
+  return out;
+}
+
+}
+
+HMDInfoCardboard::HMDInfoCardboard()
+  : VRHMDInfo(VRHMDType::Cardboard)
+  , mStartCount(0)
+  , mOrient(eScreenOrientation_PortraitPrimary)
+{
+  MOZ_ASSERT(sizeof(HMDInfoCardboard::DistortionVertex) == sizeof(VRDistortionVertex),
+             "HMDInfoCardboard::DistortionVertex must match the size of VRDistortionVertex");
+
+  mSupportedSensorBits = State_Orientation;
+
+  mRecommendedEyeFOV[Eye_Left] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
+  mRecommendedEyeFOV[Eye_Right] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
+
+  mMaximumEyeFOV[Eye_Left] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
+  mMaximumEyeFOV[Eye_Right] = VRFieldOfView(45.0, 45.0, 45.0, 45.0);
+
+  SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0);
+}
+
+bool
+HMDInfoCardboard::StartSensorTracking()
+{
+  LOG("HMDInfoCardboard::StartSensorTracking %d\n", mStartCount);
+  if (mStartCount == 0) {
+    // it's never been started before; initialize observers and
+    // initial state.
+
+    mozilla::hal::ScreenConfiguration sconfig;
+    mozilla::hal::GetCurrentScreenConfiguration(&sconfig);
+    this->Notify(sconfig);
+
+    mozilla::hal::RegisterSensorObserver(mozilla::hal::SENSOR_GAME_ROTATION_VECTOR, this);
+    mozilla::hal::RegisterScreenConfigurationObserver(this);
+
+    mLastSensorState.Clear();
+  }
+
+  mStartCount++;
+  return true;
+}
+
+void
+HMDInfoCardboard::Notify(const mozilla::hal::ScreenConfiguration& config)
+{
+  mOrient = config.orientation();
+
+  if (mOrient == eScreenOrientation_LandscapePrimary) {
+    mScreenTransform = Quaternion(0.f, 0.f, M_SQRT1_2, M_SQRT1_2);
+  } else if (mOrient == eScreenOrientation_LandscapeSecondary) {
+    mScreenTransform = Quaternion(0.f, 0.f, -M_SQRT1_2, M_SQRT1_2);
+  } else if (mOrient == eScreenOrientation_PortraitPrimary) {
+    mScreenTransform = Quaternion();
+  } else if (mOrient == eScreenOrientation_PortraitSecondary) {
+    mScreenTransform = Quaternion(0.f, 0.f, 1.f, 0.f);
+  }
+}
+
+void
+HMDInfoCardboard::Notify(const mozilla::hal::SensorData& data)
+{
+  if (data.sensor() != mozilla::hal::SENSOR_GAME_ROTATION_VECTOR)
+    return;
+
+  const nsTArray<float>& sensorValues = data.values();
+
+  // This is super chatty
+  //LOG("HMDInfoCardboard::Notify %f %f %f %f\n", sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]);
+
+  mSavedLastSensor.Set(sensorValues[0], sensorValues[1], sensorValues[2], sensorValues[3]);
+  mSavedLastSensorTime = data.timestamp();
+  mNeedsSensorCompute = true;
+}
+
+void
+HMDInfoCardboard::ComputeStateFromLastSensor()
+{
+  if (!mNeedsSensorCompute)
+    return;
+
+  // apply the zero orientation
+  Quaternion q = mSensorZeroInverse * mSavedLastSensor;
+
+  // make a matrix from the quat
+  Matrix4x4 qm;
+  qm.SetRotationFromQuaternion(q);
+
+  // remap the coordinate space, based on the orientation
+  Matrix4x4 qmRemapped = RemapMatrixForOrientation(mOrient, qm);
+
+  // turn it back into a quat
+  q.SetFromRotationMatrix(qmRemapped);
+
+  // apply adjustment based on what's been done to the screen and the original zero
+  // position of the base coordinate space
+  q = mScreenTransform * q;
+
+  VRHMDSensorState& state = mLastSensorState;
+
+  state.flags |= State_Orientation;
+  state.orientation[0] = q.x;
+  state.orientation[1] = q.y;
+  state.orientation[2] = q.z;
+  state.orientation[3] = q.w;
+
+  state.timestamp = mSavedLastSensorTime / 1000000.0;
+
+  mNeedsSensorCompute = false;
+}
+
+VRHMDSensorState
+HMDInfoCardboard::GetSensorState(double timeOffset)
+{
+  ComputeStateFromLastSensor();
+  return mLastSensorState;
+}
+
+void
+HMDInfoCardboard::StopSensorTracking()
+{
+  LOG("HMDInfoCardboard::StopSensorTracking, count %d\n", mStartCount);
+  if (--mStartCount == 0) {
+    mozilla::hal::UnregisterScreenConfigurationObserver(this);
+    mozilla::hal::UnregisterSensorObserver(mozilla::hal::SENSOR_GAME_ROTATION_VECTOR, this);
+  }
+}
+
+void
+HMDInfoCardboard::ZeroSensor()
+{
+  mSensorZeroInverse = mSavedLastSensor;
+  mSensorZeroInverse.Invert();
+}
+
+static Matrix4x4
+ConstructProjectionMatrix(const VRFieldOfView& fov, bool rightHanded, double zNear, double zFar)
+{
+  float upTan = tan(fov.upDegrees * M_PI / 180.0);
+  float downTan = tan(fov.downDegrees * M_PI / 180.0);
+  float leftTan = tan(fov.leftDegrees * M_PI / 180.0);
+  float rightTan = tan(fov.rightDegrees * M_PI / 180.0);
+
+  float handednessScale = rightHanded ? -1.0 : 1.0;
+
+  float pxscale = 2.0f / (leftTan + rightTan);
+  float pxoffset = (leftTan - rightTan) * pxscale * 0.5;
+  float pyscale = 2.0f / (upTan + downTan);
+  float pyoffset = (upTan - downTan) * pyscale * 0.5;
+
+  Matrix4x4 mobj;
+  float *m = &mobj._11;
+
+  m[0*4+0] = pxscale;
+  m[0*4+2] = pxoffset * handednessScale;
+
+  m[1*4+1] = pyscale;
+  m[1*4+2] = -pyoffset * handednessScale;
+
+  m[2*4+2] = zFar / (zNear - zFar) * -handednessScale;
+  m[2*4+3] = (zFar * zNear) / (zNear - zFar);
+
+  m[3*4+2] = handednessScale;
+
+  return mobj;
+}
+
+bool
+HMDInfoCardboard::SetFOV(const VRFieldOfView& aFOVLeft,
+                         const VRFieldOfView& aFOVRight,
+                         double zNear, double zFar)
+{
+  const float standardIPD = 0.064f;
+
+  for (uint32_t eye = 0; eye < NumEyes; eye++) {
+    mEyeFOV[eye] = eye == Eye_Left ? aFOVLeft : aFOVRight;
+    mEyeTranslation[eye] = Point3D(standardIPD * (eye == Eye_Left ? -1.0 : 1.0), 0.0, 0.0);
+    mEyeProjectionMatrix[eye] = ConstructProjectionMatrix(mEyeFOV[eye], true, zNear, zFar);
+
+    mDistortionMesh[eye].mVertices.SetLength(4);
+    mDistortionMesh[eye].mIndices.SetLength(6);
+
+    HMDInfoCardboard::DistortionVertex *destv = reinterpret_cast<HMDInfoCardboard::DistortionVertex*>(mDistortionMesh[eye].mVertices.Elements());
+    float xoffs = eye == Eye_Left ? 0.0f : 1.0f;
+    float txoffs = eye == Eye_Left ? 0.0f : 0.5f;
+    destv[0].pos[0] = -1.0 + xoffs;
+    destv[0].pos[1] = -1.0;
+    destv[0].texR[0] = destv[0].texG[0] = destv[0].texB[0] = 0.0 + txoffs;
+    destv[0].texR[1] = destv[0].texG[1] = destv[0].texB[1] = 1.0;
+    destv[0].padding[0] = 1.0; // vignette factor
+
+    destv[1].pos[0] = 0.0 + xoffs;
+    destv[1].pos[1] = -1.0;
+    destv[1].texR[0] = destv[1].texG[0] = destv[1].texB[0] = 0.5 + txoffs;
+    destv[1].texR[1] = destv[1].texG[1] = destv[1].texB[1] = 1.0;
+    destv[1].padding[0] = 1.0; // vignette factor
+
+    destv[2].pos[0] = 0.0 + xoffs;
+    destv[2].pos[1] = 1.0;
+    destv[2].texR[0] = destv[2].texG[0] = destv[2].texB[0] = 0.5 + txoffs;
+    destv[2].texR[1] = destv[2].texG[1] = destv[2].texB[1] = 0.0;
+    destv[2].padding[0] = 1.0; // vignette factor
+
+    destv[3].pos[0] = -1.0 + xoffs;
+    destv[3].pos[1] = 1.0;
+    destv[3].texR[0] = destv[3].texG[0] = destv[3].texB[0] = 0.0 + txoffs;
+    destv[3].texR[1] = destv[3].texG[1] = destv[3].texB[1] = 0.0;
+    destv[3].padding[0] = 1.0; // vignette factor
+
+    uint16_t *iv = mDistortionMesh[eye].mIndices.Elements();
+    iv[0] = 0; iv[1] = 1; iv[2] = 2;
+    iv[3] = 2; iv[4] = 3; iv[5] = 0;
+  }
+
+  // XXX find out the default screen size and use that
+  mEyeResolution.width = 1920 / 2;
+  mEyeResolution.height = 1080;
+
+  mConfiguration.hmdType = mType;
+  mConfiguration.value = 0;
+  mConfiguration.fov[0] = aFOVLeft;
+  mConfiguration.fov[1] = aFOVRight;
+
+  return true;
+}
+
+void
+HMDInfoCardboard::FillDistortionConstants(uint32_t whichEye,
+                                          const IntSize& textureSize, const IntRect& eyeViewport,
+                                          const Size& destViewport, const Rect& destRect,
+                                          VRDistortionConstants& values)
+{
+  // these modify the texture coordinates; texcoord * zw + xy
+  values.eyeToSourceScaleAndOffset[0] = 0.0;
+  values.eyeToSourceScaleAndOffset[1] = 0.0;
+  values.eyeToSourceScaleAndOffset[2] = 1.0;
+  values.eyeToSourceScaleAndOffset[3] = 1.0;
+
+  // Our mesh positions are in the [-1..1] clip space; we give appropriate offset
+  // and scaling for the right viewport.  (In the 0..2 space for sanity)
+
+  // this is the destRect in clip space
+  float x0 = destRect.x / destViewport.width * 2.0 - 1.0;
+  float x1 = (destRect.x + destRect.width) / destViewport.width * 2.0 - 1.0;
+
+  float y0 = destRect.y / destViewport.height * 2.0 - 1.0;
+  float y1 = (destRect.y + destRect.height) / destViewport.height * 2.0 - 1.0;
+
+  // offset
+  values.destinationScaleAndOffset[0] = (x0+x1) / 2.0;
+  values.destinationScaleAndOffset[1] = (y0+y1) / 2.0;
+  // scale
+  values.destinationScaleAndOffset[2] = destRect.width / destViewport.width;
+  values.destinationScaleAndOffset[3] = destRect.height / destViewport.height;
+}
+
+void
+HMDInfoCardboard::Destroy()
+{
+}
+
+
+
+bool
+VRHMDManagerCardboard::PlatformInit()
+{
+  return true;
+}
+
+bool
+VRHMDManagerCardboard::Init()
+{
+  if (mCardboardInitialized)
+    return true;
+
+  nsRefPtr<HMDInfoCardboard> hmd = new HMDInfoCardboard();
+  mCardboardHMDs.AppendElement(hmd);
+
+  mCardboardInitialized = true;
+  return true;
+}
+
+void
+VRHMDManagerCardboard::Destroy()
+{
+  if (!mCardboardInitialized)
+    return;
+
+  for (size_t i = 0; i < mCardboardHMDs.Length(); ++i) {
+    mCardboardHMDs[i]->Destroy();
+  }
+
+  mCardboardHMDs.Clear();
+  mCardboardInitialized = false;
+}
+
+void
+VRHMDManagerCardboard::GetHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult)
+{
+  Init();
+  for (size_t i = 0; i < mCardboardHMDs.Length(); ++i) {
+    aHMDResult.AppendElement(mCardboardHMDs[i]);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVRCardboard.h
@@ -0,0 +1,97 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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/. */
+
+#ifndef GFX_VR_CARDBOARD_H
+#define GFX_VR_CARDBOARD_H
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/gfx/Quaternion.h"
+#include "mozilla/EnumeratedArray.h"
+#include "mozilla/HalSensor.h"
+#include "mozilla/HalScreenConfiguration.h"
+
+#include "gfxVR.h"
+
+namespace mozilla {
+namespace gfx {
+namespace impl {
+
+class HMDInfoCardboard :
+    public VRHMDInfo,
+    public hal::ISensorObserver,
+    public hal::ScreenConfigurationObserver
+{
+public:
+  explicit HMDInfoCardboard();
+
+  bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
+              double zNear, double zFar) override;
+
+  bool StartSensorTracking() override;
+  VRHMDSensorState GetSensorState(double timeOffset) override;
+  void StopSensorTracking() override;
+  void ZeroSensor() override;
+
+  void FillDistortionConstants(uint32_t whichEye,
+                               const IntSize& textureSize, const IntRect& eyeViewport,
+                               const Size& destViewport, const Rect& destRect,
+                               VRDistortionConstants& values) override;
+
+  void Destroy();
+
+  // ISensorObserver interface
+  void Notify(const hal::SensorData& SensorData) override;
+  // ScreenConfigurationObserver interface
+  void Notify(const hal::ScreenConfiguration& ScreenConfiguration) override;
+
+protected:
+  // must match the size of VRDistortionVertex
+  struct DistortionVertex {
+    float pos[2];
+    float texR[2];
+    float texG[2];
+    float texB[2];
+    float padding[4];
+  };
+
+  virtual ~HMDInfoCardboard() {
+    Destroy();
+  }
+
+  void ComputeStateFromLastSensor();
+
+  uint32_t mStartCount;
+  VRHMDSensorState mLastSensorState;
+  uint32_t mOrient;
+  Quaternion mScreenTransform;
+  Quaternion mSensorZeroInverse;
+
+  Quaternion mSavedLastSensor;
+  double mSavedLastSensorTime;
+  bool mNeedsSensorCompute;    // if we need to compute the state from mSavedLastSensor
+};
+
+} // namespace impl
+
+class VRHMDManagerCardboard : public VRHMDManager
+{
+public:
+  VRHMDManagerCardboard()
+    : mCardboardInitialized(false)
+  { }
+
+  virtual bool PlatformInit() override;
+  virtual bool Init() override;
+  virtual void Destroy() override;
+  virtual void GetHMDs(nsTArray<nsRefPtr<VRHMDInfo> >& aHMDResult) override;
+protected:
+  nsTArray<nsRefPtr<impl::HMDInfoCardboard>> mCardboardHMDs;
+  bool mCardboardInitialized;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif /* GFX_VR_CARDBOARD_H */
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVROculus.cpp
@@ -0,0 +1,547 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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 <math.h>
+
+#include "prlink.h"
+#include "prmem.h"
+#include "prenv.h"
+#include "gfxPrefs.h"
+#include "nsString.h"
+#include "mozilla/Preferences.h"
+
+#include "gfxVROculus.h"
+
+#include "nsServiceManagerUtils.h"
+#include "nsIScreenManager.h"
+
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif
+
+using namespace mozilla::gfx;
+using namespace mozilla::gfx::impl;
+
+namespace {
+
+#ifdef OVR_CAPI_LIMITED_MOZILLA
+static pfn_ovr_Initialize ovr_Initialize = nullptr;
+static pfn_ovr_Shutdown ovr_Shutdown = nullptr;
+static pfn_ovrHmd_Detect ovrHmd_Detect = nullptr;
+static pfn_ovrHmd_Create ovrHmd_Create = nullptr;
+static pfn_ovrHmd_Destroy ovrHmd_Destroy = nullptr;
+static pfn_ovrHmd_CreateDebug ovrHmd_CreateDebug = nullptr;
+static pfn_ovrHmd_GetLastError ovrHmd_GetLastError = nullptr;
+static pfn_ovrHmd_AttachToWindow ovrHmd_AttachToWindow = nullptr;
+static pfn_ovrHmd_GetEnabledCaps ovrHmd_GetEnabledCaps = nullptr;
+static pfn_ovrHmd_SetEnabledCaps ovrHmd_SetEnabledCaps = nullptr;
+static pfn_ovrHmd_ConfigureTracking ovrHmd_ConfigureTracking = nullptr;
+static pfn_ovrHmd_RecenterPose ovrHmd_RecenterPose = nullptr;
+static pfn_ovrHmd_GetTrackingState ovrHmd_GetTrackingState = nullptr;
+static pfn_ovrHmd_GetFovTextureSize ovrHmd_GetFovTextureSize = nullptr;
+static pfn_ovrHmd_GetRenderDesc ovrHmd_GetRenderDesc = nullptr;
+static pfn_ovrHmd_CreateDistortionMesh ovrHmd_CreateDistortionMesh = nullptr;
+static pfn_ovrHmd_DestroyDistortionMesh ovrHmd_DestroyDistortionMesh = nullptr;
+static pfn_ovrHmd_GetRenderScaleAndOffset ovrHmd_GetRenderScaleAndOffset = nullptr;
+static pfn_ovrHmd_GetFrameTiming ovrHmd_GetFrameTiming = nullptr;
+static pfn_ovrHmd_BeginFrameTiming ovrHmd_BeginFrameTiming = nullptr;
+static pfn_ovrHmd_EndFrameTiming ovrHmd_EndFrameTiming = nullptr;
+static pfn_ovrHmd_ResetFrameTiming ovrHmd_ResetFrameTiming = nullptr;
+static pfn_ovrHmd_GetEyePoses ovrHmd_GetEyePoses = nullptr;
+static pfn_ovrHmd_GetHmdPosePerEye ovrHmd_GetHmdPosePerEye = nullptr;
+static pfn_ovrHmd_GetEyeTimewarpMatrices ovrHmd_GetEyeTimewarpMatrices = nullptr;
+static pfn_ovrMatrix4f_Projection ovrMatrix4f_Projection = nullptr;
+static pfn_ovrMatrix4f_OrthoSubProjection ovrMatrix4f_OrthoSubProjection = nullptr;
+static pfn_ovr_GetTimeInSeconds ovr_GetTimeInSeconds = nullptr;
+
+#ifdef HAVE_64BIT_BUILD
+#define BUILD_BITS 64
+#else
+#define BUILD_BITS 32
+#endif
+
+#define LIBOVR_PRODUCT_VERSION 0
+#define LIBOVR_MAJOR_VERSION   5
+#define LIBOVR_MINOR_VERSION   0
+
+static bool
+InitializeOculusCAPI()
+{
+  static PRLibrary *ovrlib = nullptr;
+
+  if (!ovrlib) {
+    nsTArray<nsCString> libSearchPaths;
+    nsCString libName;
+    nsCString searchPath;
+
+#if defined(_WIN32)
+    static const char dirSep = '\\';
+#else
+    static const char dirSep = '/';
+#endif
+
+#if defined(_WIN32)
+    static const int pathLen = 260;
+    searchPath.SetCapacity(pathLen);
+    int realLen = ::GetSystemDirectoryA(searchPath.BeginWriting(), pathLen);
+    if (realLen != 0 && realLen < pathLen) {
+      searchPath.SetLength(realLen);
+      libSearchPaths.AppendElement(searchPath);
+    }
+    libName.AppendPrintf("LibOVRRT%d_%d_%d.dll", BUILD_BITS, LIBOVR_PRODUCT_VERSION, LIBOVR_MAJOR_VERSION);
+#elif defined(__APPLE__)
+    searchPath.Truncate();
+    searchPath.AppendPrintf("/Library/Frameworks/LibOVRRT_%d.framework/Versions/%d", LIBOVR_PRODUCT_VERSION, LIBOVR_MAJOR_VERSION);
+    libSearchPaths.AppendElement(searchPath);
+
+    if (PR_GetEnv("HOME")) {
+      searchPath.Truncate();
+      searchPath.AppendPrintf("%s/Library/Frameworks/LibOVRRT_%d.framework/Versions/%d", PR_GetEnv("HOME"), LIBOVR_PRODUCT_VERSION, LIBOVR_MAJOR_VERSION);
+      libSearchPaths.AppendElement(searchPath);
+    }
+    libName.AppendPrintf("LibOVRRT_%d", LIBOVR_PRODUCT_VERSION);
+#else
+    libSearchPaths.AppendElement(nsCString("/usr/local/lib"));
+    libSearchPaths.AppendElement(nsCString("/usr/lib"));
+    libName.AppendPrintf("LibOVRRT%d_%d.so.%d", BUILD_BITS, LIBOVR_PRODUCT_VERSION, LIBOVR_MAJOR_VERSION);
+#endif
+
+    // If the pref is present, we override libName
+    nsAdoptingCString prefLibPath = mozilla::Preferences::GetCString("dom.vr.ovr_lib_path");
+    if (prefLibPath && prefLibPath.get()) {
+      libSearchPaths.InsertElementsAt(0, 1, prefLibPath);
+    }
+
+    nsAdoptingCString prefLibName = mozilla::Preferences::GetCString("dom.vr.ovr_lib_name");
+    if (prefLibName && prefLibName.get()) {
+      libName.Assign(prefLibName);
+    }
+
+    // search the path/module dir
+    libSearchPaths.InsertElementsAt(0, 1, nsCString());
+
+    // If the env var is present, we override libName
+    if (PR_GetEnv("OVR_LIB_PATH")) {
+      searchPath = PR_GetEnv("OVR_LIB_PATH");
+      libSearchPaths.InsertElementsAt(0, 1, searchPath);
+    }
+
+    if (PR_GetEnv("OVR_LIB_NAME")) {
+      libName = PR_GetEnv("OVR_LIB_NAME");
+    }
+
+    for (uint32_t i = 0; i < libSearchPaths.Length(); ++i) {
+      nsCString& libPath = libSearchPaths[i];
+      nsCString fullName;
+      if (libPath.Length() == 0) {
+        fullName.Assign(libName);
+      } else {
+        fullName.AppendPrintf("%s%c%s", libPath.BeginReading(), dirSep, libName.BeginReading());
+      }
+
+      ovrlib = PR_LoadLibrary(fullName.BeginReading());
+      if (ovrlib)
+        break;
+    }
+
+    if (!ovrlib) {
+      printf_stderr("Failed to load Oculus VR library!\n");
+      return false;
+    }
+  }
+
+  // was it already initialized?
+  if (ovr_Initialize)
+    return true;
+
+#define REQUIRE_FUNCTION(_x) do { \
+    *(void **)&_x = (void *) PR_FindSymbol(ovrlib, #_x);                \
+    if (!_x) { printf_stderr(#_x " symbol missing\n"); goto fail; }       \
+  } while (0)
+
+  REQUIRE_FUNCTION(ovr_Initialize);
+  REQUIRE_FUNCTION(ovr_Shutdown);
+  REQUIRE_FUNCTION(ovrHmd_Detect);
+  REQUIRE_FUNCTION(ovrHmd_Create);
+  REQUIRE_FUNCTION(ovrHmd_Destroy);
+  REQUIRE_FUNCTION(ovrHmd_CreateDebug);
+  REQUIRE_FUNCTION(ovrHmd_GetLastError);
+  REQUIRE_FUNCTION(ovrHmd_AttachToWindow);
+  REQUIRE_FUNCTION(ovrHmd_GetEnabledCaps);
+  REQUIRE_FUNCTION(ovrHmd_SetEnabledCaps);
+  REQUIRE_FUNCTION(ovrHmd_ConfigureTracking);
+  REQUIRE_FUNCTION(ovrHmd_RecenterPose);
+  REQUIRE_FUNCTION(ovrHmd_GetTrackingState);
+
+  REQUIRE_FUNCTION(ovrHmd_GetFovTextureSize);
+  REQUIRE_FUNCTION(ovrHmd_GetRenderDesc);
+  REQUIRE_FUNCTION(ovrHmd_CreateDistortionMesh);
+  REQUIRE_FUNCTION(ovrHmd_DestroyDistortionMesh);
+  REQUIRE_FUNCTION(ovrHmd_GetRenderScaleAndOffset);
+  REQUIRE_FUNCTION(ovrHmd_GetFrameTiming);
+  REQUIRE_FUNCTION(ovrHmd_BeginFrameTiming);
+  REQUIRE_FUNCTION(ovrHmd_EndFrameTiming);
+  REQUIRE_FUNCTION(ovrHmd_ResetFrameTiming);
+  REQUIRE_FUNCTION(ovrHmd_GetEyePoses);
+  REQUIRE_FUNCTION(ovrHmd_GetHmdPosePerEye);
+  REQUIRE_FUNCTION(ovrHmd_GetEyeTimewarpMatrices);
+  REQUIRE_FUNCTION(ovrMatrix4f_Projection);
+  REQUIRE_FUNCTION(ovrMatrix4f_OrthoSubProjection);
+  REQUIRE_FUNCTION(ovr_GetTimeInSeconds);
+
+#undef REQUIRE_FUNCTION
+
+  return true;
+
+ fail:
+  ovr_Initialize = nullptr;
+  return false;
+}
+
+#else
+// we're statically linked; it's available
+static bool InitializeOculusCAPI()
+{
+  return true;
+}
+#endif
+
+ovrFovPort
+ToFovPort(const VRFieldOfView& aFOV)
+{
+  ovrFovPort fovPort;
+  fovPort.LeftTan = tan(aFOV.leftDegrees * M_PI / 180.0);
+  fovPort.RightTan = tan(aFOV.rightDegrees * M_PI / 180.0);
+  fovPort.UpTan = tan(aFOV.upDegrees * M_PI / 180.0);
+  fovPort.DownTan = tan(aFOV.downDegrees * M_PI / 180.0);
+  return fovPort;
+}
+
+VRFieldOfView
+FromFovPort(const ovrFovPort& aFOV)
+{
+  VRFieldOfView fovInfo;
+  fovInfo.leftDegrees = atan(aFOV.LeftTan) * 180.0 / M_PI;
+  fovInfo.rightDegrees = atan(aFOV.RightTan) * 180.0 / M_PI;
+  fovInfo.upDegrees = atan(aFOV.UpTan) * 180.0 / M_PI;
+  fovInfo.downDegrees = atan(aFOV.DownTan) * 180.0 / M_PI;
+  return fovInfo;
+}
+
+} // anonymous namespace
+
+HMDInfoOculus::HMDInfoOculus(ovrHmd aHMD)
+  : VRHMDInfo(VRHMDType::Oculus)
+  , mHMD(aHMD)
+  , mStartCount(0)
+{
+  MOZ_ASSERT(sizeof(HMDInfoOculus::DistortionVertex) == sizeof(VRDistortionVertex),
+             "HMDInfoOculus::DistortionVertex must match the size of VRDistortionVertex");
+
+  MOZ_COUNT_CTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
+
+  mSupportedSensorBits = 0;
+  if (mHMD->TrackingCaps & ovrTrackingCap_Orientation)
+    mSupportedSensorBits |= State_Orientation;
+  if (mHMD->TrackingCaps & ovrTrackingCap_Position)
+    mSupportedSensorBits |= State_Position;
+
+  mRecommendedEyeFOV[Eye_Left] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Left]);
+  mRecommendedEyeFOV[Eye_Right] = FromFovPort(mHMD->DefaultEyeFov[ovrEye_Right]);
+
+  mMaximumEyeFOV[Eye_Left] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Left]);
+  mMaximumEyeFOV[Eye_Right] = FromFovPort(mHMD->MaxEyeFov[ovrEye_Right]);
+
+  SetFOV(mRecommendedEyeFOV[Eye_Left], mRecommendedEyeFOV[Eye_Right], 0.01, 10000.0);
+
+  nsCOMPtr<nsIScreenManager> screenmgr = do_GetService("@mozilla.org/gfx/screenmanager;1");
+  if (screenmgr) {
+    screenmgr->ScreenForRect(mHMD->WindowsPos.x, mHMD->WindowsPos.y,
+                             mHMD->Resolution.w, mHMD->Resolution.h,
+                             getter_AddRefs(mScreen));
+  }
+}
+
+void
+HMDInfoOculus::Destroy()
+{
+  if (mHMD) {
+    ovrHmd_Destroy(mHMD);
+    mHMD = nullptr;
+  }
+}
+
+bool
+HMDInfoOculus::SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
+                      double zNear, double zFar)
+{
+  float pixelsPerDisplayPixel = 1.0;
+  ovrSizei texSize[2];
+
+  uint32_t caps = ovrDistortionCap_Chromatic | ovrDistortionCap_Vignette; // XXX TODO add TimeWarp
+
+  // get eye parameters and create the mesh
+  for (uint32_t eye = 0; eye < NumEyes; eye++) {
+    mEyeFOV[eye] = eye == 0 ? aFOVLeft : aFOVRight;
+    mFOVPort[eye] = ToFovPort(mEyeFOV[eye]);
+
+    ovrEyeRenderDesc renderDesc = ovrHmd_GetRenderDesc(mHMD, (ovrEyeType) eye, mFOVPort[eye]);
+
+    // these values are negated so that content can add the adjustment to its camera position,
+    // instead of subtracting
+    mEyeTranslation[eye] = Point3D(-renderDesc.HmdToEyeViewOffset.x, -renderDesc.HmdToEyeViewOffset.y, -renderDesc.HmdToEyeViewOffset.z);
+
+    // note that we are using a right-handed coordinate system here, to match CSS
+    ovrMatrix4f projMatrix = ovrMatrix4f_Projection(mFOVPort[eye], zNear, zFar, true);
+
+    // XXX this is gross, we really need better methods on Matrix4x4
+    memcpy(&mEyeProjectionMatrix[eye], projMatrix.M, sizeof(ovrMatrix4f));
+    mEyeProjectionMatrix[eye].Transpose();
+
+    texSize[eye] = ovrHmd_GetFovTextureSize(mHMD, (ovrEyeType) eye, mFOVPort[eye], pixelsPerDisplayPixel);
+
+    ovrDistortionMesh mesh;
+    bool ok = ovrHmd_CreateDistortionMesh(mHMD, (ovrEyeType) eye, mFOVPort[eye], caps, &mesh);
+    if (!ok)
+      return false;
+
+    mDistortionMesh[eye].mVertices.SetLength(mesh.VertexCount);
+    mDistortionMesh[eye].mIndices.SetLength(mesh.IndexCount);
+
+    ovrDistortionVertex *srcv = mesh.pVertexData;
+    HMDInfoOculus::DistortionVertex *destv = reinterpret_cast<HMDInfoOculus::DistortionVertex*>(mDistortionMesh[eye].mVertices.Elements());
+    memset(destv, 0, mesh.VertexCount * sizeof(VRDistortionVertex));
+    for (uint32_t i = 0; i < mesh.VertexCount; ++i) {
+      destv[i].pos[0] = srcv[i].ScreenPosNDC.x;
+      destv[i].pos[1] = srcv[i].ScreenPosNDC.y;
+
+      destv[i].texR[0] = srcv[i].TanEyeAnglesR.x;
+      destv[i].texR[1] = srcv[i].TanEyeAnglesR.y;
+      destv[i].texG[0] = srcv[i].TanEyeAnglesG.x;
+      destv[i].texG[1] = srcv[i].TanEyeAnglesG.y;
+      destv[i].texB[0] = srcv[i].TanEyeAnglesB.x;
+      destv[i].texB[1] = srcv[i].TanEyeAnglesB.y;
+
+      destv[i].genericAttribs[0] = srcv[i].VignetteFactor;
+      destv[i].genericAttribs[1] = srcv[i].TimeWarpFactor;
+    }
+
+    memcpy(mDistortionMesh[eye].mIndices.Elements(), mesh.pIndexData, mesh.IndexCount * sizeof(uint16_t));
+    ovrHmd_DestroyDistortionMesh(&mesh);
+  }
+
+  // take the max of both for eye resolution
+  mEyeResolution.width = std::max(texSize[Eye_Left].w, texSize[Eye_Right].w);
+  mEyeResolution.height = std::max(texSize[Eye_Left].h, texSize[Eye_Right].h);
+
+  mConfiguration.hmdType = mType;
+  mConfiguration.value = 0;
+  mConfiguration.fov[0] = aFOVLeft;
+  mConfiguration.fov[1] = aFOVRight;
+
+  return true;
+  //* need to call this during rendering each frame I think? */
+  //ovrHmd_GetRenderScaleAndOffset(fovPort, texSize, renderViewport, uvScaleOffsetOut);
+}
+
+void
+HMDInfoOculus::FillDistortionConstants(uint32_t whichEye,
+                                       const IntSize& textureSize,
+                                       const IntRect& eyeViewport,
+                                       const Size& destViewport,
+                                       const Rect& destRect,
+                                       VRDistortionConstants& values)
+{
+  ovrSizei texSize = { textureSize.width, textureSize.height };
+  ovrRecti eyePort = { { eyeViewport.x, eyeViewport.y }, { eyeViewport.width, eyeViewport.height } };
+  ovrVector2f scaleOut[2];
+
+  ovrHmd_GetRenderScaleAndOffset(mFOVPort[whichEye], texSize, eyePort, scaleOut);
+
+  values.eyeToSourceScaleAndOffset[0] = scaleOut[1].x;
+  values.eyeToSourceScaleAndOffset[1] = scaleOut[1].y;
+  values.eyeToSourceScaleAndOffset[2] = scaleOut[0].x;
+  values.eyeToSourceScaleAndOffset[3] = scaleOut[0].y;
+
+  // These values are in clip space [-1..1] range, but we're providing
+  // scaling in the 0..2 space for sanity.
+
+  // this is the destRect in clip space
+  float x0 = destRect.x / destViewport.width * 2.0 - 1.0;
+  float x1 = (destRect.x + destRect.width) / destViewport.width * 2.0 - 1.0;
+
+  float y0 = destRect.y / destViewport.height * 2.0 - 1.0;
+  float y1 = (destRect.y + destRect.height) / destViewport.height * 2.0 - 1.0;
+
+  // offset
+  values.destinationScaleAndOffset[0] = (x0+x1) / 2.0;
+  values.destinationScaleAndOffset[1] = (y0+y1) / 2.0;
+  // scale
+  values.destinationScaleAndOffset[2] = destRect.width / destViewport.width;
+  values.destinationScaleAndOffset[3] = destRect.height / destViewport.height;
+}
+
+bool
+HMDInfoOculus::StartSensorTracking()
+{
+  if (mStartCount == 0) {
+    bool ok = ovrHmd_ConfigureTracking(mHMD, ovrTrackingCap_Orientation | ovrTrackingCap_Position, 0);
+    if (!ok)
+      return false;
+  }
+
+  mStartCount++;
+  return true;
+}
+
+void
+HMDInfoOculus::StopSensorTracking()
+{
+  if (--mStartCount == 0) {
+    ovrHmd_ConfigureTracking(mHMD, 0, 0);
+  }
+}
+
+void
+HMDInfoOculus::ZeroSensor()
+{
+  ovrHmd_RecenterPose(mHMD);
+}
+
+VRHMDSensorState
+HMDInfoOculus::GetSensorState(double timeOffset)
+{
+  VRHMDSensorState result;
+  result.Clear();
+
+  // XXX this is the wrong time base for timeOffset; we need to figure out how to synchronize
+  // the Oculus time base and the browser one.
+  ovrTrackingState state = ovrHmd_GetTrackingState(mHMD, ovr_GetTimeInSeconds() + timeOffset);
+  ovrPoseStatef& pose(state.HeadPose);
+
+  result.timestamp = pose.TimeInSeconds;
+
+  if (state.StatusFlags & ovrStatus_OrientationTracked) {
+    result.flags |= State_Orientation;
+
+    result.orientation[0] = pose.ThePose.Orientation.x;
+    result.orientation[1] = pose.ThePose.Orientation.y;
+    result.orientation[2] = pose.ThePose.Orientation.z;
+    result.orientation[3] = pose.ThePose.Orientation.w;
+    
+    result.angularVelocity[0] = pose.AngularVelocity.x;
+    result.angularVelocity[1] = pose.AngularVelocity.y;
+    result.angularVelocity[2] = pose.AngularVelocity.z;
+
+    result.angularAcceleration[0] = pose.AngularAcceleration.x;
+    result.angularAcceleration[1] = pose.AngularAcceleration.y;
+    result.angularAcceleration[2] = pose.AngularAcceleration.z;
+  }
+
+  if (state.StatusFlags & ovrStatus_PositionTracked) {
+    result.flags |= State_Position;
+
+    result.position[0] = pose.ThePose.Position.x;
+    result.position[1] = pose.ThePose.Position.y;
+    result.position[2] = pose.ThePose.Position.z;
+    
+    result.linearVelocity[0] = pose.LinearVelocity.x;
+    result.linearVelocity[1] = pose.LinearVelocity.y;
+    result.linearVelocity[2] = pose.LinearVelocity.z;
+
+    result.linearAcceleration[0] = pose.LinearAcceleration.x;
+    result.linearAcceleration[1] = pose.LinearAcceleration.y;
+    result.linearAcceleration[2] = pose.LinearAcceleration.z;
+  }
+
+  return result;
+}
+
+bool
+VRHMDManagerOculus::PlatformInit()
+{
+  if (mOculusPlatformInitialized)
+    return true;
+
+  if (!gfxPrefs::VREnabled())
+    return false;
+
+  if (!InitializeOculusCAPI())
+    return false;
+
+  ovrInitParams params;
+  params.Flags = ovrInit_RequestVersion;
+  params.RequestedMinorVersion = LIBOVR_MINOR_VERSION;
+  params.LogCallback = nullptr;
+  params.ConnectionTimeoutMS = 0;
+
+  bool ok = ovr_Initialize(&params);
+
+  if (!ok)
+    return false;
+
+  mOculusPlatformInitialized = true;
+  return true;
+}
+
+bool
+VRHMDManagerOculus::Init()
+{
+  if (mOculusInitialized)
+    return true;
+
+  if (!PlatformInit())
+    return false;
+
+  int count = ovrHmd_Detect();
+
+  for (int i = 0; i < count; ++i) {
+    ovrHmd hmd = ovrHmd_Create(i);
+    if (hmd) {
+      nsRefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
+      mOculusHMDs.AppendElement(oc);
+    }
+  }
+
+  // VRAddTestDevices == 1: add test device only if no real devices present
+  // VRAddTestDevices == 2: add test device always
+  if ((count == 0 && gfxPrefs::VRAddTestDevices() == 1) ||
+      (gfxPrefs::VRAddTestDevices() == 2))
+  {
+    ovrHmd hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
+    if (hmd) {
+      nsRefPtr<HMDInfoOculus> oc = new HMDInfoOculus(hmd);
+      mOculusHMDs.AppendElement(oc);
+    }
+  }
+
+  mOculusInitialized = true;
+  return true;
+}
+
+void
+VRHMDManagerOculus::Destroy()
+{
+  if (!mOculusInitialized)
+    return;
+
+  for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
+    mOculusHMDs[i]->Destroy();
+  }
+
+  mOculusHMDs.Clear();
+
+  ovr_Shutdown();
+  mOculusInitialized = false;
+}
+
+void
+VRHMDManagerOculus::GetHMDs(nsTArray<nsRefPtr<VRHMDInfo>>& aHMDResult)
+{
+  Init();
+  for (size_t i = 0; i < mOculusHMDs.Length(); ++i) {
+    aHMDResult.AppendElement(mOculusHMDs[i]);
+  }
+}
new file mode 100644
--- /dev/null
+++ b/gfx/vr/gfxVROculus.h
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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/. */
+
+#ifndef GFX_VR_OCULUS_H
+#define GFX_VR_OCULUS_H
+
+#include "nsTArray.h"
+#include "nsIScreen.h"
+#include "nsCOMPtr.h"
+#include "nsRefPtr.h"
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/EnumeratedArray.h"
+
+#include "gfxVR.h"
+#include "ovr_capi_dynamic.h"
+
+namespace mozilla {
+namespace gfx {
+namespace impl {
+
+class HMDInfoOculus : public VRHMDInfo {
+public:
+  explicit HMDInfoOculus(ovrHmd aHMD);
+
+  bool SetFOV(const VRFieldOfView& aFOVLeft, const VRFieldOfView& aFOVRight,
+              double zNear, double zFar) override;
+
+  bool StartSensorTracking() override;
+  VRHMDSensorState GetSensorState(double timeOffset) override;
+  void StopSensorTracking() override;
+  void ZeroSensor() override;
+
+  void FillDistortionConstants(uint32_t whichEye,
+                               const IntSize& textureSize, const IntRect& eyeViewport,
+                               const Size& destViewport, const Rect& destRect,
+                               VRDistortionConstants& values) override;
+
+  void Destroy();
+
+protected:
+  // must match the size of VRDistortionVertex
+  struct DistortionVertex {
+    float pos[2];
+    float texR[2];
+    float texG[2];
+    float texB[2];
+    float genericAttribs[4];
+  };
+
+  virtual ~HMDInfoOculus() {
+      Destroy();
+      MOZ_COUNT_DTOR_INHERITED(HMDInfoOculus, VRHMDInfo);
+  }
+
+  ovrHmd mHMD;
+  ovrFovPort mFOVPort[2];
+  uint32_t mStartCount;
+};
+
+} // namespace impl
+
+class VRHMDManagerOculus : public VRHMDManager
+{
+public:
+  VRHMDManagerOculus()
+    : mOculusInitialized(false), mOculusPlatformInitialized(false)
+  { }
+
+  virtual bool PlatformInit() override;
+  virtual bool Init() override;
+  virtual void Destroy() override;
+  virtual void GetHMDs(nsTArray<nsRefPtr<VRHMDInfo> >& aHMDResult) override;
+protected:
+  nsTArray<nsRefPtr<impl::HMDInfoOculus>> mOculusHMDs;
+  bool mOculusInitialized;
+  bool mOculusPlatformInitialized;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif /* GFX_VR_OCULUS_H */
new file mode 100644
--- /dev/null
+++ b/gfx/vr/moz.build
@@ -0,0 +1,33 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+EXPORTS += [
+    'gfxVR.h',
+]
+
+LOCAL_INCLUDES += [
+    '/gfx/thebes',
+]
+
+UNIFIED_SOURCES += [
+    'gfxVR.cpp',
+    'gfxVRCardboard.cpp',
+    'gfxVROculus.cpp',
+]
+
+CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
+CXXFLAGS += CONFIG['TK_CFLAGS']
+CFLAGS += CONFIG['MOZ_CAIRO_CFLAGS']
+CFLAGS += CONFIG['TK_CFLAGS']
+
+FAIL_ON_WARNINGS = not CONFIG['_MSC_VER']
+
+MSVC_ENABLE_PGO = True
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FINAL_LIBRARY = 'xul'
+
new file mode 100644
--- /dev/null
+++ b/gfx/vr/ovr_capi_dynamic.h
@@ -0,0 +1,292 @@
+/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
+/* 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/. */
+
+/* This file contains just the needed struct definitions for
+ * interacting with the Oculus VR C API, without needing to #include
+ * OVR_CAPI.h directly.  Note that it uses the same type names as the
+ * CAPI, and cannot be #included at the same time as OVR_CAPI.h.  It
+ * does not include the entire C API, just want's needed.
+ */
+
+#ifdef OVR_CAPI_h
+#warning OVR_CAPI.h included before ovr_capi_dynamic.h, skpping this
+#define mozilla_ovr_capi_dynamic_h_
+
+#else
+
+#ifndef mozilla_ovr_capi_dynamic_h_
+#define mozilla_ovr_capi_dynamic_h_
+
+#define OVR_CAPI_LIMITED_MOZILLA 1
+
+#if defined(_WIN32)
+#define OVR_PFN __cdecl
+#else
+#define OVR_PFN
+#endif
+
+#if !defined(OVR_ALIGNAS)
+#if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L))
+#define OVR_ALIGNAS(n) alignas(n)
+#elif defined(__clang__) && !defined(__APPLE__) && (((__clang_major__ * 100) + __clang_minor__) >= 300) && (__cplusplus >= 201103L)
+#define OVR_ALIGNAS(n) alignas(n)
+#elif defined(__clang__) && defined(__APPLE__) && (((__clang_major__ * 100) + __clang_minor__) >= 401) && (__cplusplus >= 201103L)
+#define OVR_ALIGNAS(n) alignas(n)
+#elif defined(_MSC_VER) && (_MSC_VER >= 1900)
+#define OVR_ALIGNAS(n) alignas(n)
+#elif defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408)
+#define OVR_ALIGNAS(n) alignas(n)
+#elif defined(__GNUC__) || defined(__clang__)
+#define OVR_ALIGNAS(n) __attribute__((aligned(n)))
+#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
+#define OVR_ALIGNAS(n) __declspec(align(n))
+#else
+#error Need to define OVR_ALIGNAS
+#endif
+#endif
+
+#ifdef __cplusplus 
+extern "C" {
+#endif
+
+typedef char ovrBool;
+typedef struct { int x, y; } ovrVector2i;
+typedef struct { int w, h; } ovrSizei;
+typedef struct { ovrVector2i Pos; ovrSizei Size; } ovrRecti;
+typedef struct { float x, y, z, w; } ovrQuatf;
+typedef struct { float x, y; } ovrVector2f;
+typedef struct { float x, y, z; } ovrVector3f;
+typedef struct { float M[4][4]; } ovrMatrix4f;
+
+typedef struct {
+  ovrQuatf Orientation;
+  ovrVector3f Position;
+} ovrPosef;
+
+typedef struct OVR_ALIGNAS(8) {
+  ovrPosef ThePose;
+  ovrVector3f AngularVelocity;
+  ovrVector3f LinearVelocity;
+  ovrVector3f AngularAcceleration;
+  ovrVector3f LinearAcceleration;
+  float       Pad;
+  double      TimeInSeconds;
+} ovrPoseStatef;
+
+typedef struct {
+  float UpTan;
+  float DownTan;
+  float LeftTan;
+  float RightTan;
+} ovrFovPort;
+
+typedef enum {
+  ovrHmd_None             = 0,    
+  ovrHmd_DK1              = 3,
+  ovrHmd_DKHD             = 4,
+  ovrHmd_DK2              = 6,
+  ovrHmd_BlackStar        = 7,
+  ovrHmd_CB               = 8,
+  ovrHmd_Other            = 9,
+  ovrHmd_EnumSize         = 0x7fffffff
+} ovrHmdType;
+
+typedef enum {
+  ovrHmdCap_Present           = 0x0001,
+  ovrHmdCap_Available         = 0x0002,
+  ovrHmdCap_Captured          = 0x0004,
+  ovrHmdCap_ExtendDesktop     = 0x0008,
+  ovrHmdCap_DebugDevice       = 0x0010,
+  ovrHmdCap_DisplayOff        = 0x0040,
+  ovrHmdCap_LowPersistence    = 0x0080,
+  ovrHmdCap_DynamicPrediction = 0x0200,
+  ovrHmdCap_NoVSync           = 0x1000,
+  ovrHmdCap_NoMirrorToWindow  = 0x2000
+} ovrHmdCapBits;
+
+typedef enum
+{
+  ovrTrackingCap_Orientation      = 0x0010,
+  ovrTrackingCap_MagYawCorrection = 0x0020,
+  ovrTrackingCap_Position         = 0x0040,
+  ovrTrackingCap_Idle             = 0x0100,
+  ovrTrackingCap_EnumSize         = 0x7fffffff
+} ovrTrackingCaps;
+
+typedef enum {
+  ovrDistortionCap_Chromatic = 0x01,
+  ovrDistortionCap_TimeWarp  = 0x02,
+  ovrDistortionCap_Vignette  = 0x08,
+  ovrDistortionCap_NoRestore = 0x10,
+  ovrDistortionCap_FlipInput = 0x20,
+  ovrDistortionCap_SRGB      = 0x40,
+  ovrDistortionCap_Overdrive = 0x80,
+  ovrDistortionCap_HqDistortion = 0x100,
+  ovrDistortionCap_LinuxDevFullscreen = 0x200,
+  ovrDistortionCap_ComputeShader = 0x400,
+  ovrDistortionCap_TimewarpJitDelay = 0x1000,
+  ovrDistortionCap_ProfileNoSpinWaits = 0x10000,
+  ovrDistortionCap_EnumSize = 0x7fffffff
+} ovrDistortionCaps;
+
+typedef enum {
+  ovrEye_Left  = 0,
+  ovrEye_Right = 1,
+  ovrEye_Count = 2,
+  ovrEye_EnumSize = 0x7fffffff
+} ovrEyeType;
+
+typedef struct ovrHmdDesc_ {
+  void* Handle;
+  ovrHmdType  Type;
+  const char* ProductName;    
+  const char* Manufacturer;
+  short VendorId;
+  short ProductId;
+  char SerialNumber[24];
+  short FirmwareMajor;
+  short FirmwareMinor;
+  float CameraFrustumHFovInRadians;
+  float CameraFrustumVFovInRadians;
+  float CameraFrustumNearZInMeters;
+  float CameraFrustumFarZInMeters;
+
+  unsigned int HmdCaps;
+  unsigned int TrackingCaps;
+  unsigned int DistortionCaps;
+
+  ovrFovPort  DefaultEyeFov[ovrEye_Count];
+  ovrFovPort  MaxEyeFov[ovrEye_Count];
+  ovrEyeType  EyeRenderOrder[ovrEye_Count];
+
+  ovrSizei    Resolution;
+  ovrVector2i WindowsPos;
+
+  const char* DisplayDeviceName;
+  int         DisplayId;
+} ovrHmdDesc;
+
+typedef const ovrHmdDesc* ovrHmd;
+
+typedef enum {
+  ovrStatus_OrientationTracked    = 0x0001,
+  ovrStatus_PositionTracked       = 0x0002,
+  ovrStatus_CameraPoseTracked     = 0x0004,
+  ovrStatus_PositionConnected     = 0x0020,
+  ovrStatus_HmdConnected          = 0x0080,
+  ovrStatus_EnumSize              = 0x7fffffff
+} ovrStatusBits;
+
+typedef struct ovrSensorData_ {
+  ovrVector3f    Accelerometer;
+  ovrVector3f    Gyro;
+  ovrVector3f    Magnetometer;
+  float          Temperature;
+  float          TimeInSeconds;
+} ovrSensorData;
+
+
+typedef struct ovrTrackingState_ {
+  ovrPoseStatef HeadPose;
+  ovrPosef CameraPose;
+  ovrPosef LeveledCameraPose;
+  ovrSensorData RawSensorData;
+  unsigned int StatusFlags;
+  double LastVisionProcessingTime;
+  uint32_t LastCameraFrameCounter;
+  uint32_t Pad;
+} ovrTrackingState;
+
+typedef struct OVR_ALIGNAS(8) ovrFrameTiming_ {
+  float DeltaSeconds;
+  float Pad; 
+  double ThisFrameSeconds;
+  double TimewarpPointSeconds;
+  double NextFrameSeconds;
+  double ScanoutMidpointSeconds;
+  double EyeScanoutSeconds[2];    
+} ovrFrameTiming;
+
+typedef struct ovrEyeRenderDesc_ {
+  ovrEyeType  Eye;
+  ovrFovPort  Fov;
+  ovrRecti DistortedViewport;
+  ovrVector2f PixelsPerTanAngleAtCenter;
+  ovrVector3f HmdToEyeViewOffset;
+} ovrEyeRenderDesc;
+
+typedef struct ovrDistortionVertex_ {
+  ovrVector2f ScreenPosNDC;
+  float       TimeWarpFactor;
+  float       VignetteFactor;
+  ovrVector2f TanEyeAnglesR;
+  ovrVector2f TanEyeAnglesG;