merge mozilla-inbound to mozilla-central a=merge
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 22 Mar 2016 12:14:15 +0100
changeset 327620 ea6298e1b4f7e22ce2311b2b6a918822f0adb112
parent 327483 3587b25bae302c1eed72968dbd7cef883e715948 (current diff)
parent 327619 f95a0906807236c853a16964bf1cd3945c9bab68 (diff)
child 327631 f18cffdb22774061ccacd733ea401ac2d2364760
child 327667 fa5a9df70ca49ab076458059490fb68e27642c9f
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone48.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 mozilla-inbound to mozilla-central a=merge
layout/reftests/position-sticky/pref-1-disabled-ref.html
layout/reftests/position-sticky/pref-1-enabled-ref.html
layout/reftests/position-sticky/pref-1.html
layout/style/test/file_position_sticky.html
old-configure.in
testing/talos/talos/tests/tabpaint/tabpaint.manifest.develop
testing/web-platform/meta/dom/nodes/rootNode.html.ini
testing/web-platform/meta/html/semantics/selectors/pseudo-classes/focus.html.ini
--- a/Makefile.in
+++ b/Makefile.in
@@ -12,17 +12,17 @@ ifneq ($(make_min_ver),$(firstword $(sor
 endif
 
 export TOPLEVEL_BUILD := 1
 
 default::
 
 ifndef TEST_MOZBUILD
 ifdef MOZ_BUILD_APP
-include $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk
+include $(wildcard $(topsrcdir)/$(MOZ_BUILD_APP)/build.mk)
 endif
 endif
 
 include $(topsrcdir)/config/config.mk
 
 GARBAGE_DIRS += _javagen _profile staticlib
 DIST_GARBAGE = config.cache config.log config.status* config-defs.h \
    config/autoconf.mk \
--- a/accessible/base/TextAttrs.cpp
+++ b/accessible/base/TextAttrs.cpp
@@ -455,18 +455,18 @@ TextAttrsMgr::FontFamilyTextAttr::
 {
   nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::font_family, aValue);
 }
 
 bool
 TextAttrsMgr::FontFamilyTextAttr::
   GetFontFamily(nsIFrame* aFrame, nsString& aFamily)
 {
-  RefPtr<nsFontMetrics> fm;
-  nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
+  RefPtr<nsFontMetrics> fm =
+    nsLayoutUtils::GetFontMetricsForFrame(aFrame, 1.0f);
 
   gfxFontGroup* fontGroup = fm->GetThebesFontGroup();
   gfxFont* font = fontGroup->GetFirstValidFont();
   gfxFontEntry* fontEntry = font->GetFontEntry();
   aFamily = fontEntry->FamilyName();
   return true;
 }
 
@@ -613,18 +613,18 @@ TextAttrsMgr::FontWeightTextAttr::
 }
 
 int32_t
 TextAttrsMgr::FontWeightTextAttr::
   GetFontWeight(nsIFrame* aFrame)
 {
   // nsFont::width isn't suitable here because it's necessary to expose real
   // value of font weight (used font might not have some font weight values).
-  RefPtr<nsFontMetrics> fm;
-  nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
+  RefPtr<nsFontMetrics> fm =
+    nsLayoutUtils::GetFontMetricsForFrame(aFrame, 1.0f);
 
   gfxFontGroup *fontGroup = fm->GetThebesFontGroup();
   gfxFont *font = fontGroup->GetFirstValidFont();
 
   // When there doesn't exist a bold font in the family and so the rendering of
   // a non-bold font face is changed so that the user sees what looks like a
   // bold font, i.e. synthetic bolding is used. IsSyntheticBold method is only
   // needed on Mac, but it is "safe" to use on all platforms.  (For non-Mac
--- a/accessible/windows/sdn/sdnTextAccessible.cpp
+++ b/accessible/windows/sdn/sdnTextAccessible.cpp
@@ -174,18 +174,18 @@ sdnTextAccessible::get_fontFamily(BSTR _
 
   if (mAccessible->IsDefunct())
     return CO_E_OBJNOTCONNECTED;
 
   nsIFrame* frame = mAccessible->GetFrame();
   if (!frame)
     return E_FAIL;
 
-  RefPtr<nsFontMetrics> fm;
-  nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm));
+  RefPtr<nsFontMetrics> fm =
+    nsLayoutUtils::GetFontMetricsForFrame(frame, 1.0f);
 
   const nsString& name =
     fm->GetThebesFontGroup()->GetFirstValidFont()->GetName();
   if (name.IsEmpty())
     return S_FALSE;
 
   *aFontFamily = ::SysAllocStringLen(name.get(), name.Length());
   return *aFontFamily ? S_OK : E_OUTOFMEMORY;
--- a/browser/extensions/e10srollout/bootstrap.js
+++ b/browser/extensions/e10srollout/bootstrap.js
@@ -51,17 +51,18 @@ function defineCohort() {
   let updateChannel = UpdateUtils.getUpdateChannel(false);
   if (!(updateChannel in TEST_THRESHOLD)) {
     setCohort("unsupportedChannel");
     return;
   }
 
   let userOptedOut = optedOut();
   let userOptedIn = optedIn();
-  let disqualified = (Services.appinfo.multiprocessBlockPolicy != 0);
+  let disqualified = (Services.appinfo.multiprocessBlockPolicy != 0) ||
+                     isThereAnActiveExperiment();
   let testGroup = (getUserSample() < TEST_THRESHOLD[updateChannel]);
 
   if (userOptedOut) {
     setCohort("optedOut");
   } else if (userOptedIn) {
     setCohort("optedIn");
   } else if (disqualified) {
     setCohort("disqualified");
@@ -107,8 +108,12 @@ function optedOut() {
   // Users can also opt-out by toggling back the pref to false.
   // If they reset the pref instead they might be re-enabled if
   // they are still part of the threshold.
   return Preferences.get(PREF_E10S_FORCE_DISABLED, false) ||
          (Preferences.isSet(PREF_TOGGLE_E10S) &&
           Preferences.get(PREF_TOGGLE_E10S) == false);
 }
 
+function isThereAnActiveExperiment() {
+  let { Experiments } = Cu.import("resource:///modules/experiments/Experiments.jsm", {});
+  return (Experiments.instance().getActiveExperimentID() !== null);
+}
--- a/build/autoconf/ffi.m4
+++ b/build/autoconf/ffi.m4
@@ -18,17 +18,17 @@ if test -n "$MOZ_SYSTEM_FFI"; then
     fi
 fi
 
 AC_SUBST(MOZ_SYSTEM_FFI)
 
 ])
 
 AC_DEFUN([MOZ_SUBCONFIGURE_FFI], [
-if test -z "$BUILDING_JS" -o -n "$JS_STANDALONE"; then
+if test "$MOZ_BUILD_APP" != js -o -n "$JS_STANDALONE"; then
 
   if test "$BUILD_CTYPES" -a -z "$MOZ_SYSTEM_FFI"; then
     # Run the libffi 'configure' script.
     ac_configure_args="--disable-shared --enable-static --disable-raw-api"
     if test "$MOZ_DEBUG"; then
       ac_configure_args="$ac_configure_args --enable-debug"
     fi
     if test "$DSO_PIC_CFLAGS"; then
--- a/build/autoconf/icu.m4
+++ b/build/autoconf/icu.m4
@@ -123,17 +123,17 @@ if test -n "$USE_ICU" -a -z "$MOZ_SYSTEM
     AC_DEFINE(U_USING_ICU_NAMESPACE,0)
 fi
 
 
 ])
 
 AC_DEFUN([MOZ_SUBCONFIGURE_ICU], [
 
-if test -z "$BUILDING_JS" -o -n "$JS_STANDALONE"; then
+if test "$MOZ_BUILD_APP" != js -o -n "$JS_STANDALONE"; then
 
     if test -n "$USE_ICU" -a -z "$MOZ_SYSTEM_ICU"; then
         # Set ICU compile options
         ICU_CPPFLAGS=""
         # don't use icu namespace automatically in client code
         ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_USING_ICU_NAMESPACE=0"
         # don't include obsolete header files
         ICU_CPPFLAGS="$ICU_CPPFLAGS -DU_NO_DEFAULT_INCLUDE_UTF_HEADERS=1"
--- a/build/autoconf/jemalloc.m4
+++ b/build/autoconf/jemalloc.m4
@@ -1,15 +1,15 @@
 dnl This Source Code Form is subject to the terms of the Mozilla Public
 dnl License, v. 2.0. If a copy of the MPL was not distributed with this
 dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 AC_DEFUN([MOZ_SUBCONFIGURE_JEMALLOC], [
 
-if test -z "$BUILDING_JS" -o -n "$JS_STANDALONE"; then
+if test "$MOZ_BUILD_APP" != js -o -n "$JS_STANDALONE"; then
 
   # Run jemalloc configure script
 
   if test -z "$MOZ_SYSTEM_JEMALLOC" -a "$MOZ_MEMORY" && test -n "$MOZ_JEMALLOC4" -o -n "$MOZ_REPLACE_MALLOC"; then
     ac_configure_args="--build=$build --host=$target --enable-stats --with-jemalloc-prefix=je_ --disable-valgrind"
     # We're using memalign for _aligned_malloc in memory/build/mozmemory_wrap.c
     # on Windows, so just export memalign on all platforms.
     ac_configure_args="$ac_configure_args ac_cv_func_memalign=yes"
--- a/build/autoconf/nspr-build.m4
+++ b/build/autoconf/nspr-build.m4
@@ -3,21 +3,21 @@ dnl License, v. 2.0. If a copy of the MP
 dnl file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 AC_DEFUN([MOZ_CONFIG_NSPR], [
 
 ifelse([$1],,define(CONFIGURING_JS,yes))
 
 dnl Possible ways this can be called:
 dnl   from toplevel configure:
-dnl     JS_STANDALONE=  BUILDING_JS=
+dnl     JS_STANDALONE=  MOZ_BUILD_APP!=js
 dnl   from js/src/configure invoked by toplevel configure:
-dnl     JS_STANDALONE=  BUILDING_JS=1
+dnl     JS_STANDALONE=  MOZ_BUILD_APP=js
 dnl   from standalone js/src/configure:
-dnl     JS_STANDALONE=1 BUILDING_JS=1
+dnl     JS_STANDALONE=1 MOZ_BUILD_APP=js
 
 dnl ========================================================
 dnl = Find the right NSPR to use.
 dnl ========================================================
 MOZ_ARG_WITH_STRING(nspr-cflags,
 [  --with-nspr-cflags=FLAGS
                           Pass FLAGS to CC when building code that uses NSPR.
                           Use this when there's no accurate nspr-config
@@ -33,17 +33,17 @@ MOZ_ARG_WITH_STRING(nspr-libs,
 
 ifdef([CONFIGURING_JS],[
     MOZ_ARG_ENABLE_BOOL(nspr-build,
 [  --enable-nspr-build     Build NSPR from source tree],
         MOZ_BUILD_NSPR=1,
         MOZ_BUILD_NSPR=)
 ])
 
-if test -z "$BUILDING_JS" || test -n "$JS_STANDALONE"; then
+if test "$MOZ_BUILD_APP" != js || test -n "$JS_STANDALONE"; then
   _IS_OUTER_CONFIGURE=1
 fi
 
 MOZ_ARG_WITH_BOOL(system-nspr,
 [  --with-system-nspr      Use an NSPR that is already built and installed.
                           Use the 'nspr-config' script in the current path,
                           or look for the script in the directories given with
                           --with-nspr-exec-prefix or --with-nspr-prefix.
@@ -94,17 +94,17 @@ fi
 if test "$JS_POSIX_NSPR" = unset; then
     JS_POSIX_NSPR=
 else
     nspr_opts="x$nspr_opts"
     which_nspr="posix-wrapper"
 fi
 
 if test -z "$nspr_opts"; then
-    if test -z "$BUILDING_JS"; then
+    if test "$MOZ_BUILD_APP" != js; then
       dnl Toplevel configure defaults to using nsprpub from the source tree
       MOZ_BUILD_NSPR=1
       which_nspr="source-tree"
     else
       dnl JS configure defaults to emulated NSPR if available, falling back
       dnl to nsprpub.
       JS_POSIX_NSPR="$JS_POSIX_NSPR_DEFAULT"
       if test -z "$JS_POSIX_NSPR"; then
@@ -119,17 +119,17 @@ fi
 if test -z "$nspr_opts" || test "$nspr_opts" = x; then
     AC_MSG_RESULT($which_nspr)
 else
     AC_MSG_ERROR([only one way of using NSPR may be selected. See 'configure --help'.])
 fi
 
 AC_SUBST(MOZ_BUILD_NSPR)
 
-if test -n "$BUILDING_JS"; then
+if test "$MOZ_BUILD_APP" = js; then
   if test "$JS_POSIX_NSPR" = 1; then
     AC_DEFINE(JS_POSIX_NSPR)
   fi
   AC_SUBST(JS_POSIX_NSPR)
 fi
 
 # A (sub)configure invoked by the toplevel configure will always receive
 # --with-nspr-libs on the command line. It will never need to figure out
--- a/build/moz.configure/init.configure
+++ b/build/moz.configure/init.configure
@@ -250,16 +250,17 @@ def wanted_mozconfig_variables(help):
          'AUTOCONF',
          'AWK',
          'DISABLE_EXPORT_JS',
          'DISABLE_SHARED_JS',
          'DOXYGEN',
          'DSYMUTIL',
          'EXTERNAL_SOURCE_DIR',
          'GENISOIMAGE',
+         'JS_STANDALONE',
          'L10NBASEDIR',
          'MOZILLABUILD',
          'MOZ_ARTIFACT_BUILDS',
          'MOZ_BUILD_APP',
          'MOZ_CALLGRIND',
          'MOZ_DMD',
          'MOZ_FMP4',
          'MOZ_INSTRUMENT_EVENT_LOOP',
@@ -271,16 +272,17 @@ def wanted_mozconfig_variables(help):
          'MOZTTDIR',
          'PERL',
          'RPMBUILD',
          'TAR',
          'UNZIP',
          'USE_FC_FREETYPE',
          'WITHOUT_X',
          'XARGS',
+         'YASM',
          'ZIP',
      ])
 
 
 @depends(mozconfig, wanted_mozconfig_variables, '--help')
 def mozconfig_options(mozconfig, wanted_mozconfig_variables, help):
     if mozconfig['path']:
         helper = command_line_helper()
@@ -509,16 +511,36 @@ def host_variables(host):
     if host.kernel == 'kFreeBSD':
         os_arch = 'GNU_kFreeBSD'
     else:
         os_arch = host.kernel
     add_old_configure_assignment('HOST_OS_ARCH', os_arch)
     set_config('HOST_OS_ARCH', os_arch)
 
 
+@depends(target)
+def target_platform_defines(target):
+    if target.kernel == 'WINNT':
+        set_define('_WINDOWS', '1')
+        set_define('WIN32', '1')
+        set_define('XP_WIN', '1')
+        set_define('XP_WIN32', '1')
+    else:
+        set_define('XP_UNIX', '1')
+
+    if target.kernel == 'Darwin':
+        set_define('XP_DARWIN', '1')
+        if target.os == 'iOS':
+            set_define('XP_IOS', '1')
+        elif target.os == 'OSX':
+            set_define('XP_MACOSX', '1')
+    elif target.kernel == 'Linux':
+        set_define('XP_LINUX', '1')
+
+
 # The application/project to build
 # ==============================================================
 option('--enable-application', nargs=1, env='MOZ_BUILD_APP',
        help='Application to build. Same as --enable-project.')
 
 @depends('--enable-application', '--help')
 def application(app, help):
     if app:
@@ -554,16 +576,18 @@ def include_project_configure(project, e
     if not os.path.exists(path):
         error('Cannot find project %s' % project[0])
     return path
 
 @depends(include_project_configure, check_build_environment, '--help')
 def build_project(include_project_configure, build_env, help):
     ret = os.path.dirname(os.path.relpath(include_project_configure,
                                           build_env['TOPSRCDIR']))
+    set_config('MOZ_BUILD_APP', ret)
+    set_define('MOZ_BUILD_APP', ret)
     add_old_configure_assignment('MOZ_BUILD_APP', ret)
     return ret
 
 
 # set RELEASE_BUILD and NIGHTLY_BUILD variables depending on the cycle we're in
 # The logic works like this:
 # - if we have "a1" in GRE_MILESTONE, we're building Nightly (define NIGHTLY_BUILD)
 # - otherwise, if we have "a" in GRE_MILESTONE, we're building Nightly or Aurora
--- a/build/subconfigure.py
+++ b/build/subconfigure.py
@@ -309,16 +309,17 @@ def run(objdir):
             # environment, we lose the benefits from our own efforts in this
             # script to get past the msys problems. So manually call the python
             # script instead, so that we don't do a native->msys transition
             # here. Then the python configure will still have the right
             # environment when calling the shell configure.
             command = [
                 sys.executable,
                 os.path.join(os.path.dirname(__file__), '..', 'configure.py'),
+                '--enable-project=js',
             ]
             data['env']['OLD_CONFIGURE'] = os.path.join(
                 os.path.dirname(configure), 'old-configure')
         else:
             command = [data['shell'], configure]
         for kind in ('target', 'build', 'host'):
             if data.get(kind) is not None:
                 command += ['--%s=%s' % (kind, data[kind])]
--- a/config/config.mk
+++ b/config/config.mk
@@ -133,17 +133,17 @@ TOUCH ?= touch
 PYTHON_PATH = $(PYTHON) $(topsrcdir)/config/pythonpath.py
 
 # determine debug-related options
 _DEBUG_ASFLAGS :=
 _DEBUG_CFLAGS :=
 _DEBUG_LDFLAGS :=
 
 ifneq (,$(MOZ_DEBUG)$(MOZ_DEBUG_SYMBOLS))
-  ifeq ($(AS),yasm)
+  ifeq ($(AS),$(YASM))
     ifeq ($(OS_ARCH)_$(GNU_CC),WINNT_)
       _DEBUG_ASFLAGS += -g cv8
     else
       ifneq ($(OS_ARCH),Darwin)
         _DEBUG_ASFLAGS += -g dwarf2
       endif
     endif
   else
--- a/configure.py
+++ b/configure.py
@@ -53,28 +53,28 @@ def config_status(config):
         fh.write('true, false, null = True, False, None\n')
         for k, v in sanitized_config.iteritems():
             fh.write('%s = ' % k)
             json.dump(v, fh, sort_keys=True, indent=4, ensure_ascii=False)
             fh.write('\n')
         fh.write("__all__ = ['topobjdir', 'topsrcdir', 'defines', "
                  "'non_global_defines', 'substs']")
 
-        if not config.get('BUILDING_JS') or config.get('JS_STANDALONE'):
+        if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'):
             fh.write('''
 if __name__ == '__main__':
     args = dict([(name, globals()[name]) for name in __all__])
     from mozbuild.config_status import config_status
     config_status(**args)
 ''')
 
     # Other things than us are going to run this file, so we need to give it
     # executable permissions.
     os.chmod('config.status', 0755)
-    if not config.get('BUILDING_JS') or config.get('JS_STANDALONE'):
+    if config.get('MOZ_BUILD_APP') != 'js' or config.get('JS_STANDALONE'):
         if not config.get('JS_STANDALONE'):
             os.environ['WRITE_MOZINFO'] = '1'
         # Until we have access to the virtualenv from this script, execute
         # config.status externally, with the virtualenv python.
         return subprocess.call([config['PYTHON'], 'config.status'])
     return 0
 
 
--- a/devtools/server/actors/animation.js
+++ b/devtools/server/actors/animation.js
@@ -617,32 +617,50 @@ var AnimationsActor = exports.Animations
         // actually removed from the node (e.g. css class removed) or when they
         // are finished and don't have forwards animation-fill-mode.
         // In the latter case, we don't send an event, because the corresponding
         // animation can still be seeked/resumed, so we want the client to keep
         // its reference to the AnimationPlayerActor.
         if (player.playState !== "idle") {
           continue;
         }
+        // FIXME: In bug 1249219, we support the animation mutation for pseudo
+        // elements. However, the timeline may not be ready yet to
+        // display those correctly. Therefore, we add this check to bails out if
+        // the mutation target is a pseudo-element.
+        // Note. Only CSSPseudoElement object has |type| attribute, so if type
+        // exists, it is a CSSPseudoElement object.
+        if (player.effect.target.type) {
+          continue;
+        }
         let index = this.actors.findIndex(a => a.player === player);
         if (index !== -1) {
           eventData.push({
             type: "removed",
             player: this.actors[index]
           });
           this.actors.splice(index, 1);
         }
       }
 
       for (let player of addedAnimations) {
         // If the added player already exists, it means we previously filtered
         // it out when it was reported as removed. So filter it out here too.
         if (this.actors.find(a => a.player === player)) {
           continue;
         }
+        // FIXME: In bug 1249219, we support the animation mutation for pseudo
+        // elements. However, the timeline may not be ready yet to
+        // display those correctly. Therefore, we add this check to bails out if
+        // the mutation target is a pseudo-element.
+        // Note. Only CSSPseudoElement object has |type| attribute, so if type
+        // exists, it is a CSSPseudoElement object.
+        if (player.effect.target.type) {
+          continue;
+        }
         // If the added player has the same name and target node as a player we
         // already have, it means it's a transition that's re-starting. So send
         // a "removed" event for the one we already have.
         let index = this.actors.findIndex(a => {
           let isSameType = a.player.constructor === player.constructor;
           let isSameName = (a.isCssAnimation() &&
                             a.player.animationName === player.animationName) ||
                            (a.isCssTransition() &&
--- a/dom/animation/Animation.cpp
+++ b/dom/animation/Animation.cpp
@@ -6,16 +6,17 @@
 
 #include "Animation.h"
 #include "AnimationUtils.h"
 #include "mozilla/dom/AnimationBinding.h"
 #include "mozilla/dom/AnimationPlaybackEvent.h"
 #include "mozilla/AutoRestore.h"
 #include "mozilla/AsyncEventDispatcher.h" // For AsyncEventDispatcher
 #include "mozilla/Maybe.h" // For Maybe
+#include "mozilla/NonOwningAnimationTarget.h"
 #include "nsAnimationManager.h" // For CSSAnimation
 #include "nsDOMMutationObserver.h" // For nsAutoAnimationMutationBatch
 #include "nsIDocument.h" // For nsIDocument
 #include "nsIPresShell.h" // For nsIPresShell
 #include "nsLayoutUtils.h" // For PostRestyleEvent (remove after bug 1073336)
 #include "nsThreadUtils.h" // For nsRunnableMethod and nsRevocableEventPtr
 #include "nsTransitionManager.h" // For CSSTransition
 #include "PendingAnimationTracker.h" // For PendingAnimationTracker
@@ -53,23 +54,24 @@ Animation::WrapObject(JSContext* aCx, JS
 namespace {
   // A wrapper around nsAutoAnimationMutationBatch that looks up the
   // appropriate document from the supplied animation.
   class MOZ_RAII AutoMutationBatchForAnimation {
   public:
     explicit AutoMutationBatchForAnimation(const Animation& aAnimation
                                            MOZ_GUARD_OBJECT_NOTIFIER_PARAM) {
       MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-      Element* targetElement = nsNodeUtils::GetTargetForAnimation(&aAnimation);
-      if (!targetElement) {
+      Maybe<NonOwningAnimationTarget> target =
+        nsNodeUtils::GetTargetForAnimation(&aAnimation);
+      if (!target) {
         return;
       }
 
       // For mutation observers, we use the OwnerDoc.
-      nsIDocument* doc = targetElement->OwnerDoc();
+      nsIDocument* doc = target->mElement->OwnerDoc();
       if (!doc) {
         return;
       }
 
       mAutoBatch.emplace(doc);
     }
 
   private:
@@ -1101,26 +1103,24 @@ Animation::FlushStyle() const
 void
 Animation::PostUpdate()
 {
   nsPresContext* presContext = GetPresContext();
   if (!presContext) {
     return;
   }
 
-  Element* targetElement;
-  CSSPseudoElementType targetPseudoType;
-  mEffect->GetTarget(targetElement, targetPseudoType);
-  if (!targetElement) {
+  Maybe<NonOwningAnimationTarget> target = mEffect->GetTarget();
+  if (!target) {
     return;
   }
 
   presContext->EffectCompositor()
-             ->RequestRestyle(targetElement,
-                              targetPseudoType,
+             ->RequestRestyle(target->mElement,
+                              target->mPseudoType,
                               EffectCompositor::RestyleType::Layer,
                               CascadeLevel());
 }
 
 void
 Animation::CancelPendingTasks()
 {
   if (mPendingState == PendingState::NotPending) {
--- a/dom/animation/AnimationUtils.cpp
+++ b/dom/animation/AnimationUtils.cpp
@@ -1,25 +1,22 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "AnimationUtils.h"
 
-#include "nsCSSParser.h" // For nsCSSParser
 #include "nsDebug.h"
 #include "nsIAtom.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsGlobalWindow.h"
 #include "nsString.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/ComputedTimingFunction.h" // ComputedTimingFunction
 #include "xpcpublic.h" // For xpc::NativeGlobal
 
 namespace mozilla {
 
 /* static */ void
 AnimationUtils::LogAsyncAnimationFailure(nsCString& aMessage,
                                          const nsIContent* aContent)
 {
@@ -34,74 +31,16 @@ AnimationUtils::LogAsyncAnimationFailure
       aMessage.Append('\'');
     }
     aMessage.Append(']');
   }
   aMessage.Append('\n');
   printf_stderr("%s", aMessage.get());
 }
 
-/* static */ Maybe<ComputedTimingFunction>
-AnimationUtils::ParseEasing(const nsAString& aEasing,
-                            nsIDocument* aDocument)
-{
-  MOZ_ASSERT(aDocument);
-
-  nsCSSValue value;
-  nsCSSParser parser;
-  parser.ParseLonghandProperty(eCSSProperty_animation_timing_function,
-                               aEasing,
-                               aDocument->GetDocumentURI(),
-                               aDocument->GetDocumentURI(),
-                               aDocument->NodePrincipal(),
-                               value);
-
-  switch (value.GetUnit()) {
-    case eCSSUnit_List: {
-      const nsCSSValueList* list = value.GetListValue();
-      if (list->mNext) {
-        // don't support a list of timing functions
-        break;
-      }
-      switch (list->mValue.GetUnit()) {
-        case eCSSUnit_Enumerated:
-          // Return Nothing() if "linear" is passed in.
-          if (list->mValue.GetIntValue() ==
-              NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR) {
-            return Nothing();
-          }
-          MOZ_FALLTHROUGH;
-        case eCSSUnit_Cubic_Bezier:
-        case eCSSUnit_Steps: {
-          nsTimingFunction timingFunction;
-          nsRuleNode::ComputeTimingFunction(list->mValue, timingFunction);
-          ComputedTimingFunction computedTimingFunction;
-          computedTimingFunction.Init(timingFunction);
-          return Some(computedTimingFunction);
-        }
-        default:
-          MOZ_ASSERT_UNREACHABLE("unexpected animation-timing-function list "
-                                 "item unit");
-        break;
-      }
-      break;
-    }
-    case eCSSUnit_Null:
-    case eCSSUnit_Inherit:
-    case eCSSUnit_Initial:
-    case eCSSUnit_Unset:
-    case eCSSUnit_TokenStream:
-      break;
-    default:
-      MOZ_ASSERT_UNREACHABLE("unexpected animation-timing-function unit");
-      break;
-  }
-  return Nothing();
-}
-
 /* static */ nsIDocument*
 AnimationUtils::GetCurrentRealmDocument(JSContext* aCx)
 {
   nsGlobalWindow* win = xpc::CurrentWindowOrNull(aCx);
   if (!win) {
     return nullptr;
   }
   return win->GetDoc();
--- a/dom/animation/EffectCompositor.cpp
+++ b/dom/animation/EffectCompositor.cpp
@@ -14,17 +14,16 @@
 #include "mozilla/EffectSet.h"
 #include "mozilla/InitializerList.h"
 #include "mozilla/LayerAnimationInfo.h"
 #include "mozilla/RestyleManagerHandle.h"
 #include "mozilla/RestyleManagerHandleInlines.h"
 #include "nsComputedDOMStyle.h" // nsComputedDOMStyle::GetPresShellForContent
 #include "nsCSSPropertySet.h"
 #include "nsCSSProps.h"
-#include "nsCSSPseudoElements.h"
 #include "nsIPresShell.h"
 #include "nsLayoutUtils.h"
 #include "nsRuleNode.h" // For nsRuleNode::ComputePropertiesOverridingAnimation
 #include "nsRuleProcessorData.h" // For ElementRuleProcessorData etc.
 #include "nsTArray.h"
 
 using mozilla::dom::Animation;
 using mozilla::dom::Element;
@@ -78,21 +77,21 @@ FindAnimationsForCompositor(const nsIFra
 
   // The animation cascade will almost always be up-to-date by this point
   // but there are some cases such as when we are restoring the refresh driver
   // from test control after seeking where it might not be the case.
   //
   // Those cases are probably not important but just to be safe, let's make
   // sure the cascade is up to date since if it *is* up to date, this is
   // basically a no-op.
-  Maybe<Pair<dom::Element*, CSSPseudoElementType>> pseudoElement =
+  Maybe<NonOwningAnimationTarget> pseudoElement =
     EffectCompositor::GetAnimationElementAndPseudoForFrame(aFrame);
   if (pseudoElement) {
-    EffectCompositor::MaybeUpdateCascadeResults(pseudoElement->first(),
-                                                pseudoElement->second(),
+    EffectCompositor::MaybeUpdateCascadeResults(pseudoElement->mElement,
+                                                pseudoElement->mPseudoType,
                                                 aFrame->StyleContext());
   }
 
   if (!nsLayoutUtils::AreAsyncAnimationsEnabled()) {
     if (nsLayoutUtils::IsAnimationLoggingEnabled()) {
       nsCString message;
       message.AppendLiteral("Performance warning: Async animations are "
                             "disabled");
@@ -145,17 +144,17 @@ EffectCompositor::RequestRestyle(dom::El
                                  CascadeLevel aCascadeLevel)
 {
   if (!mPresContext) {
     // Pres context will be null after the effect compositor is disconnected.
     return;
   }
 
   auto& elementsToRestyle = mElementsToRestyle[aCascadeLevel];
-  PseudoElementHashKey key = { aElement, aPseudoType };
+  PseudoElementHashEntry::KeyType key = { aElement, aPseudoType };
 
   if (aRestyleType == RestyleType::Throttled) {
     if (!elementsToRestyle.Contains(key)) {
       elementsToRestyle.Put(key, false);
     }
     mPresContext->Document()->SetNeedStyleFlush();
   } else {
     // Get() returns 0 if the element is not found. It will also return
@@ -227,17 +226,17 @@ EffectCompositor::MaybeUpdateAnimationRu
                                            CSSPseudoElementType aPseudoType,
                                            CascadeLevel aCascadeLevel)
 {
   // First update cascade results since that may cause some elements to
   // be marked as needing a restyle.
   MaybeUpdateCascadeResults(aElement, aPseudoType);
 
   auto& elementsToRestyle = mElementsToRestyle[aCascadeLevel];
-  PseudoElementHashKey key = { aElement, aPseudoType };
+  PseudoElementHashEntry::KeyType key = { aElement, aPseudoType };
 
   if (!mPresContext || !elementsToRestyle.Contains(key)) {
     return;
   }
 
   ComposeAnimationRule(aElement, aPseudoType, aCascadeLevel,
                        mPresContext->RefreshDriver()->MostRecentRefresh());
 
@@ -273,17 +272,17 @@ EffectCompositor::GetAnimationRule(dom::
     return nullptr;
   }
 
   MaybeUpdateAnimationRule(aElement, aPseudoType, aCascadeLevel);
 
 #ifdef DEBUG
   {
     auto& elementsToRestyle = mElementsToRestyle[aCascadeLevel];
-    PseudoElementHashKey key = { aElement, aPseudoType };
+    PseudoElementHashEntry::KeyType key = { aElement, aPseudoType };
     MOZ_ASSERT(!elementsToRestyle.Contains(key),
                "Element should no longer require a restyle after its "
                "animation rule has been updated");
   }
 #endif
 
   EffectSet* effectSet = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (!effectSet) {
@@ -359,17 +358,18 @@ EffectCompositor::AddStyleUpdatesTo(Rest
     auto& elementSet = mElementsToRestyle[cascadeLevel];
 
     // Copy the list of elements to restyle to a separate array that we can
     // iterate over. This is because we need to call MaybeUpdateCascadeResults
     // on each element, but doing that can mutate elementSet. In this case
     // it will only mutate the bool value associated with each element in the
     // set but even doing that will cause assertions in PLDHashTable to fail
     // if we are iterating over the hashtable at the same time.
-    nsTArray<PseudoElementHashKey> elementsToRestyle(elementSet.Count());
+    nsTArray<PseudoElementHashEntry::KeyType> elementsToRestyle(
+      elementSet.Count());
     for (auto iter = elementSet.Iter(); !iter.Done(); iter.Next()) {
       elementsToRestyle.AppendElement(iter.Key());
     }
 
     for (auto& pseudoElem : elementsToRestyle) {
       MaybeUpdateCascadeResults(pseudoElem.mElement, pseudoElem.mPseudoType);
 
       ComposeAnimationRule(pseudoElem.mElement,
@@ -492,21 +492,21 @@ EffectCompositor::UpdateCascadeResults(E
   EffectSet* effects = EffectSet::GetEffectSet(aElement, aPseudoType);
   if (!effects) {
     return;
   }
 
   UpdateCascadeResults(*effects, aElement, aPseudoType, aStyleContext);
 }
 
-/* static */ Maybe<Pair<Element*, CSSPseudoElementType>>
+/* static */ Maybe<NonOwningAnimationTarget>
 EffectCompositor::GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame)
 {
   // Always return the same object to benefit from return-value optimization.
-  Maybe<Pair<Element*, CSSPseudoElementType>> result;
+  Maybe<NonOwningAnimationTarget> result;
 
   nsIContent* content = aFrame->GetContent();
   if (!content) {
     return result;
   }
 
   CSSPseudoElementType pseudoType = CSSPseudoElementType::NotPseudo;
 
@@ -533,17 +533,17 @@ EffectCompositor::GetAnimationElementAnd
       return result;
     }
   }
 
   if (!content->IsElement()) {
     return result;
   }
 
-  result = Some(MakePair(content->AsElement(), pseudoType));
+  result.emplace(content->AsElement(), pseudoType);
 
   return result;
 }
 
 /* static */ void
 EffectCompositor::ComposeAnimationRule(dom::Element* aElement,
                                        CSSPseudoElementType aPseudoType,
                                        CascadeLevel aCascadeLevel,
--- a/dom/animation/EffectCompositor.h
+++ b/dom/animation/EffectCompositor.h
@@ -5,17 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_EffectCompositor_h
 #define mozilla_EffectCompositor_h
 
 #include "mozilla/EnumeratedArray.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/OwningNonNull.h"
-#include "mozilla/Pair.h"
+#include "mozilla/NonOwningAnimationTarget.h"
 #include "mozilla/PseudoElementHashEntry.h"
 #include "mozilla/RefPtr.h"
 #include "nsCSSProperty.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsDataHashtable.h"
 #include "nsIStyleRuleProcessor.h"
 #include "nsTArray.h"
 
@@ -24,17 +24,16 @@ class nsIFrame;
 class nsIStyleRule;
 class nsPresContext;
 class nsStyleContext;
 
 namespace mozilla {
 
 class EffectSet;
 class RestyleTracker;
-enum class CSSPseudoElementType : uint8_t;
 struct AnimationPerformanceWarning;
 
 namespace dom {
 class Animation;
 class Element;
 }
 
 class EffectCompositor
@@ -180,17 +179,17 @@ public:
   //
   // For frames corresponding to pseudo-elements, the returned element is the
   // element on which we store the animations (i.e. the EffectSet and/or
   // AnimationCollection), *not* the generated content.
   //
   // Returns an empty result when a suitable element cannot be found including
   // when the frame represents a pseudo-element on which we do not support
   // animations.
-  static Maybe<Pair<dom::Element*, CSSPseudoElementType>>
+  static Maybe<NonOwningAnimationTarget>
   GetAnimationElementAndPseudoForFrame(const nsIFrame* aFrame);
 
   // Associates a performance warning with effects on |aFrame| that animates
   // |aProperty|.
   static void SetPerformanceWarning(
     const nsIFrame* aFrame,
     nsCSSProperty aProperty,
     const AnimationPerformanceWarning& aWarning);
--- a/dom/animation/KeyframeEffect.cpp
+++ b/dom/animation/KeyframeEffect.cpp
@@ -1287,20 +1287,23 @@ GenerateValueEntries(Element* aTarget,
                      nsTArray<KeyframeValueEntry>& aResult,
                      ErrorResult& aRv)
 {
   nsCSSPropertySet properties;              // All properties encountered.
   nsCSSPropertySet propertiesWithFromValue; // Those with a defined 0% value.
   nsCSSPropertySet propertiesWithToValue;   // Those with a defined 100% value.
 
   for (OffsetIndexedKeyframe& keyframe : aKeyframes) {
+    Maybe<ComputedTimingFunction> easing =
+      TimingParams::ParseEasing(keyframe.mKeyframeDict.mEasing,
+                                aTarget->OwnerDoc(), aRv);
+    if (aRv.Failed()) {
+      return;
+    }
     float offset = float(keyframe.mKeyframeDict.mOffset.Value());
-    Maybe<ComputedTimingFunction> easing =
-      AnimationUtils::ParseEasing(keyframe.mKeyframeDict.mEasing,
-                                  aTarget->OwnerDoc());
     // We ignore keyframe.mKeyframeDict.mComposite since we don't support
     // composite modes on keyframes yet.
 
     // keyframe.mPropertyValuePairs is currently sorted by CSS property IDL
     // name, since that was the order we read the properties from the JS
     // object.  Re-sort the list so that longhand properties appear before
     // shorthands, and with shorthands all appearing in increasing order of
     // number of components.  For two longhand properties, or two shorthands
@@ -1555,17 +1558,17 @@ BuildAnimationPropertyListFromPropertyIn
   binding_detail::FastPropertyIndexedKeyframes keyframes;
   if (!keyframes.Init(aCx, aValue, "PropertyIndexedKeyframes argument",
                       false)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   Maybe<ComputedTimingFunction> easing =
-    AnimationUtils::ParseEasing(keyframes.mEasing, aTarget->OwnerDoc());
+    TimingParams::ParseEasing(keyframes.mEasing, aTarget->OwnerDoc(), aRv);
 
   // We ignore easing.mComposite since we don't support composite modes on
   // keyframes yet.
 
   // Get all the property--value-list pairs off the object.
   JS::Rooted<JSObject*> object(aCx, &aValue.toObject());
   nsTArray<PropertyValuesPair> propertyValuesPairs;
   if (!GetPropertyValuesPairs(aCx, object, ListAllowance::eAllow,
@@ -2313,25 +2316,18 @@ KeyframeEffect::Constructor(
     ErrorResult& aRv)
 {
   return ConstructKeyframeEffect<KeyframeEffect>(aGlobal, aTarget, aFrames,
                                                  aOptions, aRv);
 }
 
 void KeyframeEffect::NotifySpecifiedTimingUpdated()
 {
-  nsIDocument* doc = nullptr;
-  // Bug 1249219:
-  // We don't support animation mutation observers on pseudo-elements yet.
-  if (mTarget &&
-      mPseudoType == CSSPseudoElementType::NotPseudo) {
-    doc = mTarget->OwnerDoc();
-  }
-
-  nsAutoAnimationMutationBatch mb(doc);
+  // Use the same document for a pseudo element and its parent element.
+  nsAutoAnimationMutationBatch mb(mTarget->OwnerDoc());
 
   if (mAnimation) {
     mAnimation->NotifyEffectTimingUpdated();
 
     if (mAnimation->IsRelevant()) {
       nsNodeUtils::AnimationChanged(mAnimation);
     }
 
--- a/dom/animation/KeyframeEffect.h
+++ b/dom/animation/KeyframeEffect.h
@@ -10,16 +10,17 @@
 #include "nsAutoPtr.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIDocument.h"
 #include "nsWrapperCache.h"
 #include "mozilla/AnimationPerformanceWarning.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/ComputedTimingFunction.h" // ComputedTimingFunction
 #include "mozilla/LayerAnimationInfo.h"     // LayerAnimations::kRecords
+#include "mozilla/NonOwningAnimationTarget.h"
 #include "mozilla/OwningNonNull.h"          // OwningNonNull<...>
 #include "mozilla/StickyTimeDuration.h"
 #include "mozilla/StyleAnimationValue.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/TimingParams.h"
 #include "mozilla/dom/AnimationEffectReadOnly.h"
 #include "mozilla/dom/AnimationEffectTimingReadOnly.h"
 #include "mozilla/dom/Element.h"
@@ -201,30 +202,30 @@ public:
   static already_AddRefed<KeyframeEffectReadOnly>
   Constructor(const GlobalObject& aGlobal,
               const Nullable<ElementOrCSSPseudoElement>& aTarget,
               JS::Handle<JSObject*> aFrames,
               const UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
               ErrorResult& aRv);
 
   void GetTarget(Nullable<OwningElementOrCSSPseudoElement>& aRv) const;
+  Maybe<NonOwningAnimationTarget> GetTarget() const
+  {
+    Maybe<NonOwningAnimationTarget> result;
+    if (mTarget) {
+      result.emplace(mTarget, mPseudoType);
+    }
+    return result;
+  }
   void GetFrames(JSContext*& aCx,
                  nsTArray<JSObject*>& aResult,
                  ErrorResult& aRv);
   void GetProperties(nsTArray<AnimationPropertyDetails>& aProperties,
                      ErrorResult& aRv) const;
 
-  // Temporary workaround to return both the target element and pseudo-type
-  // until we implement PseudoElement (bug 1174575).
-  void GetTarget(Element*& aTarget,
-                 CSSPseudoElementType& aPseudoType) const {
-    aTarget = mTarget;
-    aPseudoType = mPseudoType;
-  }
-
   IterationCompositeOperation IterationComposite() const;
   CompositeOperation Composite() const;
   void GetSpacing(nsString& aRetVal) const {
     aRetVal.AssignLiteral("distribute");
   }
 
   already_AddRefed<AnimationEffectTimingReadOnly> Timing() const override;
 
new file mode 100644
--- /dev/null
+++ b/dom/animation/NonOwningAnimationTarget.h
@@ -0,0 +1,32 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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_NonOwningAnimationTarget_h
+#define mozilla_NonOwningAnimationTarget_h
+
+#include "mozilla/Attributes.h"   // For MOZ_NON_OWNING_REF
+#include "nsCSSPseudoElements.h"
+
+namespace mozilla {
+
+namespace dom {
+class Element;
+} // namespace dom
+
+struct NonOwningAnimationTarget
+{
+  NonOwningAnimationTarget(dom::Element* aElement, CSSPseudoElementType aType)
+    : mElement(aElement), mPseudoType(aType) { }
+
+  // mElement represents the parent element of a pseudo-element, not the
+  // generated content element.
+  dom::Element* MOZ_NON_OWNING_REF mElement = nullptr;
+  CSSPseudoElementType mPseudoType = CSSPseudoElementType::NotPseudo;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_NonOwningAnimationTarget_h
--- a/dom/animation/PseudoElementHashEntry.h
+++ b/dom/animation/PseudoElementHashEntry.h
@@ -4,43 +4,36 @@
  * 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_PseudoElementHashEntry_h
 #define mozilla_PseudoElementHashEntry_h
 
 #include "mozilla/dom/Element.h"
 #include "mozilla/HashFunctions.h"
+#include "mozilla/NonOwningAnimationTarget.h"
 #include "PLDHashTable.h"
 
 namespace mozilla {
 
-enum class CSSPseudoElementType : uint8_t;
-
-struct PseudoElementHashKey
-{
-  dom::Element* mElement;
-  CSSPseudoElementType mPseudoType;
-};
-
 // A hash entry that uses a RefPtr<dom::Element>, CSSPseudoElementType pair
 class PseudoElementHashEntry : public PLDHashEntryHdr
 {
 public:
-  typedef PseudoElementHashKey KeyType;
-  typedef const PseudoElementHashKey* KeyTypePointer;
+  typedef NonOwningAnimationTarget KeyType;
+  typedef const NonOwningAnimationTarget* KeyTypePointer;
 
   explicit PseudoElementHashEntry(KeyTypePointer aKey)
     : mElement(aKey->mElement)
     , mPseudoType(aKey->mPseudoType) { }
   explicit PseudoElementHashEntry(const PseudoElementHashEntry& aCopy)=default;
 
   ~PseudoElementHashEntry() = default;
 
-  KeyType GetKey() const { return {mElement, mPseudoType}; }
+  KeyType GetKey() const { return { mElement, mPseudoType }; }
   bool KeyEquals(KeyTypePointer aKey) const
   {
     return mElement == aKey->mElement &&
            mPseudoType == aKey->mPseudoType;
   }
 
   static KeyTypePointer KeyToPointer(KeyType& aKey) { return &aKey; }
   static PLDHashNumber HashKey(KeyTypePointer aKey)
--- a/dom/animation/TimingParams.cpp
+++ b/dom/animation/TimingParams.cpp
@@ -1,16 +1,17 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 "mozilla/TimingParams.h"
 
+#include "nsCSSParser.h" // For nsCSSParser
 #include "nsIDocument.h"
 
 namespace mozilla {
 
 template <class OptionsType>
 static const dom::AnimationEffectTimingProperties&
 GetTimingProperties(const OptionsType& aOptions);
 
@@ -55,25 +56,34 @@ TimingParamsFromOptionsUnion(const Optio
       TimingParams::ParseDuration(timing.mDuration, aRv);
     if (aRv.Failed()) {
       return result;
     }
     TimingParams::ValidateIterationStart(timing.mIterationStart, aRv);
     if (aRv.Failed()) {
       return result;
     }
+    TimingParams::ValidateIterations(timing.mIterations, aRv);
+    if (aRv.Failed()) {
+      return result;
+    }
+    Maybe<ComputedTimingFunction> easing =
+      TimingParams::ParseEasing(timing.mEasing, aDocument, aRv);
+    if (aRv.Failed()) {
+      return result;
+    }
 
     result.mDuration = duration;
     result.mDelay = TimeDuration::FromMilliseconds(timing.mDelay);
     result.mEndDelay = TimeDuration::FromMilliseconds(timing.mEndDelay);
     result.mIterations = timing.mIterations;
     result.mIterationStart = timing.mIterationStart;
     result.mDirection = timing.mDirection;
     result.mFill = timing.mFill;
-    result.mFunction = AnimationUtils::ParseEasing(timing.mEasing, aDocument);
+    result.mFunction = easing;
   }
   return result;
 }
 
 /* static */ TimingParams
 TimingParams::FromOptionsUnion(
   const dom::UnrestrictedDoubleOrKeyframeEffectOptions& aOptions,
   nsIDocument* aDocument,
@@ -86,16 +96,76 @@ TimingParams::FromOptionsUnion(
 TimingParams::FromOptionsUnion(
   const dom::UnrestrictedDoubleOrKeyframeAnimationOptions& aOptions,
   nsIDocument* aDocument,
   ErrorResult& aRv)
 {
   return TimingParamsFromOptionsUnion(aOptions, aDocument, aRv);
 }
 
+/* static */ Maybe<ComputedTimingFunction>
+TimingParams::ParseEasing(const nsAString& aEasing,
+                          nsIDocument* aDocument,
+                          ErrorResult& aRv)
+{
+  MOZ_ASSERT(aDocument);
+
+  nsCSSValue value;
+  nsCSSParser parser;
+  parser.ParseLonghandProperty(eCSSProperty_animation_timing_function,
+                               aEasing,
+                               aDocument->GetDocumentURI(),
+                               aDocument->GetDocumentURI(),
+                               aDocument->NodePrincipal(),
+                               value);
+
+  switch (value.GetUnit()) {
+    case eCSSUnit_List: {
+      const nsCSSValueList* list = value.GetListValue();
+      if (list->mNext) {
+        // don't support a list of timing functions
+        break;
+      }
+      switch (list->mValue.GetUnit()) {
+        case eCSSUnit_Enumerated:
+          // Return Nothing() if "linear" is passed in.
+          if (list->mValue.GetIntValue() ==
+              NS_STYLE_TRANSITION_TIMING_FUNCTION_LINEAR) {
+            return Nothing();
+          }
+          MOZ_FALLTHROUGH;
+        case eCSSUnit_Cubic_Bezier:
+        case eCSSUnit_Steps: {
+          nsTimingFunction timingFunction;
+          nsRuleNode::ComputeTimingFunction(list->mValue, timingFunction);
+          ComputedTimingFunction computedTimingFunction;
+          computedTimingFunction.Init(timingFunction);
+          return Some(computedTimingFunction);
+        }
+        default:
+          MOZ_ASSERT_UNREACHABLE("unexpected animation-timing-function list "
+                                 "item unit");
+        break;
+      }
+      break;
+    }
+    case eCSSUnit_Inherit:
+    case eCSSUnit_Initial:
+    case eCSSUnit_Unset:
+    case eCSSUnit_TokenStream:
+    case eCSSUnit_Null:
+      break;
+    default:
+      MOZ_ASSERT_UNREACHABLE("unexpected animation-timing-function unit");
+      break;
+  }
+  aRv.ThrowTypeError<dom::MSG_INVALID_EASING_ERROR>();
+  return Nothing();
+}
+
 bool
 TimingParams::operator==(const TimingParams& aOther) const
 {
   return mDuration == aOther.mDuration &&
          mDelay == aOther.mDelay &&
          mIterations == aOther.mIterations &&
          mIterationStart == aOther.mIterationStart &&
          mDirection == aOther.mDirection &&
--- a/dom/animation/TimingParams.h
+++ b/dom/animation/TimingParams.h
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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_TimingParams_h
 #define mozilla_TimingParams_h
 
+#include "nsStringFwd.h"
 #include "mozilla/dom/Nullable.h"
 #include "mozilla/dom/UnionTypes.h" // For OwningUnrestrictedDoubleOrString
 #include "mozilla/ComputedTimingFunction.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/TimeStamp.h" // for TimeDuration
 
 // X11 has a #define for None
 #ifdef None
@@ -48,33 +49,47 @@ struct TimingParams
   static Maybe<StickyTimeDuration> ParseDuration(DoubleOrString& aDuration,
                                                  ErrorResult& aRv)
   {
     Maybe<StickyTimeDuration> result;
     if (aDuration.IsUnrestrictedDouble()) {
       double durationInMs = aDuration.GetAsUnrestrictedDouble();
       if (durationInMs >= 0) {
         result.emplace(StickyTimeDuration::FromMilliseconds(durationInMs));
-        return result;
+      } else {
+        aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>(
+          NS_LITERAL_STRING("duration"));
       }
-    } else if (aDuration.GetAsString().EqualsLiteral("auto")) {
-      return result;
+    } else if (!aDuration.GetAsString().EqualsLiteral("auto")) {
+      aRv.ThrowTypeError<dom::MSG_INVALID_DURATION_ERROR>();
     }
-    aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
     return result;
   }
 
   static void ValidateIterationStart(double aIterationStart,
                                      ErrorResult& aRv)
   {
     if (aIterationStart < 0) {
-      aRv.Throw(NS_ERROR_DOM_TYPE_ERR);
+      aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>(
+        NS_LITERAL_STRING("iterationStart"));
     }
   }
 
+  static void ValidateIterations(double aIterations, ErrorResult& aRv)
+  {
+    if (IsNaN(aIterations) || aIterations < 0) {
+      aRv.ThrowTypeError<dom::MSG_ENFORCE_RANGE_OUT_OF_RANGE>(
+        NS_LITERAL_STRING("iterations"));
+    }
+  }
+
+  static Maybe<ComputedTimingFunction> ParseEasing(const nsAString& aEasing,
+                                                   nsIDocument* aDocument,
+                                                   ErrorResult& aRv);
+
   // mDuration.isNothing() represents the "auto" value
   Maybe<StickyTimeDuration> mDuration;
   TimeDuration mDelay;      // Initializes to zero
   TimeDuration mEndDelay;
   double mIterations = 1.0; // Can be NaN, negative, +/-Infinity
   double mIterationStart = 0.0;
   dom::PlaybackDirection mDirection = dom::PlaybackDirection::Normal;
   dom::FillMode mFill = dom::FillMode::Auto;
--- a/dom/animation/moz.build
+++ b/dom/animation/moz.build
@@ -21,16 +21,17 @@ EXPORTS.mozilla.dom += [
 EXPORTS.mozilla += [
     'AnimationComparator.h',
     'AnimationPerformanceWarning.h',
     'AnimationUtils.h',
     'AnimValuesStyleRule.h',
     'ComputedTimingFunction.h',
     'EffectCompositor.h',
     'EffectSet.h',
+    'NonOwningAnimationTarget.h',
     'PendingAnimationTracker.h',
     'PseudoElementHashEntry.h',
     'TimingParams.h',
 ]
 
 UNIFIED_SOURCES += [
     'Animation.cpp',
     'AnimationEffectReadOnly.cpp',
--- a/dom/animation/test/chrome/test_animation_observers.html
+++ b/dom/animation/test/chrome/test_animation_observers.html
@@ -9,29 +9,37 @@
   to { transform: translate(100px); }
 }
 #target {
   width: 100px;
   height: 100px;
   background-color: yellow;
   line-height: 16px;
 }
+.init::before {
+  content: "";
+  animation: anim 100s;
+}
 </style>
 <div id=container><div id=target></div></div>
 <script>
 var div = document.getElementById("target");
 var gRecords = [];
 var gRecordPromiseResolvers = [];
 var gObserver = new MutationObserver(function(newRecords) {
   gRecords.push(...newRecords);
 
   var resolvers = gRecordPromiseResolvers;
   gRecordPromiseResolvers = [];
   resolvers.forEach(fn => fn());
 });
+// Get the pseudo element target.
+div.classList.add("init");
+var pseudoTarget = document.getAnimations()[0].effect.target;
+div.classList.remove("init");
 
 // Asynchronous testing framework based on layout/style/test/animation_utils.js.
 
 var gTests = [];
 var gCurrentTestName;
 
 function addAsyncAnimTest(aName, aOptions, aTestGenerator) {
   aTestGenerator.testName = aName;
@@ -156,18 +164,18 @@ function assert_records(expected, desc) 
     assert_record_list(records[i].addedAnimations, expected[i].added, desc, i, "addedAnimations");
     assert_record_list(records[i].changedAnimations, expected[i].changed, desc, i, "changedAnimations");
     assert_record_list(records[i].removedAnimations, expected[i].removed, desc, i, "removedAnimations");
   }
 }
 
 // -- Tests ------------------------------------------------------------------
 
-// We run all tests first targetting the div and observing the div, then again
-// targetting the div and observing its parent while using the subtree:true
+// We run all tests first targeting the div and observing the div, then again
+// targeting the div and observing its parent while using the subtree:true
 // MutationObserver option.
 
 [
   { observe: div,            target: div, subtree: false },
   { observe: div.parentNode, target: div, subtree: true  },
 ].forEach(function(aOptions) {
 
   var e = aOptions.target;
@@ -1386,139 +1394,184 @@ function assert_records(expected, desc) 
     yield await_frame();
     assert_records([], "records after attempted animation start");
 
     e.style = "";
   });
 });
 
 addAsyncAnimTest("tree_ordering", { observe: div, subtree: true }, function*() {
+  // Add style for pseudo elements
+  var extraStyle = document.createElement('style');
+  document.head.appendChild(extraStyle);
+  var sheet = extraStyle.sheet;
+  var rules = { ".before::before": "animation: anim 100s;",
+                ".after::after"  : "animation: anim 100s, anim 100s;" };
+  for (var selector in rules) {
+    sheet.insertRule(selector + '{' + rules[selector] + '}',
+                     sheet.cssRules.length);
+  }
 
   // Create a tree with two children:
   //
-  //         div
-  //        /  \
-  //   childA  childB
+  //          div
+  //       (::before)
+  //       (::after)
+  //        /     \
+  //   childA      childB(::before)
   var childA = document.createElement("div");
   var childB = document.createElement("div");
 
   div.appendChild(childA);
   div.appendChild(childB);
 
   // Start an animation on each (using order: childB, div, childA)
   //
   // We include multiple animations on some nodes so that we can test batching
   // works as expected later in this test.
   childB.style = "animation: anim 100s";
   div.style    = "animation: anim 100s, anim 100s, anim 100s";
   childA.style = "animation: anim 100s, anim 100s";
 
+  // Start animations targeting to pseudo element of div and childB.
+  childB.classList.add("before");
+  div.classList.add("after");
+  div.classList.add("before");
+
+  // Check all animations we have in this document
+  var docAnims = document.getAnimations();
+  is(docAnims.length, 10, "total animations");
+
   var divAnimations = div.getAnimations();
   var childAAnimations = childA.getAnimations();
   var childBAnimations = childB.getAnimations();
+  var divBeforeAnimations =
+    [ for (x of docAnims) if (x.effect.target.parentElement == div &&
+                              x.effect.target.type == "::before") x ];
+  var divAfterAnimations =
+    [ for (x of docAnims) if (x.effect.target.parentElement == div &&
+                              x.effect.target.type == "::after") x ];
+  var childBPseudoAnimations =
+    [ for (x of docAnims) if (x.effect.target.parentElement == childB) x ];
 
   // The order in which we get the corresponding records is currently
   // based on the order we visit these nodes when updating styles.
   //
   // That is because we don't do any document-level batching of animation
   // mutation records when we flush styles. We may introduce that in the
   // future but for now all we are interested in testing here is that the order
   // these records are dispatched is consistent between runs.
   //
-  // We currently expect to get records in order childA, childB, div
+  // We currently expect to get records in order div::after, childA, childB,
+  // childB::before, div, div::before
   yield await_frame();
-  assert_records([{ added: childAAnimations, changed: [], removed: [] },
+  assert_records([{ added: divAfterAnimations, changed: [], removed: [] },
+                  { added: childAAnimations, changed: [], removed: [] },
                   { added: childBAnimations, changed: [], removed: [] },
-                  { added: divAnimations, changed: [], removed: [] }],
+                  { added: childBPseudoAnimations, changed: [], removed: [] },
+                  { added: divAnimations, changed: [], removed: [] },
+                  { added: divBeforeAnimations, changed: [], removed: [] }],
                  "records after simultaneous animation start");
 
   // The one case where we *do* currently perform document-level (or actually
   // timeline-level) batching is when animations are updated from a refresh
   // driver tick. In particular, this means that when animations finish
   // naturally the removed records should be dispatched according to the
   // position of the elements in the tree.
-  //
 
-  // First, flatten the set of animations.
-  var animations = [ divAnimations,
-                     childAAnimations,
-                     childBAnimations ].reduce(
-    (a, b) => a.concat(b), []
-  );
+  // First, flatten the set of animations. we put the animations targeting to
+  // pseudo elements last. (Actually, we don't care the order in the list.)
+  var animations = [ ...divAnimations,
+                     ...childAAnimations,
+                     ...childBAnimations,
+                     ...divBeforeAnimations,
+                     ...divAfterAnimations,
+                     ...childBPseudoAnimations ];
 
   // Fast-forward to *just* before the end of the animation.
   animations.forEach(animation => animation.currentTime = 99999);
 
   // Prepare the set of expected change MutationRecords, one for each
   // animation that was seeked.
   var seekRecords = animations.map(
     p => ({ added: [], changed: [p], removed: [] })
   );
 
   yield await_event(div, "animationend");
 
   // After the changed notifications, which will be dispatched in the order that
   // the animations were seeked, we should get removal MutationRecords in order
-  // div, childA, childB
+  // (div, div::before, div::after), childA, (childB, childB::before).
+  // Note: The animations targeting to the pseudo element are appended after
+  //       the animations of its parent element.
+  divAnimations = [ ...divAnimations,
+                    ...divBeforeAnimations,
+                    ...divAfterAnimations ];
+  childBAnimations = [ ...childBAnimations, ...childBPseudoAnimations ];
   assert_records(seekRecords.concat(
                    { added: [], changed: [], removed: divAnimations },
                    { added: [], changed: [], removed: childAAnimations },
                    { added: [], changed: [], removed: childBAnimations }),
                  "records after finishing");
 
   // Clean up
+  div.classList.remove("before");
+  div.classList.remove("after");
   div.style = "";
   childA.remove();
   childB.remove();
+  extraStyle.remove();
 });
 
+[ div, pseudoTarget ].forEach(function(target) {
+  addAsyncAnimTest("change_duration_and_currenttime",
+                   { observe: div, subtree: true }, function*() {
+    var anim = target.animate({ opacity: [ 0, 1 ] }, 100000);
 
-addAsyncAnimTest("change_duration_and_currenttime",
-                 { observe: div, subtree: true }, function*() {
-  var anim = div.animate({ opacity: [ 0, 1 ] }, 100000);
-  yield await_frame();
-  assert_records([{ added: [anim], changed: [], removed: [] }],
-                 "records after animation is added");
+    yield await_frame();
+    assert_records([{ added: [anim], changed: [], removed: [] }],
+                   "records after animation is added");
 
-  anim.effect.timing.duration = 10000;
-  yield await_frame();
+    anim.effect.timing.duration = 10000;
+    yield await_frame();
+    assert_records([{ added: [], changed: [anim], removed: [] }],
+                   "records after duration is changed");
 
-  assert_records([{ added: [], changed: [anim], removed: [] }],
-                 "records after duration is changed");
-
-  anim.effect.timing.duration = 10000;
-  yield await_frame();
-  assert_records([], "records after assigning same value");
+    anim.effect.timing.duration = 10000;
+    yield await_frame();
+    assert_records([], "records after assigning same value");
 
-  anim.currentTime = 50000;
-  yield await_frame();
-  assert_records([{ added: [], changed: [], removed: [anim] }],
-                 "records after animation end");
+    anim.currentTime = 50000;
+    yield await_frame();
+    assert_records([{ added: [], changed: [], removed: [anim] }],
+                   "records after animation end");
 
-  anim.effect.timing.duration = 100000;
-  yield await_frame();
-  assert_records([{ added: [anim], changed: [], removed: [] }],
-                 "records after animation restarted");
+    anim.effect.timing.duration = 100000;
+    yield await_frame();
+    assert_records([{ added: [anim], changed: [], removed: [] }],
+                   "records after animation restarted");
 
-  anim.effect.timing.duration = "auto";
-  yield await_frame();
-  assert_records([{ added: [], changed: [], removed: [anim] }],
-                 "records after duration set \"auto\"");
+    anim.effect.timing.duration = "auto";
+    yield await_frame();
+    assert_records([{ added: [], changed: [], removed: [anim] }],
+                   "records after duration set \"auto\"");
 
-  anim.effect.timing.duration = "auto";
-  yield await_frame();
-  assert_records([], "records after assigning same value \"auto\"");
+    anim.effect.timing.duration = "auto";
+    yield await_frame();
+    assert_records([], "records after assigning same value \"auto\"");
 
-  anim.cancel();
-  yield await_frame();
+    anim.cancel();
+    yield await_frame();
+  });
 });
 
 addAsyncAnimTest("change_enddelay_and_currenttime",
                  { observe: div, subtree: true }, function*() {
   var anim = div.animate({ opacity: [ 0, 1 ] }, { duration: 100000 });
+
   yield await_frame();
   assert_records([{ added: [anim], changed: [], removed: [] }],
                  "records after animation is added");
 
   anim.effect.timing.endDelay = 10000;
   yield await_frame();
   assert_records([{ added: [], changed: [anim], removed: [] }],
                  "records after endDelay is changed");
@@ -1543,16 +1596,32 @@ addAsyncAnimTest("change_enddelay_and_cu
 addAsyncAnimTest("change_enddelay_and_currenttime",
                  { observe: div, subtree: true }, function*() {
   var anim = div.animate({ opacity: [ 0, 1 ] },
                          { duration: 100, endDelay: -100 });
   yield await_frame();
   assert_records([], "records after animation is added");
 });
 
+addAsyncAnimTest("exclude_animations_targeting_pseudo_elements",
+                 { observe: div, subtree: false }, function*() {
+  var anim = div.animate({ opacity: [ 0, 1 ] }, { duration: 100000 });
+  var pAnim = pseudoTarget.animate({ opacity: [ 0, 1 ] }, { duration: 100000 });
+
+  yield await_frame();
+  assert_records([{ added: [anim], changed: [], removed: [] }],
+                 "records after animation is added");
+
+  anim.finish();
+  pAnim.finish();
+  yield await_frame();
+  assert_records([{ added: [], changed: [], removed: [anim] }],
+                 "records after animation is finished");
+});
+
 // Run the tests.
 SimpleTest.requestLongerTimeout(2);
 SimpleTest.waitForExplicitFinish();
 
 runAllAsyncTests().then(function() {
   SimpleTest.finish();
 }, function(aError) {
   ok(false, "Something failed: " + aError);
--- a/dom/base/nsDOMMutationObserver.cpp
+++ b/dom/base/nsDOMMutationObserver.cpp
@@ -383,54 +383,56 @@ void
 nsAnimationReceiver::RecordAnimationMutation(Animation* aAnimation,
                                              AnimationMutation aMutationType)
 {
   mozilla::dom::KeyframeEffectReadOnly* effect = aAnimation->GetEffect();
   if (!effect) {
     return;
   }
 
-  mozilla::dom::Element* animationTarget;
-  CSSPseudoElementType pseudoType;
-  effect->GetTarget(animationTarget, pseudoType);
+  Maybe<NonOwningAnimationTarget> animationTarget = effect->GetTarget();
   if (!animationTarget) {
     return;
   }
 
-  if (!Animations() || !(Subtree() || animationTarget == Target()) ||
-      animationTarget->ChromeOnlyAccess()) {
+  dom::Element* elem = animationTarget->mElement;
+  if (!Animations() || !(Subtree() || elem == Target()) ||
+      elem->ChromeOnlyAccess()) {
+    return;
+  }
+
+  // Record animations targeting to a pseudo element only when subtree is true.
+  if (animationTarget->mPseudoType != CSSPseudoElementType::NotPseudo &&
+      !Subtree()) {
     return;
   }
 
   if (nsAutoAnimationMutationBatch::IsBatching()) {
     switch (aMutationType) {
       case eAnimationMutation_Added:
-        nsAutoAnimationMutationBatch::AnimationAdded(aAnimation,
-                                                     animationTarget);
+        nsAutoAnimationMutationBatch::AnimationAdded(aAnimation, elem);
         break;
       case eAnimationMutation_Changed:
-        nsAutoAnimationMutationBatch::AnimationChanged(aAnimation,
-                                                       animationTarget);
+        nsAutoAnimationMutationBatch::AnimationChanged(aAnimation, elem);
         break;
       case eAnimationMutation_Removed:
-        nsAutoAnimationMutationBatch::AnimationRemoved(aAnimation,
-                                                       animationTarget);
+        nsAutoAnimationMutationBatch::AnimationRemoved(aAnimation, elem);
         break;
     }
 
     nsAutoAnimationMutationBatch::AddObserver(Observer());
     return;
   }
 
   nsDOMMutationRecord* m =
     Observer()->CurrentRecord(nsGkAtoms::animations);
 
   NS_ASSERTION(!m->mTarget, "Wrong target!");
 
-  m->mTarget = animationTarget;
+  m->mTarget = elem;
 
   switch (aMutationType) {
     case eAnimationMutation_Added:
       m->mAddedAnimations.AppendElement(aAnimation);
       break;
     case eAnimationMutation_Changed:
       m->mChangedAnimations.AppendElement(aAnimation);
       break;
--- a/dom/base/nsDOMMutationObserver.h
+++ b/dom/base/nsDOMMutationObserver.h
@@ -906,16 +906,18 @@ private:
     bool mChanged;
   };
 
   static nsAutoAnimationMutationBatch* sCurrentBatch;
   AutoTArray<nsDOMMutationObserver*, 2> mObservers;
   typedef nsTArray<Entry> EntryArray;
   nsClassHashtable<nsPtrHashKey<nsINode>, EntryArray> mEntryTable;
   // List of nodes referred to by mEntryTable so we can sort them
+  // For a specific pseudo element, we use its parent element as the
+  // batch target, so they will be put in the same EntryArray.
   nsTArray<nsINode*> mBatchTargets;
 };
 
 inline
 nsDOMMutationObserver*
 nsMutationReceiverBase::Observer()
 {
   return mParent ?
--- a/dom/base/nsINode.h
+++ b/dom/base/nsINode.h
@@ -938,16 +938,21 @@ public:
 
   /**
    * Get the root of the subtree this node belongs to.  This never returns
    * null.  It may return 'this' (e.g. for document nodes, and nodes that
    * are the roots of disconnected subtrees).
    */
   nsINode* SubtreeRoot() const;
 
+  nsINode* RootNode() const
+  {
+    return SubtreeRoot();
+  }
+
   /**
    * See nsIDOMEventTarget
    */
   NS_DECL_NSIDOMEVENTTARGET
 
   virtual mozilla::EventListenerManager*
     GetExistingListenerManager() const override;
   virtual mozilla::EventListenerManager*
--- a/dom/base/nsMimeTypeArray.cpp
+++ b/dom/base/nsMimeTypeArray.cpp
@@ -114,60 +114,17 @@ nsMimeTypeArray::NamedGetter(const nsASt
   ToLowerCase(lowerName);
 
   nsMimeType* mimeType = FindMimeType(mMimeTypes, lowerName);
   if (mimeType) {
     aFound = true;
     return mimeType;
   }
 
-  // Now let's check with the MIME service.
-  nsCOMPtr<nsIMIMEService> mimeSrv = do_GetService("@mozilla.org/mime;1");
-  if (!mimeSrv) {
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIMIMEInfo> mimeInfo;
-  mimeSrv->GetFromTypeAndExtension(NS_ConvertUTF16toUTF8(lowerName),
-                                   EmptyCString(), getter_AddRefs(mimeInfo));
-  if (!mimeInfo) {
-    return nullptr;
-  }
-
-  // Now we check whether we can really claim to support this type
-  nsHandlerInfoAction action = nsIHandlerInfo::saveToDisk;
-  mimeInfo->GetPreferredAction(&action);
-  if (action != nsIMIMEInfo::handleInternally) {
-    bool hasHelper = false;
-    mimeInfo->GetHasDefaultHandler(&hasHelper);
-
-    if (!hasHelper) {
-      nsCOMPtr<nsIHandlerApp> helper;
-      mimeInfo->GetPreferredApplicationHandler(getter_AddRefs(helper));
-
-      if (!helper) {
-        // mime info from the OS may not have a PreferredApplicationHandler
-        // so just check for an empty default description
-        nsAutoString defaultDescription;
-        mimeInfo->GetDefaultDescription(defaultDescription);
-
-        if (defaultDescription.IsEmpty()) {
-          // no support; just leave
-          return nullptr;
-        }
-      }
-    }
-  }
-
-  // If we got here, we support this type!  Say so.
-  aFound = true;
-
-  nsMimeType *mt = new nsMimeType(mWindow, lowerName);
-  mMimeTypes.AppendElement(mt);
-  return mt;
+  return nullptr;
 }
 
 bool
 nsMimeTypeArray::NameIsEnumerable(const nsAString& aName)
 {
   return true;
 }
 
@@ -223,23 +180,17 @@ nsMimeType::nsMimeType(nsPIDOMWindowInne
                        const nsAString& aDescription,
                        const nsAString& aExtension)
   : mWindow(aWindow),
     mPluginElement(aPluginElement),
     mType(aType),
     mDescription(aDescription),
     mExtension(aExtension)
 {
-}
-
-nsMimeType::nsMimeType(nsPIDOMWindowInner* aWindow, const nsAString& aType)
-  : mWindow(aWindow),
-    mPluginElement(nullptr),
-    mType(aType)
-{
+  MOZ_ASSERT(aPluginElement);
 }
 
 nsMimeType::~nsMimeType()
 {
 }
 
 nsPIDOMWindowInner*
 nsMimeType::GetParentObject() const
@@ -258,16 +209,18 @@ void
 nsMimeType::GetDescription(nsString& aRetval) const
 {
   aRetval = mDescription;
 }
 
 nsPluginElement*
 nsMimeType::GetEnabledPlugin() const
 {
+  // mPluginElement might be null if we got unlinked but are still somehow being
+  // called into.
   if (!mPluginElement || !mPluginElement->PluginTag()->IsEnabled()) {
     return nullptr;
   }
   return mPluginElement;
 }
 
 void
 nsMimeType::GetSuffixes(nsString& aRetval) const
--- a/dom/base/nsMimeTypeArray.h
+++ b/dom/base/nsMimeTypeArray.h
@@ -58,17 +58,16 @@ public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(nsMimeType)
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsMimeType)
 
   nsMimeType(nsPIDOMWindowInner* aWindow,
              nsPluginElement* aPluginElement,
              const nsAString& aType,
              const nsAString& aDescription,
              const nsAString& aExtension);
-  nsMimeType(nsPIDOMWindowInner* aWindow, const nsAString& aMimeType);
   nsPIDOMWindowInner* GetParentObject() const;
   virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
 
   const nsString& Type() const
   {
     return mType;
   }
 
@@ -78,19 +77,18 @@ public:
   void GetSuffixes(nsString& retval) const;
   void GetType(nsString& retval) const;
 
 protected:
   virtual ~nsMimeType();
 
   nsCOMPtr<nsPIDOMWindowInner> mWindow;
 
-  // Strong reference to the active plugin, if any. Note that this
-  // creates an explicit reference cycle through the plugin element's
-  // mimetype array. We rely on the cycle collector to break this
-  // cycle.
+  // Strong reference to the active plugin. Note that this creates an explicit
+  // reference cycle through the plugin element's mimetype array. We rely on the
+  // cycle collector to break this cycle.
   RefPtr<nsPluginElement> mPluginElement;
   nsString mType;
   nsString mDescription;
   nsString mExtension;
 };
 
 #endif /* nsMimeTypeArray_h___ */
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -222,78 +222,69 @@ nsNodeUtils::ContentRemoved(nsINode* aCo
     document = static_cast<nsIDocument*>(aContainer);
   }
 
   IMPL_MUTATION_NOTIFICATION(ContentRemoved, aContainer,
                              (document, container, aChild, aIndexInContainer,
                               aPreviousSibling));
 }
 
-Element*
+Maybe<NonOwningAnimationTarget>
 nsNodeUtils::GetTargetForAnimation(const Animation* aAnimation)
 {
   KeyframeEffectReadOnly* effect = aAnimation->GetEffect();
-  if (!effect) {
-    return nullptr;
+  return effect ? effect->GetTarget() : Nothing();
+}
+
+void
+nsNodeUtils::AnimationMutated(Animation* aAnimation,
+                              AnimationMutationType aMutatedType)
+{
+  Maybe<NonOwningAnimationTarget> target = GetTargetForAnimation(aAnimation);
+  if (!target) {
+    return;
   }
 
-  Element* target;
-  CSSPseudoElementType pseudoType;
-  effect->GetTarget(target, pseudoType);
-
-  // If the animation targets a pseudo-element, we don't dispatch
-  // notifications for it.  (In the future we will have PseudoElement
-  // objects we can use as the target of the notifications.)
-  if (pseudoType != CSSPseudoElementType::NotPseudo) {
-    return nullptr;
+  // A pseudo element and its parent element use the same owner doc.
+  nsIDocument* doc = target->mElement->OwnerDoc();
+  if (doc->MayHaveAnimationObservers()) {
+    // we use the its parent element as the subject in DOM Mutation Observer.
+    Element* elem = target->mElement;
+    switch (aMutatedType) {
+      case AnimationMutationType::Added:
+        IMPL_ANIMATION_NOTIFICATION(AnimationAdded, elem, (aAnimation));
+        break;
+      case AnimationMutationType::Changed:
+        IMPL_ANIMATION_NOTIFICATION(AnimationChanged, elem, (aAnimation));
+        break;
+      case AnimationMutationType::Removed:
+        IMPL_ANIMATION_NOTIFICATION(AnimationRemoved, elem, (aAnimation));
+        break;
+      default:
+        MOZ_ASSERT_UNREACHABLE("unexpected mutation type");
+    }
   }
-
-  return target;
 }
 
 void
 nsNodeUtils::AnimationAdded(Animation* aAnimation)
 {
-  Element* target = GetTargetForAnimation(aAnimation);
-  if (!target) {
-    return;
-  }
-  nsIDocument* doc = target->OwnerDoc();
-
-  if (doc->MayHaveAnimationObservers()) {
-    IMPL_ANIMATION_NOTIFICATION(AnimationAdded, target, (aAnimation));
-  }
+  AnimationMutated(aAnimation, AnimationMutationType::Added);
 }
 
 void
 nsNodeUtils::AnimationChanged(Animation* aAnimation)
 {
-  Element* target = GetTargetForAnimation(aAnimation);
-  if (!target) {
-    return;
-  }
-  nsIDocument* doc = target->OwnerDoc();
-
-  if (doc->MayHaveAnimationObservers()) {
-    IMPL_ANIMATION_NOTIFICATION(AnimationChanged, target, (aAnimation));
-  }
+  AnimationMutated(aAnimation, AnimationMutationType::Changed);
 }
 
 void
 nsNodeUtils::AnimationRemoved(Animation* aAnimation)
 {
-  Element* target = GetTargetForAnimation(aAnimation);
-  if (!target) {
-    return;
-  }
-  nsIDocument* doc = target->OwnerDoc();
-
-  if (doc->MayHaveAnimationObservers()) {
-    IMPL_ANIMATION_NOTIFICATION(AnimationRemoved, target, (aAnimation));
-  }
+  AnimationMutated(aAnimation, AnimationMutationType::Removed);
 }
 
 void
 nsNodeUtils::LastRelease(nsINode* aNode)
 {
   nsINode::nsSlots* slots = aNode->GetExistingSlots();
   if (slots) {
     if (!slots->mMutationObservers.IsEmpty()) {
--- a/dom/base/nsNodeUtils.h
+++ b/dom/base/nsNodeUtils.h
@@ -2,16 +2,18 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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 nsNodeUtils_h___
 #define nsNodeUtils_h___
 
+#include "mozilla/Maybe.h"
+#include "mozilla/NonOwningAnimationTarget.h"
 #include "nsIContent.h"          // for use in inline function (ParentChainChanged)
 #include "nsIMutationObserver.h" // for use in inline function (ParentChainChanged)
 #include "js/TypeDecls.h"
 #include "nsCOMArray.h"
 
 struct CharacterDataChangeInfo;
 template<class E> class nsCOMArray;
 class nsCycleCollectionTraversalCallback;
@@ -137,18 +139,28 @@ public:
     if (slots && !slots->mMutationObservers.IsEmpty()) {
       NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(slots->mMutationObservers,
                                          nsIMutationObserver,
                                          ParentChainChanged,
                                          (aContent));
     }
   }
 
-  static mozilla::dom::Element*
+  /**
+   * Utility function to get the target (pseudo-)element associated with an
+   * animation.
+   * @param aAnimation The animation whose target is what we want.
+   */
+  static mozilla::Maybe<mozilla::NonOwningAnimationTarget>
     GetTargetForAnimation(const mozilla::dom::Animation* aAnimation);
+
+  /**
+   * Notify that an animation is added/changed/removed.
+   * @param aAnimation The animation we added/changed/removed.
+   */
   static void AnimationAdded(mozilla::dom::Animation* aAnimation);
   static void AnimationChanged(mozilla::dom::Animation* aAnimation);
   static void AnimationRemoved(mozilla::dom::Animation* aAnimation);
 
   /**
    * To be called when reference count of aNode drops to zero.
    * @param aNode The node which is going to be deleted.
    */
@@ -294,11 +306,27 @@ private:
    * @param aResult If aClone is true then *aResult will contain the cloned
    *                node.
    */
   static nsresult CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
                                 nsNodeInfoManager *aNewNodeInfoManager,
                                 JS::Handle<JSObject*> aReparentScope,
                                 nsCOMArray<nsINode> &aNodesWithProperties,
                                 nsINode *aParent, nsINode **aResult);
+
+  enum class AnimationMutationType
+  {
+    Added,
+    Changed,
+    Removed
+  };
+  /**
+   * Notify the observers of the target of an animation
+   * @param aAnimation The mutated animation.
+   * @param aMutationType The mutation type of this animation. It could be
+   *                      Added, Changed, or Removed.
+   */
+  static void AnimationMutated(mozilla::dom::Animation* aAnimation,
+                               AnimationMutationType aMutatedType);
+
 };
 
 #endif // nsNodeUtils_h___
--- a/dom/bindings/Errors.msg
+++ b/dom/bindings/Errors.msg
@@ -87,8 +87,10 @@ MSG_DEF(MSG_PROMISE_CAPABILITY_HAS_SOMET
 MSG_DEF(MSG_PROMISE_RESOLVE_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the resolve function.")
 MSG_DEF(MSG_PROMISE_REJECT_FUNCTION_NOT_CALLABLE, 0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the reject function.")
 MSG_DEF(MSG_PROMISE_ARG_NOT_ITERABLE, 1, JSEXN_TYPEERR, "{0} is not iterable")
 MSG_DEF(MSG_IS_NOT_PROMISE, 1, JSEXN_TYPEERR, "{0} is not a Promise")
 MSG_DEF(MSG_SW_INSTALL_ERROR, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for scope {1} encountered an error during installation.")
 MSG_DEF(MSG_SW_SCRIPT_THREW, 2, JSEXN_TYPEERR, "ServiceWorker script at {0} for scope {1} threw an exception during script evaluation.")
 MSG_DEF(MSG_TYPEDARRAY_IS_SHARED, 1, JSEXN_TYPEERR, "{0} can't be a typed array on SharedArrayBuffer")
 MSG_DEF(MSG_CACHE_ADD_FAILED_RESPONSE, 3, JSEXN_TYPEERR, "Cache got {0} response with bad status {1} while trying to add request {2}")
+MSG_DEF(MSG_INVALID_DURATION_ERROR, 0, JSEXN_TYPEERR, "Invalid duration.")
+MSG_DEF(MSG_INVALID_EASING_ERROR, 0, JSEXN_TYPEERR, "Invalid easing.")
\ No newline at end of file
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -2463,22 +2463,22 @@ public:
   virtual float GetEmLength() const override
   {
     return NSAppUnitsToFloatPixels(mFont.size,
                                    nsPresContext::AppUnitsPerCSSPixel());
   }
 
   virtual float GetExLength() const override
   {
-    gfxTextPerfMetrics* tp = mPresContext->GetTextPerfMetrics();
-    RefPtr<nsFontMetrics> fontMetrics;
     nsDeviceContext* dc = mPresContext->DeviceContext();
-    dc->GetMetricsFor(mFont, mFontLanguage, mExplicitLanguage,
-                      gfxFont::eHorizontal, nullptr, tp,
-                      *getter_AddRefs(fontMetrics));
+    nsFontMetrics::Params params;
+    params.language = mFontLanguage;
+    params.explicitLanguage = mExplicitLanguage;
+    params.textPerf = mPresContext->GetTextPerfMetrics();
+    RefPtr<nsFontMetrics> fontMetrics = dc->GetMetricsFor(mFont, params);
     return NSAppUnitsToFloatPixels(fontMetrics->XHeight(),
                                    nsPresContext::AppUnitsPerCSSPixel());
   }
 
   virtual gfx::Size GetSize() const override
   { return Size(mSize); }
 
 private:
@@ -3225,24 +3225,23 @@ CanvasRenderingContext2D::SetFontInterna
   // device pixels, to avoid being affected by page zoom. nsFontMetrics will
   // convert nsFont size in app units to device pixels for the font group, so
   // here we first apply to the size the equivalent of a conversion from device
   // pixels to CSS pixels, to adjust for the difference in expectations from
   // other nsFontMetrics clients.
   resizedFont.size =
     (fontStyle->mSize * c->AppUnitsPerDevPixel()) / c->AppUnitsPerCSSPixel();
 
-  RefPtr<nsFontMetrics> metrics;
-  c->DeviceContext()->GetMetricsFor(resizedFont,
-                                    fontStyle->mLanguage,
-                                    fontStyle->mExplicitLanguage,
-                                    gfxFont::eHorizontal,
-                                    c->GetUserFontSet(),
-                                    c->GetTextPerfMetrics(),
-                                    *getter_AddRefs(metrics));
+  nsFontMetrics::Params params;
+  params.language = fontStyle->mLanguage;
+  params.explicitLanguage = fontStyle->mExplicitLanguage;
+  params.userFontSet = c->GetUserFontSet();
+  params.textPerf = c->GetTextPerfMetrics();
+  RefPtr<nsFontMetrics> metrics =
+    c->DeviceContext()->GetMetricsFor(resizedFont, params);
 
   gfxFontGroup* newFontGroup = metrics->GetThebesFontGroup();
   CurrentState().fontGroup = newFontGroup;
   NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
   CurrentState().font = usedFont;
   CurrentState().fontFont = fontStyle->mFont;
   CurrentState().fontFont.size = fontStyle->mSize;
   CurrentState().fontLanguage = fontStyle->mLanguage;
@@ -4957,16 +4956,20 @@ CanvasRenderingContext2D::DrawWindow(nsG
 
   nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
   Unused << shell->RenderDocument(r, renderDocFlags, backgroundColor, thebes);
   // If this canvas was contained in the drawn window, the pre-transaction callback
   // may have returned its DT. If so, we must reacquire it here.
   EnsureTarget();
   if (drawDT) {
     RefPtr<SourceSurface> snapshot = drawDT->Snapshot();
+    if (NS_WARN_IF(!snapshot)) {
+      aError.Throw(NS_ERROR_FAILURE);
+      return;
+    }
     RefPtr<DataSourceSurface> data = snapshot->GetDataSurface();
 
     DataSourceSurface::MappedSurface rawData;
     if (NS_WARN_IF(!data->Map(DataSourceSurface::READ, &rawData))) {
         aError.Throw(NS_ERROR_FAILURE);
         return;
     }
     RefPtr<SourceSurface> source =
--- a/dom/canvas/test/reftest/reftest.list
+++ b/dom/canvas/test/reftest/reftest.list
@@ -15,105 +15,104 @@ pref(webgl.force-layers-readback,true)  
 == webgl-clear-test.html?depth wrapper.html?green.png
 == webgl-clear-test.html?stencil wrapper.html?green.png
 == webgl-clear-test.html?depth&stencil wrapper.html?green.png
 
 # Check that resize works:
 == webgl-resize-test.html  wrapper.html?green.png
 
 # Check that captureStream() displays in a local video element
-skip-if(winWidget&&layersGPUAccelerated&&d2d) == webgl-capturestream-test.html?preserve wrapper.html?green.png
+== webgl-capturestream-test.html?preserve wrapper.html?green.png
 
 # Some of the failure conditions are a little crazy. I'm (jgilbert) setting these based on
 # failures encountered when running on Try, and then targetting the Try config by
 # differences in the `sandbox` contents. That is, I'm labeling based on symptoms rather
 # than cause.
-# Lin-R-e10s: gtkWidget && browserIsRemote
-# WinXP-R: winWidget && layersGPUAccelerated && !d2d
-# Win7+-R: winWidget && layersGPUAccelerated && d2d
-# Win7+-Ru: winWidget && !layersGPUAccelerated
+# WinXP R:  winWidget && layersGPUAccelerated  && !d3d11
+# Win7+ R:  winWidget && layersGPUAccelerated  && d3d11
+# Win7+ Ru: winWidget && !layersGPUAccelerated && d3d11
 # (Note that we have to remove spaces when used below)
 
 # IMPORTANT: Expected outcomes are evaluated left-to-right, and they replace eachother.
 # That means that if an unconditional status (`fuzzy()`) is to the right of another status
 # (such as fails-if), it will overwrite the old status.
 #
 # As such, all unconditional statuses should be to the left of conditional statuses.
 # (See /layout/tools/reftest/reftest.js:945)
 
 # Does we draw the correct colors in the correct places?
 # Combinations: PowerSet([readback, aa, preserve, premult, alpha]) x [frame=1,frame=6]
 # This is 2^6 = 64 combinations.
-                                                                                                         == webgl-color-test.html?frame=1&__&________&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=1&aa&________&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=1&__&preserve&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=1&aa&preserve&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=1&__&________&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=1&aa&________&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=1&__&preserve&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=1&aa&preserve&premult&_____  wrapper.html?colors-no-alpha.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    == webgl-color-test.html?frame=1&__&________&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    == webgl-color-test.html?frame=1&aa&________&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    == webgl-color-test.html?frame=1&__&preserve&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    == webgl-color-test.html?frame=1&aa&preserve&_______&alpha  wrapper.html?colors-non-premult.png
-                                                                                                         == webgl-color-test.html?frame=1&__&________&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                         == webgl-color-test.html?frame=1&aa&________&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                         == webgl-color-test.html?frame=1&__&preserve&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                         == webgl-color-test.html?frame=1&aa&preserve&premult&alpha  wrapper.html?colors-premult.png
+                                                                                                        == webgl-color-test.html?frame=1&__&________&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=1&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=1&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=1&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=1&__&________&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=1&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=1&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=1&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)                                        == webgl-color-test.html?frame=1&__&________&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)                                        == webgl-color-test.html?frame=1&aa&________&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)                                        == webgl-color-test.html?frame=1&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)                                        == webgl-color-test.html?frame=1&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
+                                                                                                        == webgl-color-test.html?frame=1&__&________&premult&alpha wrapper.html?colors-premult.png
+                                                                                                        == webgl-color-test.html?frame=1&aa&________&premult&alpha wrapper.html?colors-premult.png
+                                                                                                        == webgl-color-test.html?frame=1&__&preserve&premult&alpha wrapper.html?colors-premult.png
+                                                                                                        == webgl-color-test.html?frame=1&aa&preserve&premult&alpha wrapper.html?colors-premult.png
 
-                                                                                                         == webgl-color-test.html?frame=6&__&________&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=6&aa&________&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=6&__&preserve&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                          == webgl-color-test.html?frame=6&aa&preserve&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=6&__&________&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=6&aa&________&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         == webgl-color-test.html?frame=6&__&preserve&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                          == webgl-color-test.html?frame=6&aa&preserve&premult&_____  wrapper.html?colors-no-alpha.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    == webgl-color-test.html?frame=6&__&________&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    == webgl-color-test.html?frame=6&aa&________&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    == webgl-color-test.html?frame=6&__&preserve&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&(!layersGPUAccelerated||!d3d11)) == webgl-color-test.html?frame=6&aa&preserve&_______&alpha  wrapper.html?colors-non-premult.png
-                                                                                                         == webgl-color-test.html?frame=6&__&________&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                         == webgl-color-test.html?frame=6&aa&________&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                         == webgl-color-test.html?frame=6&__&preserve&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                         == webgl-color-test.html?frame=6&aa&preserve&premult&alpha  wrapper.html?colors-premult.png
+                                                                                                        == webgl-color-test.html?frame=6&__&________&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=6&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=6&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=6&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=6&__&________&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=6&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=6&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                                                        == webgl-color-test.html?frame=6&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)                                        == webgl-color-test.html?frame=6&__&________&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)                                        == webgl-color-test.html?frame=6&aa&________&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)                                        == webgl-color-test.html?frame=6&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)                                        == webgl-color-test.html?frame=6&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
+                                                                                                        == webgl-color-test.html?frame=6&__&________&premult&alpha wrapper.html?colors-premult.png
+                                                                                                        == webgl-color-test.html?frame=6&aa&________&premult&alpha wrapper.html?colors-premult.png
+                                                                                                        == webgl-color-test.html?frame=6&__&preserve&premult&alpha wrapper.html?colors-premult.png
+                                                                                                        == webgl-color-test.html?frame=6&aa&preserve&premult&alpha wrapper.html?colors-premult.png
 
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&__&________&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&aa&________&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&__&preserve&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&aa&preserve&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&__&________&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&aa&________&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&__&preserve&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&aa&preserve&premult&_____  wrapper.html?colors-no-alpha.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)   pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&__&________&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)   pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&aa&________&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)   pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&__&preserve&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)   pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&aa&preserve&_______&alpha  wrapper.html?colors-non-premult.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&__&________&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&aa&________&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&__&preserve&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=1&readback&aa&preserve&premult&alpha  wrapper.html?colors-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&________&premult&alpha wrapper.html?colors-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=1&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
 
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&__&________&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&aa&________&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&__&preserve&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                         pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&aa&preserve&_______&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&__&________&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&aa&________&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&__&preserve&premult&_____  wrapper.html?colors-no-alpha.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&aa&preserve&premult&_____  wrapper.html?colors-no-alpha.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&__&________&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&aa&________&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&layersGPUAccelerated&&!d3d11)    pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&__&preserve&_______&alpha  wrapper.html?colors-non-premult.png
-fuzzy(1,30000) fails-if(gtkWidget&&browserIsRemote) fails-if(winWidget&&(!layersGPUAccelerated||!d3d11)) pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&aa&preserve&_______&alpha  wrapper.html?colors-non-premult.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&__&________&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&aa&________&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&__&preserve&premult&alpha  wrapper.html?colors-premult.png
-                                                                                                        pref(webgl.force-layers-readback,true)  == webgl-color-test.html?frame=6&readback&aa&preserve&premult&alpha  wrapper.html?colors-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&premult&_____ wrapper.html?colors-no-alpha.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&_____ wrapper.html?colors-no-alpha.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&_______&alpha wrapper.html?colors-non-premult.png
+fuzzy(1,30000) fails-if(winWidget&&layersGPUAccelerated&&!d3d11) pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&_______&alpha wrapper.html?colors-non-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&________&premult&alpha wrapper.html?colors-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&________&premult&alpha wrapper.html?colors-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&__&preserve&premult&alpha wrapper.html?colors-premult.png
+                                                                 pref(webgl.force-layers-readback,true) == webgl-color-test.html?frame=6&readback&aa&preserve&premult&alpha wrapper.html?colors-premult.png
 
 # Check for hanging bindings/state settings:
 == webgl-hanging-fb-test.html?__&________  wrapper.html?green.png
 == webgl-hanging-fb-test.html?aa&________  wrapper.html?green.png
 == webgl-hanging-fb-test.html?__&preserve  wrapper.html?green.png
 == webgl-hanging-fb-test.html?aa&preserve  wrapper.html?green.png
 pref(webgl.force-layers-readback,true)  == webgl-hanging-fb-test.html?readback&__&________  wrapper.html?green.png
 pref(webgl.force-layers-readback,true)  == webgl-hanging-fb-test.html?readback&aa&________  wrapper.html?green.png
@@ -152,11 +151,11 @@ skip-if(!winWidget) pref(webgl.disable-a
 # Bug 815648
 == stroketext-shadow.html stroketext-shadow-ref.html
 
 # focus rings
 pref(canvas.focusring.enabled,true) skip-if(B2G) skip-if(cocoaWidget) skip-if(winWidget) needs-focus == drawFocusIfNeeded.html drawFocusIfNeeded-ref.html
 pref(canvas.customfocusring.enabled,true) skip-if(B2G) skip-if(cocoaWidget) skip-if(Android) skip-if(winWidget) needs-focus == drawCustomFocusRing.html drawCustomFocusRing-ref.html
 
 # Check that captureStream() displays in a local video element
-skip-if(winWidget&&layersGPUAccelerated&&d2d) == capturestream.html wrapper.html?green.png
+== capturestream.html wrapper.html?green.png
 
 fuzzy-if(azureSkiaGL,1,2) fuzzy-if(Android,3,40) fuzzy-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu),1,1) == 1177726-text-stroke-bounds.html 1177726-text-stroke-bounds-ref.html
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -1448,33 +1448,24 @@ ContentEventHandler::OnQueryCaretRect(Wi
 
   aEvent->mReply.mWritingMode = frame->GetWritingMode();
   bool isVertical = aEvent->mReply.mWritingMode.IsVertical();
 
   nsRect rect;
   rect.x = posInFrame.x;
   rect.y = posInFrame.y;
 
-  nscoord fontHeight = 0;
-  float inflation = nsLayoutUtils::FontSizeInflationFor(frame);
-  RefPtr<nsFontMetrics> fontMetrics;
-  rv = nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fontMetrics),
-                                             inflation);
-  if (NS_WARN_IF(!fontMetrics)) {
-    // If we cannot get font height, use frame size instead.
-    fontHeight = isVertical ? frame->GetSize().width : frame->GetSize().height;
-  } else {
-    fontHeight = fontMetrics->MaxAscent() + fontMetrics->MaxDescent();
-  }
+  RefPtr<nsFontMetrics> fontMetrics =
+    nsLayoutUtils::GetInflatedFontMetricsForFrame(frame);
   if (isVertical) {
-    rect.width = fontHeight;
+    rect.width = fontMetrics->MaxHeight();
     rect.height = caretRect.height;
   } else {
     rect.width = caretRect.width;
-    rect.height = fontHeight;
+    rect.height = fontMetrics->MaxHeight();
   }
 
   rv = ConvertToRootRelativeOffset(frame, rect);
   NS_ENSURE_SUCCESS(rv, rv);
 
   aEvent->mReply.mRect = LayoutDeviceIntRect::FromUnknownRect(
       rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()));
   // If the caret rect is empty, let's make it non-empty rect.
--- a/dom/events/CustomEvent.cpp
+++ b/dom/events/CustomEvent.cpp
@@ -12,31 +12,40 @@
 #include "nsIXPConnect.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 CustomEvent::CustomEvent(mozilla::dom::EventTarget* aOwner,
                          nsPresContext* aPresContext,
                          mozilla::WidgetEvent* aEvent)
-: Event(aOwner, aPresContext, aEvent)
+  : Event(aOwner, aPresContext, aEvent)
+  , mDetail(JS::NullValue())
 {
+  mozilla::HoldJSObjects(this);
 }
 
-CustomEvent::~CustomEvent() {}
+CustomEvent::~CustomEvent()
+{
+  mozilla::DropJSObjects(this);
+}
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(CustomEvent)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(CustomEvent, Event)
-  NS_IMPL_CYCLE_COLLECTION_UNLINK(mDetail)
+  tmp->mDetail.setUndefined();
+  mozilla::DropJSObjects(this);
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(CustomEvent, Event)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDetail)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
+NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(CustomEvent, Event)
+  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mDetail)
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+
 NS_IMPL_ADDREF_INHERITED(CustomEvent, Event)
 NS_IMPL_RELEASE_INHERITED(CustomEvent, Event)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(CustomEvent)
   NS_INTERFACE_MAP_ENTRY(nsIDOMCustomEvent)
 NS_INTERFACE_MAP_END_INHERITING(Event)
 
 already_AddRefed<CustomEvent>
@@ -61,58 +70,72 @@ CustomEvent::WrapObjectInternal(JSContex
 }
 
 NS_IMETHODIMP
 CustomEvent::InitCustomEvent(const nsAString& aType,
                              bool aCanBubble,
                              bool aCancelable,
                              nsIVariant* aDetail)
 {
+  AutoJSAPI jsapi;
+  NS_ENSURE_STATE(jsapi.Init(GetParentObject()));
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JS::Value> detail(cx);
+
+  if (!aDetail) {
+    detail = JS::NullValue();
+  } else if (NS_WARN_IF(!VariantToJsval(cx, aDetail, &detail))) {
+    JS_ClearPendingException(cx);
+    return NS_ERROR_FAILURE;
+  }
+
   Event::InitEvent(aType, aCanBubble, aCancelable);
-  mDetail = aDetail;
+  mDetail = detail;
+
   return NS_OK;
 }
 
 void
 CustomEvent::InitCustomEvent(JSContext* aCx,
                              const nsAString& aType,
                              bool aCanBubble,
                              bool aCancelable,
                              JS::Handle<JS::Value> aDetail,
                              ErrorResult& aRv)
 {
-  nsCOMPtr<nsIVariant> detail;
-  if (nsIXPConnect* xpc = nsContentUtils::XPConnect()) {
-    xpc->JSToVariant(aCx, aDetail, getter_AddRefs(detail));
-  }
-
-  if (!detail) {
-    aRv.Throw(NS_ERROR_FAILURE);
-    return;
-  }
-  InitCustomEvent(aType, aCanBubble, aCancelable, detail);
+  Event::InitEvent(aType, aCanBubble, aCancelable);
+  mDetail = aDetail;
 }
 
 NS_IMETHODIMP
 CustomEvent::GetDetail(nsIVariant** aDetail)
 {
-  NS_IF_ADDREF(*aDetail = mDetail);
-  return NS_OK;
+  if (mDetail.isNull()) {
+    *aDetail = nullptr;
+    return NS_OK;
+  }
+
+  AutoJSAPI jsapi;
+  NS_ENSURE_STATE(jsapi.Init(GetParentObject()));
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JS::Value> detail(cx, mDetail);
+  nsIXPConnect* xpc = nsContentUtils::XPConnect();
+
+  if (NS_WARN_IF(!xpc)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  return xpc->JSToVariant(cx, detail, aDetail);
 }
 
 void
 CustomEvent::GetDetail(JSContext* aCx,
                        JS::MutableHandle<JS::Value> aRetval)
 {
-  if (!mDetail) {
-    aRetval.setNull();
-    return;
-  }
-
-  VariantToJsval(aCx, mDetail, aRetval);
+  aRetval.set(mDetail);
 }
 
 already_AddRefed<CustomEvent>
 NS_NewDOMCustomEvent(EventTarget* aOwner,
                      nsPresContext* aPresContext,
                      mozilla::WidgetEvent* aEvent)
 {
   RefPtr<CustomEvent> it =
--- a/dom/events/CustomEvent.h
+++ b/dom/events/CustomEvent.h
@@ -16,25 +16,25 @@ namespace dom {
 struct CustomEventInit;
 
 class CustomEvent final : public Event,
                           public nsIDOMCustomEvent
 {
 private:
   virtual ~CustomEvent();
 
-  nsCOMPtr<nsIVariant> mDetail;
+  JS::Heap<JS::Value> mDetail;
 
 public:
   explicit CustomEvent(mozilla::dom::EventTarget* aOwner,
                        nsPresContext* aPresContext = nullptr,
                        mozilla::WidgetEvent* aEvent = nullptr);
 
   NS_DECL_ISUPPORTS_INHERITED
-  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(CustomEvent, Event)
+  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(CustomEvent, Event)
   NS_FORWARD_TO_EVENT
   NS_DECL_NSIDOMCUSTOMEVENT
 
   static already_AddRefed<CustomEvent>
   Constructor(const GlobalObject& aGlobal,
               const nsAString& aType,
               const CustomEventInit& aParam,
               ErrorResult& aRv);
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -2508,19 +2508,18 @@ EventStateManager::GetScrollAmount(nsPre
     return aPresContext->GetVisibleArea().Size();
   }
 
   // If there is no scrollable frame, we should use root frame's information.
   nsIFrame* rootFrame = aPresContext->PresShell()->GetRootFrame();
   if (!rootFrame) {
     return nsSize(0, 0);
   }
-  RefPtr<nsFontMetrics> fm;
-  nsLayoutUtils::GetFontMetricsForFrame(rootFrame, getter_AddRefs(fm),
-    nsLayoutUtils::FontSizeInflationFor(rootFrame));
+  RefPtr<nsFontMetrics> fm =
+    nsLayoutUtils::GetInflatedFontMetricsForFrame(rootFrame);
   NS_ENSURE_TRUE(fm, nsSize(0, 0));
   return nsSize(fm->AveCharWidth(), fm->MaxHeight());
 }
 
 void
 EventStateManager::DoScrollText(nsIScrollableFrame* aScrollableFrame,
                                 WidgetWheelEvent* aEvent)
 {
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -41,16 +41,18 @@ skip-if = buildapp == 'b2g' || toolkit =
 [test_bug418986-3.html]
 # Sometimes fails to finish after tests pass on 'B2G ICS Emulator'.
 skip-if = (os == 'b2g')
 [test_bug422132.html]
 skip-if = buildapp == 'b2g' # b2g(2 failures out of 8, mousewheel test) b2g-debug(2 failures out of 8, mousewheel test) b2g-desktop(2 failures out of 8, mousewheel test)
 [test_bug426082.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || os == "win" || toolkit == 'android' || e10s # Intermittent failures, bug 921693 # b2g(1 failure out of 6, Moving the mouse down from the label should have unpressed the button) b2g-debug(1 failure out of 6, Moving the mouse down from the label should have unpressed the button) b2g-desktop(1 failure out of 6, Moving the mouse down from the label should have unpressed the button)
 [test_bug427537.html]
+[test_bug1003432.html]
+support-files = test_bug1003432.js
 [test_bug428988.html]
 [test_bug432698.html]
 skip-if = buildapp == 'mulet'
 [test_bug443985.html]
 [test_bug447736.html]
 [test_bug448602.html]
 [test_bug450876.html]
 skip-if = buildapp == 'mulet'
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug1003432.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1003432
+-->
+<head>
+  <title>Test for Bug 1003432</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1003432">Mozilla Bug 1003432</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 1003432 **/
+// Test CustomEvent on worker
+SimpleTest.waitForExplicitFinish();
+var worker = new Worker("test_bug1003432.js");
+ok(worker, "Should have worker!");
+
+var count = 0;
+worker.onmessage = function(evt) {
+  is(evt.data.type, "foobar", "Should get 'foobar' event!");
+  is(evt.data.detail, "test", "Detail should be 'test'.");
+  ok(evt.data.bubbles, "Event should bubble!");
+  ok(evt.data.cancelable, "Event should be cancelable.");
+
+  // wait for test results of constructor and initCustomEvent
+  if (++count == 2) {
+    worker.terminate();
+    SimpleTest.finish();
+  }
+};
+
+worker.postMessage("");
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug1003432.js
@@ -0,0 +1,23 @@
+addEventListener("foobar",
+  function(evt) {
+    postMessage(
+      {
+        type: evt.type,
+        bubbles: evt.bubbles,
+        cancelable: evt.cancelable,
+        detail: evt.detail
+      });
+  }, true);
+
+addEventListener("message",
+  function(evt) {
+    // Test the constructor of CustomEvent
+    var e = new CustomEvent("foobar",
+      {bubbles:true, cancelable: true, detail:"test"});
+    dispatchEvent(e);
+
+    // Test initCustomEvent
+    e = new CustomEvent("foobar");
+    e.initCustomEvent("foobar", true, true, "test");
+    dispatchEvent(e);
+  }, true);
--- a/dom/events/test/test_bug427537.html
+++ b/dom/events/test/test_bug427537.html
@@ -35,16 +35,20 @@ document.addEventListener("foobar",
     ok(e.bubbles, "Event should bubble!");
     ok(e.cancelable, "Event should be cancelable.");
   }, true);
 
 document.dispatchEvent(e);
 ok(didCallListener, "Should have called listener!");
 
 e = document.createEvent("CustomEvent");
+e.initEvent("foo", true, true);
+is(e.detail, null, "Default detail should be null.");
+
+e = document.createEvent("CustomEvent");
 e.initCustomEvent("foobar", true, true, 1);
 is(e.detail, 1, "Detail should be 1.");
 
 e = document.createEvent("CustomEvent");
 e.initCustomEvent("foobar", true, true, "test");
 is(e.detail, "test", "Detail should be 'test'.");
 
 e = document.createEvent("CustomEvent");
--- a/dom/indexedDB/ActorsParent.cpp
+++ b/dom/indexedDB/ActorsParent.cpp
@@ -5294,19 +5294,20 @@ public:
 
   void
   Dispatch(uint64_t aTransactionId, nsIRunnable* aRunnable);
 
   void
   Finish(uint64_t aTransactionId, FinishCallback* aCallback);
 
   void
-  CloseDatabaseWhenIdle(const nsACString& aDatabaseId)
-  {
-    Unused << CloseDatabaseWhenIdleInternal(aDatabaseId);
+  CloseDatabaseWhenIdle(const nsACString& aDatabaseId,
+                        uintptr_t aCallsite)
+  {
+    Unused << CloseDatabaseWhenIdleInternal(aDatabaseId, aCallsite);
   }
 
   void
   WaitForDatabasesToComplete(nsTArray<nsCString>&& aDatabaseIds,
                              nsIRunnable* aCallback);
 
   void
   Shutdown();
@@ -5358,17 +5359,18 @@ private:
 
   void
   PerformIdleDatabaseMaintenance(DatabaseInfo* aDatabaseInfo);
 
   void
   CloseDatabase(DatabaseInfo* aDatabaseInfo, uintptr_t aCallsite);
 
   bool
-  CloseDatabaseWhenIdleInternal(const nsACString& aDatabaseId);
+  CloseDatabaseWhenIdleInternal(const nsACString& aDatabaseId,
+                                uintptr_t aCallsite);
 };
 
 class ConnectionPool::ConnectionRunnable
   : public nsRunnable
 {
 protected:
   DatabaseInfo* mDatabaseInfo;
   nsCOMPtr<nsIEventTarget> mOwningThread;
@@ -10910,18 +10912,18 @@ UpdateRefcountFunction::Reset()
         return NS_ERROR_FAILURE;
       }
 
       nsresult rv;
       int64_t fileSize;
 
       if (aFileManager->EnforcingQuota()) {
         rv = file->GetFileSize(&fileSize);
-        if (NS_WARN_IF(!file)) {
-          return NS_ERROR_FAILURE;
+        if (NS_WARN_IF(NS_FAILED(rv))) {
+          return rv;
         }
       }
 
       rv = file->Remove(false);
       if (NS_WARN_IF(NS_FAILED(rv))) {
         return rv;
       }
 
@@ -11640,17 +11642,17 @@ ConnectionPool::WaitForDatabasesToComple
   bool mayRunCallbackImmediately = true;
 
   for (uint32_t index = 0, count = aDatabaseIds.Length();
        index < count;
        index++) {
     const nsCString& databaseId = aDatabaseIds[index];
     MOZ_ASSERT(!databaseId.IsEmpty());
 
-    if (CloseDatabaseWhenIdleInternal(databaseId)) {
+    if (CloseDatabaseWhenIdleInternal(databaseId, 0x6)) {
       mayRunCallbackImmediately = false;
     }
   }
 
   if (mayRunCallbackImmediately) {
     Unused << aCallback->Run();
     return;
   }
@@ -12144,17 +12146,17 @@ ConnectionPool::ScheduleQueuedTransactio
   AdjustIdleTimer();
 }
 
 void
 ConnectionPool::NoteIdleDatabase(DatabaseInfo* aDatabaseInfo)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aDatabaseInfo);
-  MOZ_ASSERT(!aDatabaseInfo->TotalTransactionCount());
+  MOZ_RELEASE_ASSERT(!aDatabaseInfo->TotalTransactionCount());
   MOZ_ASSERT(aDatabaseInfo->mThreadInfo.mThread);
   MOZ_ASSERT(aDatabaseInfo->mThreadInfo.mRunnable);
   MOZ_ASSERT(!mIdleDatabases.Contains(aDatabaseInfo));
 
   PROFILER_LABEL("IndexedDB",
                  "ConnectionPool::NoteIdleDatabase",
                  js::ProfileEntry::Category::STORAGE);
 
@@ -12318,17 +12320,17 @@ ConnectionPool::MaybeFireCallback(Databa
   return true;
 }
 
 void
 ConnectionPool::PerformIdleDatabaseMaintenance(DatabaseInfo* aDatabaseInfo)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(aDatabaseInfo);
-  MOZ_ASSERT(!aDatabaseInfo->TotalTransactionCount());
+  MOZ_RELEASE_ASSERT(!aDatabaseInfo->TotalTransactionCount());
   MOZ_ASSERT(aDatabaseInfo->mThreadInfo.mThread);
   MOZ_ASSERT(aDatabaseInfo->mThreadInfo.mRunnable);
   MOZ_ASSERT(aDatabaseInfo->mIdle);
   MOZ_ASSERT(!aDatabaseInfo->mCloseOnIdle);
   MOZ_ASSERT(!aDatabaseInfo->mClosing);
   MOZ_ASSERT(mIdleDatabases.Contains(aDatabaseInfo));
   MOZ_ASSERT(!mDatabasesPerformingIdleMaintenance.Contains(aDatabaseInfo));
 
@@ -12364,29 +12366,30 @@ ConnectionPool::CloseDatabase(DatabaseIn
                                                                aCallsite);
 
   MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
     aDatabaseInfo->mThreadInfo.mThread->Dispatch(runnable,
                                                  NS_DISPATCH_NORMAL)));
 }
 
 bool
-ConnectionPool::CloseDatabaseWhenIdleInternal(const nsACString& aDatabaseId)
+ConnectionPool::CloseDatabaseWhenIdleInternal(const nsACString& aDatabaseId,
+                                              uintptr_t aCallsite)
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(!aDatabaseId.IsEmpty());
 
   PROFILER_LABEL("IndexedDB",
                  "ConnectionPool::CloseDatabaseWhenIdleInternal",
                  js::ProfileEntry::Category::STORAGE);
 
   if (DatabaseInfo* dbInfo = mDatabases.Get(aDatabaseId)) {
     if (mIdleDatabases.RemoveElement(dbInfo) ||
         mDatabasesPerformingIdleMaintenance.RemoveElement(dbInfo)) {
-      CloseDatabase(dbInfo, 5);
+      CloseDatabase(dbInfo, aCallsite);
       AdjustIdleTimer();
     } else {
       dbInfo->mCloseOnIdle = true;
     }
 
     return true;
   }
 
@@ -13651,17 +13654,17 @@ Database::CloseInternal()
 
     // Ignore harmless race when we just invalidated the database.
     return true;
   }
 
   mClosed = true;
 
   if (gConnectionPool) {
-    gConnectionPool->CloseDatabaseWhenIdle(Id());
+    gConnectionPool->CloseDatabaseWhenIdle(Id(), 0x7);
   }
 
   DatabaseActorInfo* info;
   MOZ_ALWAYS_TRUE(gLiveDatabaseHashtable->Get(Id(), &info));
 
   MOZ_ASSERT(info->mLiveDatabases.Contains(this));
 
   if (info->mWaitingFactoryOp) {
--- a/dom/media/FrameStatistics.h
+++ b/dom/media/FrameStatistics.h
@@ -15,18 +15,17 @@ class FrameStatistics {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FrameStatistics);
 
   FrameStatistics() :
       mReentrantMonitor("FrameStats"),
       mParsedFrames(0),
       mDecodedFrames(0),
       mPresentedFrames(0),
-      mDroppedFrames(0),
-      mCorruptFrames(0) {}
+      mDroppedFrames(0) {}
 
   // Returns number of frames which have been parsed from the media.
   // Can be called on any thread.
   uint32_t GetParsedFrames() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mParsedFrames;
   }
 
@@ -44,22 +43,17 @@ public:
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     return mPresentedFrames;
   }
 
   // Number of frames that have been skipped because they have missed their
   // compoisition deadline.
   uint32_t GetDroppedFrames() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-    return mDroppedFrames + mCorruptFrames;
-  }
-
-  uint32_t GetCorruptedFrames() {
-    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-    return mCorruptFrames;
+    return mDroppedFrames;
   }
 
   // Increments the parsed and decoded frame counters by the passed in counts.
   // Can be called on any thread.
   void NotifyDecodedFrames(uint32_t aParsed, uint32_t aDecoded,
                            uint32_t aDropped) {
     if (aParsed == 0 && aDecoded == 0 && aDropped == 0)
       return;
@@ -71,21 +65,16 @@ public:
 
   // Increments the presented frame counters.
   // Can be called on any thread.
   void NotifyPresentedFrame() {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     ++mPresentedFrames;
   }
 
-  void NotifyCorruptFrame() {
-    ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-    ++mCorruptFrames;
-  }
-
 private:
   ~FrameStatistics() {}
 
   // ReentrantMonitor to protect access of playback statistics.
   ReentrantMonitor mReentrantMonitor;
 
   // Number of frames parsed and demuxed from media.
   // Access protected by mReentrantMonitor.
@@ -95,15 +84,13 @@ private:
   // Access protected by mReentrantMonitor.
   uint32_t mDecodedFrames;
 
   // Number of decoded frames which were actually sent down the rendering
   // pipeline to be painted ("presented"). Access protected by mReentrantMonitor.
   uint32_t mPresentedFrames;
 
   uint32_t mDroppedFrames;
-
-  uint32_t mCorruptFrames;
 };
 
 } // namespace mozilla
 
 #endif
--- a/dom/media/MediaDecoderReader.h
+++ b/dom/media/MediaDecoderReader.h
@@ -276,18 +276,16 @@ public:
   // implementation in this class to adapt the old synchronous to
   // the newer async model.
   virtual bool IsAsync() const { return false; }
 
   // Returns true if this decoder reader uses hardware accelerated video
   // decoding.
   virtual bool VideoIsHardwareAccelerated() const { return false; }
 
-  virtual void DisableHardwareAcceleration() {}
-
   TimedMetadataEventSource& TimedMetadataEvent()
   {
     return mTimedMetadataEvent;
   }
 
   // Notified by the OggReader during playback when chained ogg is detected.
   MediaEventSource<void>& OnMediaNotSeekable() { return mOnMediaNotSeekable; }
 
--- a/dom/media/MediaDecoderStateMachine.cpp
+++ b/dom/media/MediaDecoderStateMachine.cpp
@@ -233,17 +233,16 @@ MediaDecoderStateMachine::MediaDecoderSt
   mNotifyMetadataBeforeFirstFrame(false),
   mDispatchedEventToDecode(false),
   mQuickBuffering(false),
   mMinimizePreroll(false),
   mDecodeThreadWaiting(false),
   mDropAudioUntilNextDiscontinuity(false),
   mDropVideoUntilNextDiscontinuity(false),
   mCurrentTimeBeforeSeek(0),
-  mCorruptFrames(60),
   mDecodingFirstFrame(true),
   mSentLoadedMetadataEvent(false),
   mSentFirstFrameLoadedEvent(false),
   mSentPlaybackEndedEvent(false),
   mOutputStreamManager(new OutputStreamManager()),
   mResource(aDecoder->GetResource()),
   mAudioOffloading(false),
   mSilentDataDuration(0),
@@ -456,22 +455,23 @@ void MediaDecoderStateMachine::DiscardSt
     if (a && a->mTime < clockTime) {
       RefPtr<MediaData> releaseMe = AudioQueue().PopFront();
       continue;
     }
     break;
   }
 }
 
-bool MediaDecoderStateMachine::HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs)
+bool MediaDecoderStateMachine::HaveEnoughDecodedAudio()
 {
   MOZ_ASSERT(OnTaskQueue());
 
+  int64_t ampleAudioUSecs = mAmpleAudioThresholdUsecs * mPlaybackRate;
   if (AudioQueue().GetSize() == 0 ||
-      GetDecodedAudioDuration() < aAmpleAudioUSecs) {
+      GetDecodedAudioDuration() < ampleAudioUSecs) {
     return false;
   }
 
   // MDSM will ensure buffering level is high enough for playback speed at 1x
   // at which the DecodedStream is playing.
   return true;
 }
 
@@ -558,24 +558,22 @@ MediaDecoderStateMachine::NeedToSkipToNe
   return false;
 }
 
 bool
 MediaDecoderStateMachine::NeedToDecodeAudio()
 {
   MOZ_ASSERT(OnTaskQueue());
   SAMPLE_LOG("NeedToDecodeAudio() isDec=%d minPrl=%d enufAud=%d",
-             IsAudioDecoding(), mMinimizePreroll,
-             HaveEnoughDecodedAudio(mAmpleAudioThresholdUsecs * mPlaybackRate));
+             IsAudioDecoding(), mMinimizePreroll, HaveEnoughDecodedAudio());
 
   return IsAudioDecoding() &&
          mState != DECODER_STATE_SEEKING &&
          ((IsDecodingFirstFrame() && AudioQueue().GetSize() == 0) ||
-          (!mMinimizePreroll &&
-           !HaveEnoughDecodedAudio(mAmpleAudioThresholdUsecs * mPlaybackRate)));
+          (!mMinimizePreroll && !HaveEnoughDecodedAudio()));
 }
 
 bool
 MediaDecoderStateMachine::IsAudioSeekComplete()
 {
   MOZ_ASSERT(OnTaskQueue());
   SAMPLE_LOG("IsAudioSeekComplete() curTarVal=%d mAudDis=%d aqFin=%d aqSz=%d",
     mCurrentSeek.Exists(), mDropAudioUntilNextDiscontinuity, AudioQueue().IsFinished(), AudioQueue().GetSize());
@@ -889,20 +887,16 @@ MediaDecoderStateMachine::OnVideoDecoded
   // Handle abnormal or negative timestamps.
   mDecodedVideoEndTime = std::max(mDecodedVideoEndTime, video->GetEndTime());
 
   SAMPLE_LOG("OnVideoDecoded [%lld,%lld] disc=%d",
              (video ? video->mTime : -1),
              (video ? video->GetEndTime() : -1),
              (video ? video->mDiscontinuity : 0));
 
-  // Check frame validity here for every decoded frame in order to have a
-  // better chance to make the decision of turning off HW acceleration.
-  CheckFrameValidity(aVideoSample->As<VideoData>());
-
   switch (mState) {
     case DECODER_STATE_BUFFERING: {
       // If we're buffering, this may be the sample we need to stop buffering.
       // Save it and schedule the state machine.
       Push(video, MediaData::VIDEO_DATA);
       ScheduleStateMachine();
       return;
     }
@@ -2414,43 +2408,16 @@ MediaDecoderStateMachine::Reset()
 
   mPlaybackOffset = 0;
 
   nsCOMPtr<nsIRunnable> resetTask =
     NS_NewRunnableMethod(mReader, &MediaDecoderReader::ResetDecode);
   DecodeTaskQueue()->Dispatch(resetTask.forget());
 }
 
-void
-MediaDecoderStateMachine::CheckFrameValidity(VideoData* aData)
-{
-  MOZ_ASSERT(OnTaskQueue());
-
-  // Update corrupt-frames statistics
-  if (aData->mImage && !aData->mImage->IsValid() && !gfxPrefs::HardwareVideoDecodingForceEnabled()) {
-    FrameStatistics& frameStats = *mFrameStats;
-    frameStats.NotifyCorruptFrame();
-    // If more than 10% of the last 30 frames have been corrupted, then try disabling
-    // hardware acceleration. We use 10 as the corrupt value because RollingMean<>
-    // only supports integer types.
-    mCorruptFrames.insert(10);
-    if (mReader->VideoIsHardwareAccelerated() &&
-        frameStats.GetPresentedFrames() > 60 &&
-        mCorruptFrames.mean() >= 2 /* 20% */) {
-        nsCOMPtr<nsIRunnable> task =
-          NS_NewRunnableMethod(mReader, &MediaDecoderReader::DisableHardwareAcceleration);
-        DecodeTaskQueue()->Dispatch(task.forget());
-        mCorruptFrames.clear();
-      gfxCriticalNote << "Too many dropped/corrupted frames, disabling DXVA";
-    }
-  } else {
-    mCorruptFrames.insert(0);
-  }
-}
-
 int64_t
 MediaDecoderStateMachine::GetClock(TimeStamp* aTimeStamp) const
 {
   MOZ_ASSERT(OnTaskQueue());
   int64_t clockTime = mMediaSink->GetPosition(aTimeStamp);
   NS_ASSERTION(GetMediaTime() <= clockTime, "Clock should go forwards.");
   return clockTime;
 }
--- a/dom/media/MediaDecoderStateMachine.h
+++ b/dom/media/MediaDecoderStateMachine.h
@@ -79,17 +79,16 @@ audio data off the queue and plays it wi
 hardware (via AudioStream).
 
 */
 #if !defined(MediaDecoderStateMachine_h__)
 #define MediaDecoderStateMachine_h__
 
 #include "mozilla/Attributes.h"
 #include "mozilla/ReentrantMonitor.h"
-#include "mozilla/RollingMean.h"
 #include "mozilla/StateMirroring.h"
 
 #include "nsThreadUtils.h"
 #include "MediaDecoder.h"
 #include "MediaDecoderReader.h"
 #include "MediaDecoderOwner.h"
 #include "MediaEventSource.h"
 #include "MediaMetadataManager.h"
@@ -336,17 +335,17 @@ private:
     mDelayedScheduler.CompleteRequest();
     ScheduleStateMachine();
   }
 
   void NotReached() { MOZ_DIAGNOSTIC_ASSERT(false); }
 
   // Discard audio/video data that are already played by MSG.
   void DiscardStreamData();
-  bool HaveEnoughDecodedAudio(int64_t aAmpleAudioUSecs);
+  bool HaveEnoughDecodedAudio();
   bool HaveEnoughDecodedVideo();
 
   // Returns true if the state machine has shutdown or is in the process of
   // shutting down. The decoder monitor must be held while calling this.
   bool IsShutdown();
 
   // Returns true if we're currently playing. The decoder monitor must
   // be held.
@@ -449,20 +448,16 @@ protected:
   void SetStartTime(int64_t aStartTimeUsecs);
 
   // Update only the state machine's current playback position (and duration,
   // if unknown).  Does not update the playback position on the decoder or
   // media element -- use UpdatePlaybackPosition for that.  Called on the state
   // machine thread, caller must hold the decoder lock.
   void UpdatePlaybackPositionInternal(int64_t aTime);
 
-  // Decode monitor must be held. To determine if MDSM needs to turn off HW
-  // acceleration.
-  void CheckFrameValidity(VideoData* aData);
-
   // Update playback position and trigger next update by default time period.
   // Called on the state machine thread.
   void UpdatePlaybackPositionPeriodically();
 
   media::MediaSink* CreateAudioSink();
 
   // Always create mediasink which contains an AudioSink or StreamSink inside.
   already_AddRefed<media::MediaSink> CreateMediaSink(bool aAudioCaptured);
@@ -1126,18 +1121,16 @@ private:
   // Stores presentation info required for playback. The decoder monitor
   // must be held when accessing this.
   MediaInfo mInfo;
 
   nsAutoPtr<MetadataTags> mMetadataTags;
 
   mozilla::MediaMetadataManager mMetadataManager;
 
-  mozilla::RollingMean<uint32_t, uint32_t> mCorruptFrames;
-
   // Track our request to update the buffered ranges
   MozPromiseRequestHolder<MediaDecoderReader::BufferedUpdatePromise> mBufferedUpdateRequest;
 
   // True if we need to call FinishDecodeFirstFrame() upon frame decoding
   // successeeding.
   bool mDecodingFirstFrame;
 
   // True if we are back from DECODER_STATE_DORMANT state and
--- a/dom/media/MediaFormatReader.cpp
+++ b/dom/media/MediaFormatReader.cpp
@@ -63,17 +63,16 @@ MediaFormatReader::MediaFormatReader(Abs
   , mVideo(this, MediaData::VIDEO_DATA, Preferences::GetUint("media.video-decode-ahead", 2))
   , mDemuxer(aDemuxer)
   , mDemuxerInitDone(false)
   , mLastReportedNumDecodedFrames(0)
   , mLayersBackendType(aLayersBackend)
   , mInitDone(false)
   , mIsEncrypted(false)
   , mTrackDemuxersMayBlock(false)
-  , mHardwareAccelerationDisabled(false)
   , mDemuxOnly(false)
   , mVideoFrameContainer(aVideoFrameContainer)
 {
   MOZ_ASSERT(aDemuxer);
   MOZ_COUNT_CTOR(MediaFormatReader);
 }
 
 MediaFormatReader::~MediaFormatReader()
@@ -401,17 +400,16 @@ MediaFormatReader::EnsureDecoderCreated(
       // Decoders use the layers backend to decide if they can use hardware decoding,
       // so specify LAYERS_NONE if we want to forcibly disable it.
       decoder.mDecoder =
         mPlatform->CreateDecoder(mVideo.mInfo ?
                                    *mVideo.mInfo->GetAsVideoInfo() :
                                    mInfo.mVideo,
                                  decoder.mTaskQueue,
                                  decoder.mCallback,
-                                 mHardwareAccelerationDisabled ? LayersBackend::LAYERS_NONE :
                                  mLayersBackendType,
                                  GetImageContainer());
       break;
     default:
       break;
   }
   if (decoder.mDecoder ) {
     decoder.mDescription = decoder.mDecoder->GetDescriptionName();
@@ -466,33 +464,16 @@ MediaFormatReader::GetDecoderData(TrackT
   MOZ_ASSERT(aTrack == TrackInfo::kAudioTrack ||
              aTrack == TrackInfo::kVideoTrack);
   if (aTrack == TrackInfo::kAudioTrack) {
     return mAudio;
   }
   return mVideo;
 }
 
-void
-MediaFormatReader::DisableHardwareAcceleration()
-{
-  MOZ_ASSERT(OnTaskQueue());
-  if (HasVideo() && !mHardwareAccelerationDisabled) {
-    mHardwareAccelerationDisabled = true;
-    Flush(TrackInfo::kVideoTrack);
-    mVideo.ShutdownDecoder();
-    if (!EnsureDecoderCreated(TrackType::kVideoTrack)) {
-      LOG("Unable to re-create decoder, aborting");
-      NotifyError(TrackInfo::kVideoTrack);
-      return;
-    }
-    ScheduleUpdate(TrackInfo::kVideoTrack);
-  }
-}
-
 bool
 MediaFormatReader::ShouldSkip(bool aSkipToNextKeyframe, media::TimeUnit aTimeThreshold)
 {
   MOZ_ASSERT(HasVideo());
   media::TimeUnit nextKeyframe;
   nsresult rv = mVideo.mTrackDemuxer->GetNextRandomAccessPoint(&nextKeyframe);
   if (NS_FAILED(rv)) {
     return aSkipToNextKeyframe;
--- a/dom/media/MediaFormatReader.h
+++ b/dom/media/MediaFormatReader.h
@@ -65,18 +65,16 @@ public:
   nsresult ResetDecode() override;
 
   RefPtr<ShutdownPromise> Shutdown() override;
 
   bool IsAsync() const override { return true; }
 
   bool VideoIsHardwareAccelerated() const override;
 
-  void DisableHardwareAcceleration() override;
-
   bool IsWaitForDataSupported() override { return true; }
   RefPtr<WaitForDataPromise> WaitForData(MediaData::Type aType) override;
 
   // MediaFormatReader supports demuxed-only mode.
   bool IsDemuxOnlySupported() const override { return true; }
 
   void SetDemuxOnly(bool aDemuxedOnly) override
   {
@@ -444,18 +442,16 @@ private:
   {
     return mIsEncrypted;
   }
   bool mIsEncrypted;
 
   // Set to true if any of our track buffers may be blocking.
   bool mTrackDemuxersMayBlock;
 
-  bool mHardwareAccelerationDisabled;
-
   // Set the demuxed-only flag.
   Atomic<bool> mDemuxOnly;
 
   // Seeking objects.
   bool IsSeeking() const { return mPendingSeekTime.isSome(); }
   void AttemptSeek();
   void OnSeekFailed(TrackType aTrack, DemuxerFailureReason aFailure);
   void DoVideoSeek();
--- a/dom/media/MediaPermissionGonk.cpp
+++ b/dom/media/MediaPermissionGonk.cpp
@@ -239,17 +239,17 @@ MediaPermissionRequest::Allow(JS::Handle
 {
   // check if JS object
   if (!aChoices.isObject()) {
     MOZ_ASSERT(false, "Not a correct format of PermissionChoice");
     return NS_ERROR_INVALID_ARG;
   }
   // iterate through audio-capture and video-capture
   AutoJSAPI jsapi;
-  if (!jsapi.init(&aChoices.toObject())) {
+  if (!jsapi.Init(&aChoices.toObject())) {
     return NS_ERROR_UNEXPECTED;
   }
   JSContext* cx = jsapi.cx();
   JS::Rooted<JSObject*> obj(cx, &aChoices.toObject());
   JS::Rooted<JS::Value> v(cx);
 
   // get selected audio device name
   nsString audioDevice;
--- a/dom/media/mediasource/MediaSourceDecoder.cpp
+++ b/dom/media/mediasource/MediaSourceDecoder.cpp
@@ -272,16 +272,21 @@ MediaSourceDecoder::NextFrameBufferedSta
     ? MediaDecoderOwner::NEXT_FRAME_AVAILABLE
     : MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE;
 }
 
 bool
 MediaSourceDecoder::CanPlayThrough()
 {
   MOZ_ASSERT(NS_IsMainThread());
+
+  if (NextFrameBufferedStatus() == MediaDecoderOwner::NEXT_FRAME_UNAVAILABLE) {
+    return false;
+  }
+
   if (IsNaN(mMediaSource->Duration())) {
     // Don't have any data yet.
     return false;
   }
   TimeUnit duration = TimeUnit::FromSeconds(mMediaSource->Duration());
   TimeUnit currentPosition = TimeUnit::FromMicroseconds(CurrentPosition());
   if (duration.IsInfinite()) {
     // We can't make an informed decision and just assume that it's a live stream
--- a/dom/media/platforms/wmf/DXVA2Manager.cpp
+++ b/dom/media/platforms/wmf/DXVA2Manager.cpp
@@ -61,16 +61,21 @@ static const DWORD sAMDPreUVD4[] = {
   0x6850, 0x6858, 0x6859, 0x6760, 0x6761, 0x6762, 0x6763, 0x6764, 0x6765, 0x6766, 0x6767, 0x6768, 0x6770,
   0x6771, 0x6772, 0x6778, 0x6779, 0x677b, 0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x6705, 0x6706, 0x6707,
   0x6708, 0x6709, 0x6718, 0x6719, 0x671c, 0x671d, 0x671f, 0x9900, 0x9901, 0x9903, 0x9904, 0x9905, 0x9906,
   0x9907, 0x9908, 0x9909, 0x990a, 0x990b, 0x990c, 0x990d, 0x990e, 0x990f, 0x9910, 0x9913, 0x9917, 0x9918,
   0x9919, 0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998, 0x9999, 0x999a, 0x999b,
   0x999c, 0x999d, 0x99a0, 0x99a2, 0x99a4
 };
 
+// The size we use for our synchronization surface.
+// 16x16 is the size recommended by Microsoft (in the D3D9ExDXGISharedSurf sample) that works
+// best to avoid driver bugs.
+static const uint32_t kSyncSurfaceSize = 16;
+
 namespace mozilla {
 
 using layers::Image;
 using layers::ImageContainer;
 using layers::D3D9SurfaceImage;
 using layers::D3D9RecycleAllocator;
 using layers::D3D11ShareHandleImage;
 using layers::D3D11RecycleAllocator;
@@ -95,16 +100,17 @@ public:
   bool SupportsConfig(IMFMediaType* aType, float aFramerate) override;
 
 private:
   RefPtr<IDirect3D9Ex> mD3D9;
   RefPtr<IDirect3DDevice9Ex> mDevice;
   RefPtr<IDirect3DDeviceManager9> mDeviceManager;
   RefPtr<D3D9RecycleAllocator> mTextureClientAllocator;
   RefPtr<IDirectXVideoDecoderService> mDecoderService;
+  RefPtr<IDirect3DSurface9> mSyncSurface;
   GUID mDecoderGUID;
   UINT32 mResetToken;
   bool mFirstFrame;
   bool mIsAMDPreUVD4;
 };
 
 void GetDXVA2ExtendedFormatFromMFMediaType(IMFMediaType *pType,
                                            DXVA2_ExtendedFormat *pFormat)
@@ -387,22 +393,29 @@ D3D9DXVA2Manager::Init(nsACString& aFail
     for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sAMDPreUVD4); i++) {
       if (adapter.DeviceId == sAMDPreUVD4[i]) {
         mIsAMDPreUVD4 = true;
         break;
       }
     }
   }
 
+  RefPtr<IDirect3DSurface9> syncSurf;
+  hr = device->CreateRenderTarget(kSyncSurfaceSize, kSyncSurfaceSize,
+                                  D3DFMT_X8R8G8B8, D3DMULTISAMPLE_NONE,
+                                  0, TRUE, getter_AddRefs(syncSurf), NULL);
+  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+
   mDecoderService = decoderService;
 
   mResetToken = resetToken;
   mD3D9 = d3d9Ex;
   mDevice = device;
   mDeviceManager = deviceManager;
+  mSyncSurface = syncSurf;
 
   mTextureClientAllocator = new D3D9RecycleAllocator(layers::ImageBridgeChild::GetSingleton(),
                                                      mDevice);
   mTextureClientAllocator->SetMaxPoolSize(5);
 
   return S_OK;
 }
 
@@ -422,45 +435,30 @@ D3D9DXVA2Manager::CopyToImage(IMFSample*
                          IID_IDirect3DSurface9,
                          getter_AddRefs(surface));
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   RefPtr<D3D9SurfaceImage> image = new D3D9SurfaceImage();
   hr = image->AllocateAndCopy(mTextureClientAllocator, surface, aRegion);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
-  // Flush the draw command now, so that by the time we come to draw this
-  // image, we're less likely to need to wait for the draw operation to
-  // complete.
-  RefPtr<IDirect3DQuery9> query;
-  hr = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, getter_AddRefs(query));
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
-  hr = query->Issue(D3DISSUE_END);
+  RefPtr<IDirect3DSurface9> sourceSurf = image->GetD3D9Surface();
+
+  // Copy a small rect into our sync surface, and then map it
+  // to block until decoding/color conversion completes.
+  RECT copyRect = { 0, 0, kSyncSurfaceSize, kSyncSurfaceSize };
+  hr = mDevice->StretchRect(sourceSurf, &copyRect, mSyncSurface, &copyRect, D3DTEXF_NONE);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
-  bool valid = false;
-  int iterations = 0;
-  while (iterations < (mFirstFrame ? 100 : 10)) {
-    hr = query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
-    if (hr == S_FALSE) {
-      Sleep(1);
-      iterations++;
-      continue;
-    }
-    if (hr == S_OK) {
-      valid = true;
-    }
-    break;
-  }
+  D3DLOCKED_RECT lockedRect;
+  hr = mSyncSurface->LockRect(&lockedRect, NULL, D3DLOCK_READONLY);
+  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
-  mFirstFrame = false;
-
-  if (!valid) {
-    image->Invalidate();
-  }
+  hr = mSyncSurface->UnlockRect();
+  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   image.forget(aOutImage);
   return S_OK;
 }
 
 // Count of the number of DXVAManager's we've created. This is also the
 // number of videos we're decoding with DXVA. Use on main thread only.
 static uint32_t sDXVAVideosCount = 0;
@@ -520,16 +518,17 @@ private:
   HRESULT CreateOutputSample(RefPtr<IMFSample>& aSample,
                              ID3D11Texture2D* aTexture);
 
   RefPtr<ID3D11Device> mDevice;
   RefPtr<ID3D11DeviceContext> mContext;
   RefPtr<IMFDXGIDeviceManager> mDXGIDeviceManager;
   RefPtr<MFTDecoder> mTransform;
   RefPtr<D3D11RecycleAllocator> mTextureClientAllocator;
+  RefPtr<ID3D11Texture2D> mSyncSurface;
   GUID mDecoderGUID;
   uint32_t mWidth;
   uint32_t mHeight;
   UINT mDeviceManagerToken;
   bool mIsAMDPreUVD4;
 };
 
 bool
@@ -699,16 +698,32 @@ D3D11DXVA2Manager::Init(nsACString& aFai
     for (size_t i = 0; i < MOZ_ARRAY_LENGTH(sAMDPreUVD4); i++) {
       if (adapterDesc.DeviceId == sAMDPreUVD4[i]) {
         mIsAMDPreUVD4 = true;
         break;
       }
     }
   }
 
+  D3D11_TEXTURE2D_DESC desc;
+  desc.Width = kSyncSurfaceSize;
+  desc.Height = kSyncSurfaceSize;
+  desc.MipLevels = 1;
+  desc.ArraySize = 1;
+  desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+  desc.SampleDesc.Count = 1;
+  desc.SampleDesc.Quality = 0;
+  desc.Usage = D3D11_USAGE_STAGING;
+  desc.BindFlags = 0;
+  desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
+  desc.MiscFlags = 0;
+
+  hr = mDevice->CreateTexture2D(&desc, NULL, getter_AddRefs(mSyncSurface));
+  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+
   mTextureClientAllocator = new D3D11RecycleAllocator(layers::ImageBridgeChild::GetSingleton(),
                                                       mDevice);
   mTextureClientAllocator->SetMaxPoolSize(5);
 
   return S_OK;
 }
 
 HRESULT
@@ -750,27 +765,31 @@ D3D11DXVA2Manager::CopyToImage(IMFSample
   HRESULT hr = mTransform->Input(aVideoSample);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   RefPtr<IMFSample> sample;
   RefPtr<ID3D11Texture2D> texture = image->GetTexture();
   hr = CreateOutputSample(sample, texture);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
-  RefPtr<IDXGIKeyedMutex> keyedMutex;
-  hr = texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(getter_AddRefs(keyedMutex)));
-  NS_ENSURE_TRUE(SUCCEEDED(hr) && keyedMutex, hr);
+  hr = mTransform->Output(&sample);
+
+  RefPtr<ID3D11DeviceContext> ctx;
+  mDevice->GetImmediateContext(getter_AddRefs(ctx));
 
-  hr = keyedMutex->AcquireSync(0, INFINITE);
+  // Copy a small rect into our sync surface, and then map it
+  // to block until decoding/color conversion completes.
+  D3D11_BOX rect = { 0, 0, 0, kSyncSurfaceSize, kSyncSurfaceSize, 1 };
+  ctx->CopySubresourceRegion(mSyncSurface, 0, 0, 0, 0, texture, 0, &rect);
+
+  D3D11_MAPPED_SUBRESOURCE mapped;
+  hr = ctx->Map(mSyncSurface, 0, D3D11_MAP_READ, 0, &mapped);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
-  hr = mTransform->Output(&sample);
-
-  keyedMutex->ReleaseSync(0);
-  NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
+  ctx->Unmap(mSyncSurface, 0);
 
   image.forget(aOutImage);
 
   return S_OK;
 }
 
 HRESULT ConfigureOutput(IMFMediaType* aOutput, void* aData)
 {
--- a/dom/media/test/external/external_media_harness/runtests.py
+++ b/dom/media/test/external/external_media_harness/runtests.py
@@ -22,25 +22,27 @@ class MediaTestArgumentsBase(object):
         [['--urls'], {
             'help': 'ini file of urls to make available to all tests',
             'default': os.path.join(external_media_tests.urls, 'default.ini'),
         }],
     ]
 
     def verify_usage_handler(self, args):
         if args.urls:
-           if not os.path.isfile(args.urls):
-               raise ValueError('--urls must provide a path to an ini file')
-           else:
-               path = os.path.abspath(args.urls)
-               args.video_urls = MediaTestArgumentsBase.get_urls(path)
+            if not os.path.isfile(args.urls):
+                raise ValueError('--urls must provide a path to an ini file')
+            else:
+                path = os.path.abspath(args.urls)
+                args.video_urls = MediaTestArgumentsBase.get_urls(path)
+                if not args.video_urls:
+                    raise ValueError('list of video URLs cannot be empty')
 
     def parse_args_handler(self, args):
         if not args.tests:
-           args.tests = [external_media_tests.manifest]
+            args.tests = [external_media_tests.manifest]
 
 
     @staticmethod
     def get_urls(manifest):
         with open(manifest, 'r'):
             return [line[0] for line in read_ini(manifest)]
 
 
--- a/dom/media/test/external/mach_commands.py
+++ b/dom/media/test/external/mach_commands.py
@@ -45,17 +45,17 @@ def run_external_media_test(tests, testt
         setattr(args, k, v)
 
     parser.verify_usage(args)
 
     args.logger = commandline.setup_logging("Firefox External Media Tests",
                                             args,
                                             {"mach": sys.stdout})
     failed = mn_cli(MediaTestRunner, MediaTestArguments, FirefoxMediaHarness,
-                    args=args)
+                    args=vars(args))
 
     if failed > 0:
         return 1
     else:
         return 0
 
 
 @CommandProvider
--- a/dom/svg/SVGContentUtils.cpp
+++ b/dom/svg/SVGContentUtils.cpp
@@ -335,19 +335,18 @@ SVGContentUtils::GetFontXHeight(nsIFrame
 float
 SVGContentUtils::GetFontXHeight(nsStyleContext *aStyleContext)
 {
   MOZ_ASSERT(aStyleContext, "NULL style context in GetFontXHeight");
 
   nsPresContext *presContext = aStyleContext->PresContext();
   MOZ_ASSERT(presContext, "NULL pres context in GetFontXHeight");
 
-  RefPtr<nsFontMetrics> fontMetrics;
-  nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext,
-                                               getter_AddRefs(fontMetrics));
+  RefPtr<nsFontMetrics> fontMetrics =
+    nsLayoutUtils::GetFontMetricsForStyleContext(aStyleContext);
 
   if (!fontMetrics) {
     // ReportToConsole
     NS_WARNING("no FontMetrics in GetFontXHeight()");
     return 1.0f;
   }
 
   nscoord xHeight = fontMetrics->XHeight();
--- a/dom/webidl/CustomEvent.webidl
+++ b/dom/webidl/CustomEvent.webidl
@@ -5,17 +5,18 @@
  *
  * The origin of this IDL file is
  * http://www.w3.org/TR/2012/WD-dom-20120105/
  *
  * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
  * liability, trademark and document use rules apply.
  */
 
-[Constructor(DOMString type, optional CustomEventInit eventInitDict)]
+[Constructor(DOMString type, optional CustomEventInit eventInitDict),
+ Exposed=(Window, Worker)]
 interface CustomEvent : Event
 {
   readonly attribute any detail;
 
   // initCustomEvent is a Gecko specific deprecated method.
   [Throws]
   void initCustomEvent(DOMString type,
                        boolean canBubble,
--- a/dom/webidl/Node.webidl
+++ b/dom/webidl/Node.webidl
@@ -32,16 +32,18 @@ interface Node : EventTarget {
   readonly attribute DOMString nodeName;
 
   [Pure]
   readonly attribute DOMString? baseURI;
 
   [Pure]
   readonly attribute Document? ownerDocument;
   [Pure]
+  readonly attribute Node rootNode;
+  [Pure]
   readonly attribute Node? parentNode;
   [Pure]
   readonly attribute Element? parentElement;
   [Pure]
   boolean hasChildNodes();
   [SameObject]
   readonly attribute NodeList childNodes;
   [Pure]
--- a/dom/workers/ServiceWorkerPrivate.cpp
+++ b/dom/workers/ServiceWorkerPrivate.cpp
@@ -21,17 +21,19 @@
 #include "WorkerRunnable.h"
 #include "WorkerScope.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/dom/FetchUtil.h"
 #include "mozilla/dom/IndexedDatabaseManager.h"
 #include "mozilla/dom/InternalHeaders.h"
 #include "mozilla/dom/NotificationEvent.h"
 #include "mozilla/dom/PromiseNativeHandler.h"
+#ifndef MOZ_SIMPLEPUSH
 #include "mozilla/dom/PushEventBinding.h"
+#endif
 #include "mozilla/dom/RequestBinding.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 BEGIN_WORKERS_NAMESPACE
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(ServiceWorkerPrivate)
--- a/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
+++ b/dom/workers/test/serviceworkers/test_serviceworker_interfaces.js
@@ -84,16 +84,18 @@ var interfaceNamesInGlobalScope =
     "Cache",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "CacheStorage",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Client",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Clients",
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    "CustomEvent",
+// IMPORTANT: Do not change this list without review from a DOM peer!
     { name: "DataStore", b2g: true },
 // IMPORTANT: Do not change this list without review from a DOM peer!
     { name: "DataStoreCursor", b2g: true },
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMCursor",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMError",
 // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/dom/workers/test/test_worker_interfaces.js
+++ b/dom/workers/test/test_worker_interfaces.js
@@ -80,16 +80,18 @@ var interfaceNamesInGlobalScope =
     "Blob",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "BroadcastChannel",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "Cache",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "CacheStorage",
 // IMPORTANT: Do not change this list without review from a DOM peer!
+    "CustomEvent",
+// IMPORTANT: Do not change this list without review from a DOM peer!
     "DedicatedWorkerGlobalScope",
 // IMPORTANT: Do not change this list without review from a DOM peer!
     { name: "DataStore", b2g: true },
 // IMPORTANT: Do not change this list without review from a DOM peer!
     { name: "DataStoreCursor", b2g: true },
 // IMPORTANT: Do not change this list without review from a DOM peer!
     "DOMCursor",
 // IMPORTANT: Do not change this list without review from a DOM peer!
--- a/editor/reftests/xul/reftest.list
+++ b/editor/reftests/xul/reftest.list
@@ -1,29 +1,29 @@
-fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == empty-1.xul empty-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == empty-1.xul empty-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop, Windows: bug 1239170
 skip-if((B2G&&browserIsRemote)||Mulet) != empty-2.xul empty-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 # There is no way to simulate an autocomplete textbox in windows XP/Vista/7/8/10 default theme using CSS.
 # Therefore, the equlity tests below should be marked as failing.
 fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == autocomplete-1.xul autocomplete-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == emptyautocomplete-1.xul emptyautocomplete-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != emptymultiline-1.xul emptymultiline-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == emptymultiline-2.xul emptymultiline-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == emptytextbox-1.xul emptytextbox-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == emptytextbox-2.xul emptytextbox-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == emptytextbox-1.xul emptytextbox-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop, Windows: bug 1239170
+fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == emptytextbox-2.xul emptytextbox-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop, Windows: bug 1239170
 skip-if((B2G&&browserIsRemote)||Mulet) != emptytextbox-3.xul emptytextbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != emptytextbox-4.xul emptytextbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == emptytextbox-5.xul emptytextbox-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == emptytextbox-5.xul emptytextbox-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop, Windows: bug 1239170
 # There is no way to simulate a number textbox in windows XP/Vista/7 default theme using CSS.
 # Therefore, the equlity tests below should be marked as failing.
 skip-if((B2G&&browserIsRemote)||Mulet) != number-1.xul number-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != number-2.xul number-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == number-3.xul number-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 skip-if((B2G&&browserIsRemote)||Mulet) != number-4.xul number-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == number-5.xul number-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(5\.[12]|6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet) == numberwithvalue-1.xul numberwithvalue-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == passwd-1.xul passwd-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == passwd-2.xul passwd-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == passwd-1.xul passwd-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop, Windows: bug 1239170
+fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||((browserIsRemote&&winWidget))) == passwd-2.xul passwd-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop, Windows: bug 1239170
 skip-if((B2G&&browserIsRemote)||Mulet) != passwd-3.xul passwd-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet) == plain-1.xul plain-ref.xul # bug 783658 # Initial mulet triage: parity with B2G/B2G Desktop
-fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||(browserIsRemote&&winWidget)) == textbox-1.xul textbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(Android||B2G) skip-if((B2G&&browserIsRemote)||Mulet||(browserIsRemote&&winWidget)) == textbox-1.xul textbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop, Windows: bug 1239170
 skip-if((B2G&&browserIsRemote)||Mulet) != textbox-disabled.xul textbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 # Read-only textboxes look like normal textboxes in windows Vista/7 default theme
-fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet||(browserIsRemote&&winWidget)) != textbox-readonly.xul textbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
+fails-if(windowsDefaultTheme&&/^Windows\x20NT\x20(6\.[012]|10\.0)/.test(http.oscpu)) skip-if((B2G&&browserIsRemote)||Mulet||(browserIsRemote&&winWidget)) != textbox-readonly.xul textbox-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop, Windows: bug 1239170
--- a/gfx/2d/DrawTargetD2D1.cpp
+++ b/gfx/2d/DrawTargetD2D1.cpp
@@ -1635,17 +1635,17 @@ DrawTargetD2D1::CreateBrushForPattern(co
       // with source format A8. This creates a BGRA surface with the same alpha values that
       // the A8 surface has.
       RefPtr<ID2D1Bitmap> bitmap;
       image->QueryInterface((ID2D1Bitmap**)getter_AddRefs(bitmap));
       if (bitmap) {
         RefPtr<ID2D1Image> oldTarget;
         RefPtr<ID2D1Bitmap1> tmpBitmap;
         mDC->CreateBitmap(D2D1::SizeU(pat->mSurface->GetSize().width, pat->mSurface->GetSize().height), nullptr, 0,
-                          &D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED)),
+                          D2D1::BitmapProperties1(D2D1_BITMAP_OPTIONS_TARGET, D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED)),
                           getter_AddRefs(tmpBitmap));
         mDC->GetTarget(getter_AddRefs(oldTarget));
         mDC->SetTarget(tmpBitmap);
 
         RefPtr<ID2D1SolidColorBrush> brush;
         mDC->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), getter_AddRefs(brush));
         mDC->FillOpacityMask(bitmap, brush);
         mDC->SetTarget(oldTarget);
--- a/gfx/2d/JobScheduler_posix.cpp
+++ b/gfx/2d/JobScheduler_posix.cpp
@@ -74,17 +74,17 @@ MultiThreadedJobQueue::WaitForJob(Job*& 
 {
   return PopJob(aOutJob, BLOCKING);
 }
 
 bool
 MultiThreadedJobQueue::PopJob(Job*& aOutJobs, AccessType aAccess)
 {
   for (;;) {
-    MutexAutoLock lock(&mMutex);
+    CriticalSectionAutoEnter lock(&mMutex);
 
     while (aAccess == BLOCKING && !mShuttingDown && mJobs.empty()) {
       mAvailableCondvar.Wait(&mMutex);
     }
 
     if (mShuttingDown) {
       return false;
     }
@@ -105,90 +105,90 @@ MultiThreadedJobQueue::PopJob(Job*& aOut
     return true;
   }
 }
 
 void
 MultiThreadedJobQueue::SubmitJob(Job* aJobs)
 {
   MOZ_ASSERT(aJobs);
-  MutexAutoLock lock(&mMutex);
+  CriticalSectionAutoEnter lock(&mMutex);
   mJobs.push_back(aJobs);
   mAvailableCondvar.Broadcast();
 }
 
 size_t
 MultiThreadedJobQueue::NumJobs()
 {
-  MutexAutoLock lock(&mMutex);
+  CriticalSectionAutoEnter lock(&mMutex);
   return mJobs.size();
 }
 
 bool
 MultiThreadedJobQueue::IsEmpty()
 {
-  MutexAutoLock lock(&mMutex);
+  CriticalSectionAutoEnter lock(&mMutex);
   return mJobs.empty();
 }
 
 void
 MultiThreadedJobQueue::ShutDown()
 {
-  MutexAutoLock lock(&mMutex);
+  CriticalSectionAutoEnter lock(&mMutex);
   mShuttingDown = true;
   while (mThreadsCount) {
     mAvailableCondvar.Broadcast();
     mShutdownCondvar.Wait(&mMutex);
   }
 }
 
 void
 MultiThreadedJobQueue::RegisterThread()
 {
   mThreadsCount += 1;
 }
 
 void
 MultiThreadedJobQueue::UnregisterThread()
 {
-  MutexAutoLock lock(&mMutex);
+  CriticalSectionAutoEnter lock(&mMutex);
   mThreadsCount -= 1;
   if (mThreadsCount == 0) {
     mShutdownCondvar.Broadcast();
   }
 }
 
 EventObject::EventObject()
 : mIsSet(false)
 {}
 
 EventObject::~EventObject()
 {}
 
 bool
 EventObject::Peak()
 {
-  MutexAutoLock lock(&mMutex);
+  CriticalSectionAutoEnter lock(&mMutex);
   return mIsSet;
 }
 
 void
 EventObject::Set()
 {
-  MutexAutoLock lock(&mMutex);
+  CriticalSectionAutoEnter lock(&mMutex);
   if (!mIsSet) {
     mIsSet = true;
     mCond.Broadcast();
   }
 }
 
 void
 EventObject::Wait()
 {
-  MutexAutoLock lock(&mMutex);
+  CriticalSectionAutoEnter lock(&mMutex);
   if (mIsSet) {
     return;
   }
   mCond.Wait(&mMutex);
 }
 
 } // namespce
 } // namespce
--- a/gfx/2d/JobScheduler_posix.h
+++ b/gfx/2d/JobScheduler_posix.h
@@ -21,33 +21,30 @@
 
 namespace mozilla {
 namespace gfx {
 
 class Job;
 class PosixCondVar;
 class WorkerThread;
 
-typedef mozilla::gfx::CriticalSection Mutex;
-typedef mozilla::gfx::CriticalSectionAutoEnter MutexAutoLock;
-
 // posix platforms only!
 class PosixCondVar {
 public:
   PosixCondVar() {
     DebugOnly<int> err = pthread_cond_init(&mCond, nullptr);
     MOZ_ASSERT(!err);
   }
 
   ~PosixCondVar() {
     DebugOnly<int> err = pthread_cond_destroy(&mCond);
     MOZ_ASSERT(!err);
   }
 
-  void Wait(Mutex* aMutex) {
+  void Wait(CriticalSection* aMutex) {
     DebugOnly<int> err = pthread_cond_wait(&mCond, &aMutex->mMutex);
     MOZ_ASSERT(!err);
   }
 
   void Broadcast() {
     DebugOnly<int> err = pthread_cond_broadcast(&mCond);
     MOZ_ASSERT(!err);
   }
@@ -96,17 +93,17 @@ public:
   void RegisterThread();
 
   // Worker threads
   void UnregisterThread();
 
 protected:
 
   std::list<Job*> mJobs;
-  Mutex mMutex;
+  CriticalSection mMutex;
   PosixCondVar mAvailableCondvar;
   PosixCondVar mShutdownCondvar;
   int32_t mThreadsCount;
   bool mShuttingDown;
 
   friend class WorkerThread;
 };
 
@@ -126,17 +123,17 @@ public:
 
   /// Return true if the event is set, without blocking.
   bool Peak();
 
   /// Set the event.
   void Set();
 
 protected:
-  Mutex mMutex;
+  CriticalSection mMutex;
   PosixCondVar mCond;
   bool mIsSet;
 };
 
 } // namespace
 } // namespace
 
 #include "JobScheduler.h"
--- a/gfx/2d/RadialGradientEffectD2D1.cpp
+++ b/gfx/2d/RadialGradientEffectD2D1.cpp
@@ -148,23 +148,23 @@ RadialGradientEffectD2D1::PrepareForRend
     float radius1;
     float sq_radius1;
     float repeat_correct;
     float allow_odd;
     float padding2[1];
     float transform[8];
   };
 
-  PSConstantBuffer buffer = { { dc.x, dc.y, dr }, 0,
+  PSConstantBuffer buffer = { { dc.x, dc.y, dr }, 0.0f,
                               { mCenter1.x, mCenter1.y },
                               A, mRadius1, mRadius1 * mRadius1,
-                              mStopCollection->GetExtendMode() != D2D1_EXTEND_MODE_CLAMP ? 1 : 0,
-                              mStopCollection->GetExtendMode() == D2D1_EXTEND_MODE_MIRROR ? 1 : 0,
-                              { 0 }, { mat._11, mat._21, mat._31, 0,
-                                             mat._12, mat._22, mat._32, 0 } };
+                              mStopCollection->GetExtendMode() != D2D1_EXTEND_MODE_CLAMP ? 1.0f : 0.0f,
+                              mStopCollection->GetExtendMode() == D2D1_EXTEND_MODE_MIRROR ? 1.0f : 0.0f,
+                              { 0.0f }, { mat._11, mat._21, mat._31, 0.0f,
+                                             mat._12, mat._22, mat._32, 0.0f } };
 
   hr = mDrawInfo->SetPixelShaderConstantBuffer((BYTE*)&buffer, sizeof(buffer));
 
   if (FAILED(hr)) {
     return hr;
   }
 
   return S_OK;
--- a/gfx/gl/SharedSurface.cpp
+++ b/gfx/gl/SharedSurface.cpp
@@ -283,17 +283,17 @@ ChooseBufferBits(const SurfaceCaps& caps
     } else {
         out_drawCaps->Clear();
         *out_readCaps = screenCaps;
     }
 }
 
 SurfaceFactory::SurfaceFactory(SharedSurfaceType type, GLContext* gl,
                                const SurfaceCaps& caps,
-                               const RefPtr<layers::ISurfaceAllocator>& allocator,
+                               const RefPtr<layers::ClientIPCAllocator>& allocator,
                                const layers::TextureFlags& flags)
     : mType(type)
     , mGL(gl)
     , mCaps(caps)
     , mAllocator(allocator)
     , mFlags(flags)
     , mFormats(gl->ChooseGLFormats(caps))
     , mMutex("SurfaceFactor::mMutex")
--- a/gfx/gl/SharedSurface.h
+++ b/gfx/gl/SharedSurface.h
@@ -34,17 +34,17 @@ class nsIThread;
 
 namespace mozilla {
 namespace gfx {
 class DataSourceSurface;
 class DrawTarget;
 } // namespace gfx
 
 namespace layers {
-class ISurfaceAllocator;
+class ClientIPCAllocator;
 class SharedSurfaceTextureClient;
 enum class TextureFlags : uint32_t;
 class SurfaceDescriptor;
 class TextureClient;
 } // namespace layers
 
 namespace gl {
 
@@ -264,28 +264,28 @@ class SurfaceFactory : public SupportsWe
 public:
     // Should use the VIRTUAL version, but it's currently incompatible
     // with SupportsWeakPtr. (bug 1049278)
     MOZ_DECLARE_WEAKREFERENCE_TYPENAME(SurfaceFactory)
 
     const SharedSurfaceType mType;
     GLContext* const mGL;
     const SurfaceCaps mCaps;
-    const RefPtr<layers::ISurfaceAllocator> mAllocator;
+    const RefPtr<layers::ClientIPCAllocator> mAllocator;
     const layers::TextureFlags mFlags;
     const GLFormats mFormats;
     Mutex mMutex;
 protected:
     SurfaceCaps mDrawCaps;
     SurfaceCaps mReadCaps;
     RefQueue<layers::SharedSurfaceTextureClient> mRecycleFreePool;
     RefSet<layers::SharedSurfaceTextureClient> mRecycleTotalPool;
 
     SurfaceFactory(SharedSurfaceType type, GLContext* gl, const SurfaceCaps& caps,
-                   const RefPtr<layers::ISurfaceAllocator>& allocator,
+                   const RefPtr<layers::ClientIPCAllocator>& allocator,
                    const layers::TextureFlags& flags);
 
 public:
     virtual ~SurfaceFactory();
 
     const SurfaceCaps& DrawCaps() const {
         return mDrawCaps;
     }
--- a/gfx/gl/SharedSurfaceANGLE.cpp
+++ b/gfx/gl/SharedSurfaceANGLE.cpp
@@ -204,17 +204,21 @@ public:
             }
 
             if (FAILED(hr)) {
                 NS_WARNING("Failed to lock the texture");
                 return;
             }
         }
 
-        ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11Device();
+        RefPtr<ID3D11Device> device;
+        if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device)) {
+            return;
+        }
+
         device->GetImmediateContext(getter_AddRefs(mDeviceContext));
 
         mTexture->GetDesc(&mDesc);
         mDesc.BindFlags = 0;
         mDesc.Usage = D3D11_USAGE_STAGING;
         mDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
         mDesc.MiscFlags = 0;
 
@@ -255,18 +259,23 @@ public:
     D3D11_TEXTURE2D_DESC mDesc;
     D3D11_MAPPED_SUBRESOURCE mSubresource;
 };
 
 bool
 SharedSurface_ANGLEShareHandle::ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface)
 {
     MOZ_ASSERT(out_surface);
+
+    RefPtr<ID3D11Device> device;
+    if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device)) {
+        return false;
+    }
+
     RefPtr<ID3D11Texture2D> tex;
-    ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11Device();
     HRESULT hr = device->OpenSharedResource(mShareHandle,
                                             __uuidof(ID3D11Texture2D),
                                             (void**)(ID3D11Texture2D**)getter_AddRefs(tex));
 
     if (FAILED(hr)) {
         return false;
     }
 
@@ -316,17 +325,17 @@ SharedSurface_ANGLEShareHandle::Readback
     return true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // Factory
 
 /*static*/ UniquePtr<SurfaceFactory_ANGLEShareHandle>
 SurfaceFactory_ANGLEShareHandle::Create(GLContext* gl, const SurfaceCaps& caps,
-                                        const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                        const RefPtr<layers::ClientIPCAllocator>& allocator,
                                         const layers::TextureFlags& flags)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
     if (!egl)
         return nullptr;
 
     auto ext = GLLibraryEGL::ANGLE_surface_d3d_texture_2d_share_handle;
     if (!egl->IsExtensionSupported(ext))
@@ -336,17 +345,17 @@ SurfaceFactory_ANGLEShareHandle::Create(
 
     typedef SurfaceFactory_ANGLEShareHandle ptrT;
     UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, egl, config) );
     return Move(ret);
 }
 
 SurfaceFactory_ANGLEShareHandle::SurfaceFactory_ANGLEShareHandle(GLContext* gl,
                                                                  const SurfaceCaps& caps,
-                                                                 const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                                 const RefPtr<layers::ClientIPCAllocator>& allocator,
                                                                  const layers::TextureFlags& flags,
                                                                  GLLibraryEGL* egl,
                                                                  EGLConfig config)
     : SurfaceFactory(SharedSurfaceType::EGLSurfaceANGLE, gl, caps, allocator, flags)
     , mProdGL(gl)
     , mEGL(egl)
     , mConfig(config)
 { }
--- a/gfx/gl/SharedSurfaceANGLE.h
+++ b/gfx/gl/SharedSurfaceANGLE.h
@@ -84,22 +84,22 @@ class SurfaceFactory_ANGLEShareHandle
 protected:
     GLContext* const mProdGL;
     GLLibraryEGL* const mEGL;
     const EGLConfig mConfig;
 
 public:
     static UniquePtr<SurfaceFactory_ANGLEShareHandle> Create(GLContext* gl,
                                                              const SurfaceCaps& caps,
-                                                             const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                             const RefPtr<layers::ClientIPCAllocator>& allocator,
                                                              const layers::TextureFlags& flags);
 
 protected:
     SurfaceFactory_ANGLEShareHandle(GLContext* gl, const SurfaceCaps& caps,
-                                    const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                    const RefPtr<layers::ClientIPCAllocator>& allocator,
                                     const layers::TextureFlags& flags, GLLibraryEGL* egl,
                                     EGLConfig config);
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
         bool hasAlpha = mReadCaps.alpha;
         return SharedSurface_ANGLEShareHandle::Create(mProdGL, mConfig, size, hasAlpha);
     }
 };
--- a/gfx/gl/SharedSurfaceD3D11Interop.cpp
+++ b/gfx/gl/SharedSurfaceD3D11Interop.cpp
@@ -368,17 +368,17 @@ SharedSurface_D3D11Interop::ToSurfaceDes
     return true;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
 // Factory
 
 /*static*/ UniquePtr<SurfaceFactory_D3D11Interop>
 SurfaceFactory_D3D11Interop::Create(GLContext* gl, const SurfaceCaps& caps,
-                                    const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                    const RefPtr<layers::ClientIPCAllocator>& allocator,
                                     const layers::TextureFlags& flags)
 {
     WGLLibrary* wgl = &sWGLLib;
     if (!wgl || !wgl->HasDXInterop2())
         return nullptr;
 
     RefPtr<DXGLDevice> dxgl = DXGLDevice::Open(wgl);
     if (!dxgl) {
@@ -389,17 +389,17 @@ SurfaceFactory_D3D11Interop::Create(GLCo
     typedef SurfaceFactory_D3D11Interop ptrT;
     UniquePtr<ptrT> ret(new ptrT(gl, caps, allocator, flags, dxgl));
 
     return Move(ret);
 }
 
 SurfaceFactory_D3D11Interop::SurfaceFactory_D3D11Interop(GLContext* gl,
                                                          const SurfaceCaps& caps,
-                                                         const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                         const RefPtr<layers::ClientIPCAllocator>& allocator,
                                                          const layers::TextureFlags& flags,
                                                          const RefPtr<DXGLDevice>& dxgl)
     : SurfaceFactory(SharedSurfaceType::DXGLInterop2, gl, caps, allocator, flags)
     , mDXGL(dxgl)
 { }
 
 SurfaceFactory_D3D11Interop::~SurfaceFactory_D3D11Interop()
 { }
--- a/gfx/gl/SharedSurfaceD3D11Interop.h
+++ b/gfx/gl/SharedSurfaceD3D11Interop.h
@@ -80,22 +80,22 @@ public:
 class SurfaceFactory_D3D11Interop
     : public SurfaceFactory
 {
 public:
     const RefPtr<DXGLDevice> mDXGL;
 
     static UniquePtr<SurfaceFactory_D3D11Interop> Create(GLContext* gl,
                                                          const SurfaceCaps& caps,
-                                                         const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                         const RefPtr<layers::ClientIPCAllocator>& allocator,
                                                          const layers::TextureFlags& flags);
 
 protected:
     SurfaceFactory_D3D11Interop(GLContext* gl, const SurfaceCaps& caps,
-                                const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                const RefPtr<layers::ClientIPCAllocator>& allocator,
                                 const layers::TextureFlags& flags,
                                 const RefPtr<DXGLDevice>& dxgl);
 
 public:
     virtual ~SurfaceFactory_D3D11Interop();
 
 protected:
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
--- a/gfx/gl/SharedSurfaceEGL.cpp
+++ b/gfx/gl/SharedSurfaceEGL.cpp
@@ -34,17 +34,17 @@ SharedSurface_EGLImage::Create(GLContext
     }
 
     MOZ_ALWAYS_TRUE(prodGL->MakeCurrent());
     GLuint prodTex = CreateTextureForOffscreen(prodGL, formats, size);
     if (!prodTex) {
         return Move(ret);
     }
 
-    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(prodTex);
+    EGLClientBuffer buffer = reinterpret_cast<EGLClientBuffer>(uintptr_t(prodTex));
     EGLImage image = egl->fCreateImage(egl->Display(), context,
                                        LOCAL_EGL_GL_TEXTURE_2D, buffer,
                                        nullptr);
     if (!image) {
         prodGL->fDeleteTextures(1, &prodTex);
         return Move(ret);
     }
 
@@ -192,17 +192,17 @@ SharedSurface_EGLImage::ReadbackByShared
     MOZ_ASSERT(NS_IsMainThread());
     return sEGLLibrary.ReadbackEGLImage(mImage, out_surface);
 }
 
 ////////////////////////////////////////////////////////////////////////
 
 /*static*/ UniquePtr<SurfaceFactory_EGLImage>
 SurfaceFactory_EGLImage::Create(GLContext* prodGL, const SurfaceCaps& caps,
-                                const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                const RefPtr<layers::ClientIPCAllocator>& allocator,
                                 const layers::TextureFlags& flags)
 {
     EGLContext context = GLContextEGL::Cast(prodGL)->mContext;
 
     typedef SurfaceFactory_EGLImage ptrT;
     UniquePtr<ptrT> ret;
 
     GLLibraryEGL* egl = &sEGLLibrary;
--- a/gfx/gl/SharedSurfaceEGL.h
+++ b/gfx/gl/SharedSurfaceEGL.h
@@ -91,24 +91,24 @@ public:
 
 class SurfaceFactory_EGLImage
     : public SurfaceFactory
 {
 public:
     // Fallible:
     static UniquePtr<SurfaceFactory_EGLImage> Create(GLContext* prodGL,
                                                      const SurfaceCaps& caps,
-                                                     const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                     const RefPtr<layers::ClientIPCAllocator>& allocator,
                                                      const layers::TextureFlags& flags);
 
 protected:
     const EGLContext mContext;
 
     SurfaceFactory_EGLImage(GLContext* prodGL, const SurfaceCaps& caps,
-                            const RefPtr<layers::ISurfaceAllocator>& allocator,
+                            const RefPtr<layers::ClientIPCAllocator>& allocator,
                             const layers::TextureFlags& flags,
                             EGLContext context)
         : SurfaceFactory(SharedSurfaceType::EGLImageShare, prodGL, caps, allocator, flags)
         , mContext(context)
     { }
 
 public:
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
--- a/gfx/gl/SharedSurfaceGL.h
+++ b/gfx/gl/SharedSurfaceGL.h
@@ -144,17 +144,17 @@ public:
 };
 
 class SurfaceFactory_GLTexture
     : public SurfaceFactory
 {
 public:
     SurfaceFactory_GLTexture(GLContext* prodGL,
                              const SurfaceCaps& caps,
-                             const RefPtr<layers::ISurfaceAllocator>& allocator,
+                             const RefPtr<layers::ClientIPCAllocator>& allocator,
                              const layers::TextureFlags& flags)
         : SurfaceFactory(SharedSurfaceType::SharedGLTexture, prodGL, caps, allocator, flags)
     {
     }
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
         bool hasAlpha = mReadCaps.alpha;
         return SharedSurface_GLTexture::Create(mGL, mFormats, size, hasAlpha);
--- a/gfx/gl/SharedSurfaceGLX.cpp
+++ b/gfx/gl/SharedSurfaceGLX.cpp
@@ -115,17 +115,17 @@ SharedSurface_GLXDrawable::ReadbackBySha
 
     return true;
 }
 
 /* static */
 UniquePtr<SurfaceFactory_GLXDrawable>
 SurfaceFactory_GLXDrawable::Create(GLContext* prodGL,
                                    const SurfaceCaps& caps,
-                                   const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                   const RefPtr<layers::ClientIPCAllocator>& allocator,
                                    const layers::TextureFlags& flags)
 {
     MOZ_ASSERT(caps.alpha, "GLX surfaces require an alpha channel!");
 
     typedef SurfaceFactory_GLXDrawable ptrT;
     UniquePtr<ptrT> ret(new ptrT(prodGL, caps, allocator,
                                  flags & ~layers::TextureFlags::ORIGIN_BOTTOM_LEFT));
     return Move(ret);
--- a/gfx/gl/SharedSurfaceGLX.h
+++ b/gfx/gl/SharedSurfaceGLX.h
@@ -44,24 +44,24 @@ private:
 };
 
 class SurfaceFactory_GLXDrawable
     : public SurfaceFactory
 {
 public:
     static UniquePtr<SurfaceFactory_GLXDrawable> Create(GLContext* prodGL,
                                                         const SurfaceCaps& caps,
-                                                        const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                        const RefPtr<layers::ClientIPCAllocator>& allocator,
                                                         const layers::TextureFlags& flags);
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
 
 private:
     SurfaceFactory_GLXDrawable(GLContext* prodGL, const SurfaceCaps& caps,
-                               const RefPtr<layers::ISurfaceAllocator>& allocator,
+                               const RefPtr<layers::ClientIPCAllocator>& allocator,
                                const layers::TextureFlags& flags)
         : SurfaceFactory(SharedSurfaceType::GLXDrawable, prodGL, caps, allocator, flags)
     { }
 };
 
 } // namespace gl
 } // namespace mozilla
 
--- a/gfx/gl/SharedSurfaceGralloc.cpp
+++ b/gfx/gl/SharedSurfaceGralloc.cpp
@@ -30,30 +30,30 @@
 
 namespace mozilla {
 namespace gl {
 
 using namespace mozilla::layers;
 using namespace android;
 
 SurfaceFactory_Gralloc::SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps,
-                                               const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                               const RefPtr<layers::ClientIPCAllocator>& allocator,
                                                const layers::TextureFlags& flags)
     : SurfaceFactory(SharedSurfaceType::Gralloc, prodGL, caps, allocator, flags)
 {
     MOZ_ASSERT(mAllocator);
 }
 
 /*static*/ UniquePtr<SharedSurface_Gralloc>
 SharedSurface_Gralloc::Create(GLContext* prodGL,
                               const GLFormats& formats,
                               const gfx::IntSize& size,
                               bool hasAlpha,
                               layers::TextureFlags flags,
-                              ISurfaceAllocator* allocator)
+                              ClientIPCAllocator* allocator)
 {
     GLLibraryEGL* egl = &sEGLLibrary;
     MOZ_ASSERT(egl);
 
     UniquePtr<SharedSurface_Gralloc> ret;
 
     DEBUG_PRINT("SharedSurface_Gralloc::Create -------\n");
 
@@ -113,17 +113,17 @@ SharedSurface_Gralloc::Create(GLContext*
     return Move(ret);
 }
 
 
 SharedSurface_Gralloc::SharedSurface_Gralloc(GLContext* prodGL,
                                              const gfx::IntSize& size,
                                              bool hasAlpha,
                                              GLLibraryEGL* egl,
-                                             layers::ISurfaceAllocator* allocator,
+                                             layers::ClientIPCAllocator* allocator,
                                              layers::TextureClient* textureClient,
                                              GLuint prodTex)
     : SharedSurface(SharedSurfaceType::Gralloc,
                     AttachmentType::GLTexture,
                     prodGL,
                     size,
                     hasAlpha,
                     true)
--- a/gfx/gl/SharedSurfaceGralloc.h
+++ b/gfx/gl/SharedSurfaceGralloc.h
@@ -7,53 +7,53 @@
 #define SHARED_SURFACE_GRALLOC_H_
 
 #include "mozilla/layers/CompositorTypes.h"
 #include "mozilla/layers/LayersSurfaces.h"
 #include "SharedSurface.h"
 
 namespace mozilla {
 namespace layers {
-class ISurfaceAllocator;
+class ClientIPCAllocator;
 class TextureClient;
 }
 
 namespace gl {
 class GLContext;
 class GLLibraryEGL;
 
 class SharedSurface_Gralloc
     : public SharedSurface
 {
 public:
     static UniquePtr<SharedSurface_Gralloc> Create(GLContext* prodGL,
                                                    const GLFormats& formats,
                                                    const gfx::IntSize& size,
                                                    bool hasAlpha,
                                                    layers::TextureFlags flags,
-                                                   layers::ISurfaceAllocator* allocator);
+                                                   layers::ClientIPCAllocator* allocator);
 
     static SharedSurface_Gralloc* Cast(SharedSurface* surf) {
         MOZ_ASSERT(surf->mType == SharedSurfaceType::Gralloc);
 
         return (SharedSurface_Gralloc*)surf;
     }
 
 protected:
     GLLibraryEGL* const mEGL;
     EGLSync mSync;
-    RefPtr<layers::ISurfaceAllocator> mAllocator;
+    RefPtr<layers::ClientIPCAllocator> mAllocator;
     RefPtr<layers::TextureClient> mTextureClient;
     const GLuint mProdTex;
 
     SharedSurface_Gralloc(GLContext* prodGL,
                           const gfx::IntSize& size,
                           bool hasAlpha,
                           GLLibraryEGL* egl,
-                          layers::ISurfaceAllocator* allocator,
+                          layers::ClientIPCAllocator* allocator,
                           layers::TextureClient* textureClient,
                           GLuint prodTex);
 
     static bool HasExtensions(GLLibraryEGL* egl, GLContext* gl);
 
 public:
     virtual ~SharedSurface_Gralloc();
 
@@ -78,17 +78,17 @@ public:
     virtual bool ReadbackBySharedHandle(gfx::DataSourceSurface* out_surface) override;
 };
 
 class SurfaceFactory_Gralloc
     : public SurfaceFactory
 {
 public:
     SurfaceFactory_Gralloc(GLContext* prodGL, const SurfaceCaps& caps,
-                           const RefPtr<layers::ISurfaceAllocator>& allocator,
+                           const RefPtr<layers::ClientIPCAllocator>& allocator,
                            const layers::TextureFlags& flags);
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override {
         bool hasAlpha = mReadCaps.alpha;
 
         UniquePtr<SharedSurface> ret;
         if (mAllocator) {
             ret = SharedSurface_Gralloc::Create(mGL, mFormats, size, hasAlpha,
--- a/gfx/gl/SharedSurfaceIO.cpp
+++ b/gfx/gl/SharedSurfaceIO.cpp
@@ -207,17 +207,17 @@ SharedSurface_IOSurface::ReadbackByShare
     return true;
 }
 
 ////////////////////////////////////////////////////////////////////////
 // SurfaceFactory_IOSurface
 
 /*static*/ UniquePtr<SurfaceFactory_IOSurface>
 SurfaceFactory_IOSurface::Create(GLContext* gl, const SurfaceCaps& caps,
-                                 const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                 const RefPtr<layers::ClientIPCAllocator>& allocator,
                                  const layers::TextureFlags& flags)
 {
     gfx::IntSize maxDims(MacIOSurface::GetMaxWidth(),
                          MacIOSurface::GetMaxHeight());
 
     typedef SurfaceFactory_IOSurface ptrT;
     UniquePtr<ptrT> ret( new ptrT(gl, caps, allocator, flags, maxDims) );
     return Move(ret);
--- a/gfx/gl/SharedSurfaceIO.h
+++ b/gfx/gl/SharedSurfaceIO.h
@@ -72,23 +72,23 @@ public:
 };
 
 class SurfaceFactory_IOSurface : public SurfaceFactory
 {
 public:
     // Infallible.
     static UniquePtr<SurfaceFactory_IOSurface> Create(GLContext* gl,
                                                       const SurfaceCaps& caps,
-                                                      const RefPtr<layers::ISurfaceAllocator>& allocator,
+                                                      const RefPtr<layers::ClientIPCAllocator>& allocator,
                                                       const layers::TextureFlags& flags);
 protected:
     const gfx::IntSize mMaxDims;
 
     SurfaceFactory_IOSurface(GLContext* gl, const SurfaceCaps& caps,
-                             const RefPtr<layers::ISurfaceAllocator>& allocator,
+                             const RefPtr<layers::ClientIPCAllocator>& allocator,
                              const layers::TextureFlags& flags,
                              const gfx::IntSize& maxDims)
         : SurfaceFactory(SharedSurfaceType::IOSurface, gl, caps, allocator, flags)
         , mMaxDims(maxDims)
     { }
 
     virtual UniquePtr<SharedSurface> CreateShared(const gfx::IntSize& size) override;
 };
--- a/gfx/layers/BufferTexture.cpp
+++ b/gfx/layers/BufferTexture.cpp
@@ -20,26 +20,26 @@ namespace mozilla {
 namespace layers {
 
 class MemoryTextureData : public BufferTextureData
 {
 public:
   static MemoryTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                                    gfx::BackendType aMoz2DBackend,TextureFlags aFlags,
                                    TextureAllocationFlags aAllocFlags,
-                                   ISurfaceAllocator* aAllocator);
+                                   ClientIPCAllocator* aAllocator);
 
   virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
+  CreateSimilar(ClientIPCAllocator* aAllocator,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
 
-  virtual void Deallocate(ISurfaceAllocator*) override;
+  virtual void Deallocate(ClientIPCAllocator*) override;
 
   MemoryTextureData(const BufferDescriptor& aDesc,
                     gfx::BackendType aMoz2DBackend,
                     uint8_t* aBuffer, size_t aBufferSize)
   : BufferTextureData(aDesc, aMoz2DBackend)
   , mBuffer(aBuffer)
   , mBufferSize(aBufferSize)
   {
@@ -57,26 +57,26 @@ protected:
 };
 
 class ShmemTextureData : public BufferTextureData
 {
 public:
   static ShmemTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                                   gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
                                   TextureAllocationFlags aAllocFlags,
-                                  ISurfaceAllocator* aAllocator);
+                                  ClientIPCAllocator* aAllocator);
 
   virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
+  CreateSimilar(ClientIPCAllocator* aAllocator,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
+  virtual void Deallocate(ClientIPCAllocator* aAllocator) override;
 
   ShmemTextureData(const BufferDescriptor& aDesc,
                    gfx::BackendType aMoz2DBackend, mozilla::ipc::Shmem aShmem)
   : BufferTextureData(aDesc, aMoz2DBackend)
   , mShmem(aShmem)
   {
     MOZ_ASSERT(mShmem.Size<uint8_t>());
   }
@@ -106,55 +106,57 @@ static bool ComputeHasIntermediateBuffer
       || aFormat == gfx::SurfaceFormat::YUV
       || aFormat == gfx::SurfaceFormat::NV12;
 }
 
 BufferTextureData*
 BufferTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                           gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
                           TextureAllocationFlags aAllocFlags,
-                          ISurfaceAllocator* aAllocator)
+                          ClientIPCAllocator* aAllocator)
 {
   if (!aAllocator || aAllocator->IsSameProcess()) {
     return MemoryTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags,
                                      aAllocFlags, aAllocator);
-  } else {
+  } else if (aAllocator->AsShmemAllocator()) {
     return ShmemTextureData::Create(aSize, aFormat, aMoz2DBackend, aFlags,
                                     aAllocFlags, aAllocator);
   }
+  return nullptr;
 }
 
 BufferTextureData*
-BufferTextureData::CreateInternal(ISurfaceAllocator* aAllocator,
+BufferTextureData::CreateInternal(ClientIPCAllocator* aAllocator,
                                   const BufferDescriptor& aDesc,
                                   gfx::BackendType aMoz2DBackend,
                                   int32_t aBufferSize,
                                   TextureFlags aTextureFlags)
 {
   if (!aAllocator || aAllocator->IsSameProcess()) {
     uint8_t* buffer = new (fallible) uint8_t[aBufferSize];
     if (!buffer) {
       return nullptr;
     }
 
     GfxMemoryImageReporter::DidAlloc(buffer);
 
     return new MemoryTextureData(aDesc, aMoz2DBackend, buffer, aBufferSize);
-  } else {
+  } else if (aAllocator->AsShmemAllocator()) {
     ipc::Shmem shm;
-    if (!aAllocator->AllocUnsafeShmem(aBufferSize, OptimalShmemType(), &shm)) {
+    if (!aAllocator->AsShmemAllocator()->AllocUnsafeShmem(aBufferSize, OptimalShmemType(), &shm)) {
       return nullptr;
     }
 
     return new ShmemTextureData(aDesc, aMoz2DBackend, shm);
   }
+  return nullptr;
 }
 
 BufferTextureData*
-BufferTextureData::CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
+BufferTextureData::CreateForYCbCrWithBufferSize(ClientIPCAllocator* aAllocator,
                                                 gfx::SurfaceFormat aFormat,
                                                 int32_t aBufferSize,
                                                 TextureFlags aTextureFlags)
 {
   if (aBufferSize == 0 || !gfx::Factory::CheckBufferSize(aBufferSize)) {
     return nullptr;
   }
 
@@ -163,17 +165,17 @@ BufferTextureData::CreateForYCbCrWithBuf
   BufferDescriptor desc = YCbCrDescriptor(gfx::IntSize(), gfx::IntSize(),
                                           0, 0, 0, StereoMode::MONO);
 
   return CreateInternal(aAllocator, desc, gfx::BackendType::NONE, aBufferSize,
                         aTextureFlags);
 }
 
 BufferTextureData*
-BufferTextureData::CreateForYCbCr(ISurfaceAllocator* aAllocator,
+BufferTextureData::CreateForYCbCr(ClientIPCAllocator* aAllocator,
                                   gfx::IntSize aYSize,
                                   gfx::IntSize aCbCrSize,
                                   StereoMode aStereoMode,
                                   TextureFlags aTextureFlags)
 {
   uint32_t bufSize = ImageDataSerializer::ComputeYCbCrBufferSize(aYSize, aCbCrSize);
   if (bufSize == 0) {
     return nullptr;
@@ -422,17 +424,17 @@ static bool InitBuffer(uint8_t* buf, siz
 
   return true;
 }
 
 MemoryTextureData*
 MemoryTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                           gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
                           TextureAllocationFlags aAllocFlags,
-                          ISurfaceAllocator* aAllocator)
+                          ClientIPCAllocator* aAllocator)
 {
   // Should have used CreateForYCbCr.
   MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);
 
   if (aSize.width <= 0 || aSize.height <= 0) {
     gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
     return nullptr;
   }
@@ -455,26 +457,26 @@ MemoryTextureData::Create(gfx::IntSize a
   GfxMemoryImageReporter::DidAlloc(buf);
 
   BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasIntermediateBuffer);
 
   return new MemoryTextureData(descriptor, aMoz2DBackend, buf, bufSize);
 }
 
 void
-MemoryTextureData::Deallocate(ISurfaceAllocator*)
+MemoryTextureData::Deallocate(ClientIPCAllocator*)
 {
   MOZ_ASSERT(mBuffer);
   GfxMemoryImageReporter::WillFree(mBuffer);
   delete [] mBuffer;
   mBuffer = nullptr;
 }
 
 TextureData*
-MemoryTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
+MemoryTextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
                                  TextureFlags aFlags,
                                  TextureAllocationFlags aAllocFlags) const
 {
   return MemoryTextureData::Create(GetSize(), GetFormat(), mMoz2DBackend,
                                    aFlags, aAllocFlags, aAllocator);
 }
 
 bool
@@ -489,38 +491,38 @@ ShmemTextureData::Serialize(SurfaceDescr
 
   return true;
 }
 
 ShmemTextureData*
 ShmemTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                          gfx::BackendType aMoz2DBackend, TextureFlags aFlags,
                          TextureAllocationFlags aAllocFlags,
-                         ISurfaceAllocator* aAllocator)
+                         ClientIPCAllocator* aAllocator)
 {
   MOZ_ASSERT(aAllocator);
   // Should have used CreateForYCbCr.
   MOZ_ASSERT(aFormat != gfx::SurfaceFormat::YUV);
 
-  if (!aAllocator) {
+  if (!aAllocator || !aAllocator->AsShmemAllocator()) {
     return nullptr;
   }
 
   if (aSize.width <= 0 || aSize.height <= 0) {
     gfxDebug() << "Asking for buffer of invalid size " << aSize.width << "x" << aSize.height;
     return nullptr;
   }
 
   uint32_t bufSize = ImageDataSerializer::ComputeRGBBufferSize(aSize, aFormat);
   if (!bufSize) {
     return nullptr;
   }
 
   mozilla::ipc::Shmem shm;
-  if (!aAllocator->AllocUnsafeShmem(bufSize, OptimalShmemType(), &shm)) {
+  if (!aAllocator->AsShmemAllocator()->AllocUnsafeShmem(bufSize, OptimalShmemType(), &shm)) {
     return nullptr;
   }
 
   uint8_t* buf = shm.get<uint8_t>();
   if (!InitBuffer(buf, bufSize, aFormat, aAllocFlags)) {
     return nullptr;
   }
 
@@ -532,24 +534,24 @@ ShmemTextureData::Create(gfx::IntSize aS
   BufferDescriptor descriptor = RGBDescriptor(aSize, aFormat, hasIntermediateBuffer);
 
   return new ShmemTextureData(descriptor, aMoz2DBackend, shm);
 
   return nullptr;
 }
 
 TextureData*
-ShmemTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
+ShmemTextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
                                 TextureFlags aFlags,
                                 TextureAllocationFlags aAllocFlags) const
 {
   return ShmemTextureData::Create(GetSize(), GetFormat(), mMoz2DBackend,
                                   aFlags, aAllocFlags, aAllocator);
 }
 
 void
-ShmemTextureData::Deallocate(ISurfaceAllocator* aAllocator)
+ShmemTextureData::Deallocate(ClientIPCAllocator* aAllocator)
 {
-  aAllocator->DeallocShmem(mShmem);
+  aAllocator->AsShmemAllocator()->DeallocShmem(mShmem);
 }
 
 } // namespace
 } // namespace
--- a/gfx/layers/BufferTexture.h
+++ b/gfx/layers/BufferTexture.h
@@ -16,28 +16,28 @@ namespace mozilla {
 namespace layers {
 
 class BufferTextureData : public TextureData
 {
 public:
   static BufferTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                                    gfx::BackendType aMoz2DBackend,TextureFlags aFlags,
                                    TextureAllocationFlags aAllocFlags,
-                                   ISurfaceAllocator* aAllocator);
+                                   ClientIPCAllocator* aAllocator);
 
-  static BufferTextureData* CreateForYCbCr(ISurfaceAllocator* aAllocator,
+  static BufferTextureData* CreateForYCbCr(ClientIPCAllocator* aAllocator,
                                            gfx::IntSize aYSize,
                                            gfx::IntSize aCbCrSize,
                                            StereoMode aStereoMode,
                                            TextureFlags aTextureFlags);
 
   // It is generally better to use CreateForYCbCr instead.
   // This creates a half-initialized texture since we don't know the sizes and
   // offsets in the buffer.
-  static BufferTextureData* CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
+  static BufferTextureData* CreateForYCbCrWithBufferSize(ClientIPCAllocator* aAllocator,
                                                          gfx::SurfaceFormat aFormat,
                                                          int32_t aSize,
                                                          TextureFlags aTextureFlags);
 
   virtual bool Lock(OpenMode aMode, FenceHandle*) override { return true; }
 
   virtual void Unlock() override {}
 
@@ -59,17 +59,17 @@ public:
 
   // use TextureClient's default implementation
   virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
   // Don't use this.
   void SetDesciptor(const BufferDescriptor& aDesc);
 
 protected:
-  static BufferTextureData* CreateInternal(ISurfaceAllocator* aAllocator,
+  static BufferTextureData* CreateInternal(ClientIPCAllocator* aAllocator,
                                            const BufferDescriptor& aDesc,
                                            gfx::BackendType aMoz2DBackend,
                                            int32_t aBufferSize,
                                            TextureFlags aTextureFlags);
 
   virtual uint8_t* GetBuffer() = 0;
   virtual size_t GetBufferSize() = 0;
 
--- a/gfx/layers/CompositorTypes.h
+++ b/gfx/layers/CompositorTypes.h
@@ -225,17 +225,16 @@ enum class OpenMode : uint8_t {
   OPEN_WRITE_ONLY  = OPEN_WRITE
 };
 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(OpenMode)
 
 // The kinds of mask texture a shader can support
 // We rely on the items in this enum being sequential
 enum class MaskType : uint8_t {
   MaskNone = 0,   // no mask layer
-  Mask2d,         // mask layer for layers with 2D transforms
-  Mask3d,         // mask layer for layers with 3D transforms
+  Mask,           // mask layer
   NumMaskTypes
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/D3D11ShareHandleImage.cpp
+++ b/gfx/layers/D3D11ShareHandleImage.cpp
@@ -50,27 +50,16 @@ D3D11ShareHandleImage::GetAsSourceSurfac
   if (!texture) {
     NS_WARNING("Cannot readback from shared texture because no texture is available.");
     return nullptr;
   }
 
   RefPtr<ID3D11Device> device;
   texture->GetDevice(getter_AddRefs(device));
 
-  RefPtr<IDXGIKeyedMutex> keyedMutex;
-  if (FAILED(texture->QueryInterface(static_cast<IDXGIKeyedMutex**>(getter_AddRefs(keyedMutex))))) {
-    NS_WARNING("Failed to QueryInterface for IDXGIKeyedMutex, strange.");
-    return nullptr;
-  }
-
-  if (FAILED(keyedMutex->AcquireSync(0, 0))) {
-    NS_WARNING("Failed to acquire sync for keyedMutex, plugin failed to release?");
-    return nullptr;
-  }
-
   D3D11_TEXTURE2D_DESC desc;
   texture->GetDesc(&desc);
 
   CD3D11_TEXTURE2D_DESC softDesc(desc.Format, desc.Width, desc.Height);
   softDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
   softDesc.BindFlags = 0;
   softDesc.MiscFlags = 0;
   softDesc.MipLevels = 1;
@@ -78,29 +67,26 @@ D3D11ShareHandleImage::GetAsSourceSurfac
 
   RefPtr<ID3D11Texture2D> softTexture;
   HRESULT hr = device->CreateTexture2D(&softDesc,
                                        NULL,
                                        static_cast<ID3D11Texture2D**>(getter_AddRefs(softTexture)));
 
   if (FAILED(hr)) {
     NS_WARNING("Failed to create 2D staging texture.");
-    keyedMutex->ReleaseSync(0);
     return nullptr;
   }
 
   RefPtr<ID3D11DeviceContext> context;
   device->GetImmediateContext(getter_AddRefs(context));
   if (!context) {
-    keyedMutex->ReleaseSync(0);
     return nullptr;
   }
 
   context->CopyResource(softTexture, texture);
-  keyedMutex->ReleaseSync(0);
 
   RefPtr<gfx::DataSourceSurface> surface =
     gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8);
   if (NS_WARN_IF(!surface)) {
     return nullptr;
   }
 
   gfx::DataSourceSurface::MappedSurface mappedSurface;
@@ -147,15 +133,16 @@ D3D11RecycleAllocator::Allocate(gfx::Sur
 already_AddRefed<TextureClient>
 D3D11RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
                                              const gfx::IntSize& aSize)
 {
   RefPtr<TextureClient> textureClient =
     CreateOrRecycle(aFormat,
                     aSize,
                     BackendSelector::Content,
-                    layers::TextureFlags::DEFAULT);
+                    layers::TextureFlags::DEFAULT,
+                    TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION);
   return textureClient.forget();
 }
 
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/D3D9SurfaceImage.cpp
+++ b/gfx/layers/D3D9SurfaceImage.cpp
@@ -72,16 +72,23 @@ D3D9SurfaceImage::AllocateAndCopy(D3D9Re
   hr = device->StretchRect(surface, &src, textureSurface, nullptr, D3DTEXF_NONE);
   NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
 
   mTextureClient = textureClient;
   mSize = aRegion.Size();
   return S_OK;
 }
 
+already_AddRefed<IDirect3DSurface9>
+D3D9SurfaceImage::GetD3D9Surface()
+{
+  return static_cast<DXGID3D9TextureData*>(
+    mTextureClient->GetInternalData())->GetD3D9Surface();
+}
+
 const D3DSURFACE_DESC&
 D3D9SurfaceImage::GetDesc() const
 {
   return static_cast<DXGID3D9TextureData*>(mTextureClient->GetInternalData())->GetDesc();
 }
 
 gfx::IntSize
 D3D9SurfaceImage::GetSize()
--- a/gfx/layers/D3D9SurfaceImage.h
+++ b/gfx/layers/D3D9SurfaceImage.h
@@ -58,16 +58,18 @@ public:
   const D3DSURFACE_DESC& GetDesc() const;
 
   gfx::IntSize GetSize() override;
 
   virtual already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;
 
   virtual TextureClient* GetTextureClient(CompositableClient* aClient) override;
 
+  already_AddRefed<IDirect3DSurface9> GetD3D9Surface();
+
   virtual bool IsValid() override { return mValid; }
 
   void Invalidate() { mValid = false; }
 
 private:
 
   gfx::IntSize mSize;
   RefPtr<TextureClient> mTextureClient;
--- a/gfx/layers/Effects.cpp
+++ b/gfx/layers/Effects.cpp
@@ -29,20 +29,16 @@ TexturedEffect::PrintInfo(std::stringstr
 
 void
 EffectMask::PrintInfo(std::stringstream& aStream, const char* aPrefix)
 {
   aStream << aPrefix;
   aStream << nsPrintfCString("EffectMask (0x%p)", this).get();
   AppendToString(aStream, mSize, " [size=", "]");
   AppendToString(aStream, mMaskTransform, " [mask-transform=", "]");
-
-  if (mIs3D) {
-    aStream << " [is-3d]";
-  }
 }
 
 void
 EffectRenderTarget::PrintInfo(std::stringstream& aStream, const char* aPrefix)
 {
   TexturedEffect::PrintInfo(aStream, aPrefix);
   aStream << nsPrintfCString(" [render-target=%p]", mRenderTarget.get()).get();
 }
--- a/gfx/layers/Effects.h
+++ b/gfx/layers/Effects.h
@@ -80,25 +80,23 @@ struct TexturedEffect : public Effect
 // Support an alpha mask.
 struct EffectMask : public Effect
 {
   EffectMask(TextureSource *aMaskTexture,
              gfx::IntSize aSize,
              const gfx::Matrix4x4 &aMaskTransform)
     : Effect(EffectTypes::MASK)
     , mMaskTexture(aMaskTexture)
-    , mIs3D(false)
     , mSize(aSize)
     , mMaskTransform(aMaskTransform)
   {}
 
   virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix);
 
   TextureSource* mMaskTexture;
-  bool mIs3D;
   gfx::IntSize mSize;
   gfx::Matrix4x4 mMaskTransform;
 };
 
 struct EffectVRDistortion : public Effect
 {
   EffectVRDistortion(gfx::VRHMDInfo* aHMD,
                      CompositingRenderTarget* aRenderTarget)
--- a/gfx/layers/GrallocImages.cpp
+++ b/gfx/layers/GrallocImages.cpp
@@ -68,17 +68,17 @@ GrallocImage::SetData(const Data& aData)
   mData = aData;
   mSize = aData.mPicSize;
 
   if (gfxPlatform::GetPlatform()->IsInGonkEmulator()) {
     // Emulator does not support HAL_PIXEL_FORMAT_YV12.
     return false;
   }
 
-  ISurfaceAllocator* allocator = ImageBridgeChild::GetSingleton();
+  ClientIPCAllocator* allocator = ImageBridgeChild::GetSingleton();
   GrallocTextureData* texData = GrallocTextureData::Create(mData.mYSize, HAL_PIXEL_FORMAT_YV12,
                                                            gfx::BackendType::NONE,
                                                            GraphicBuffer::USAGE_SW_READ_OFTEN |
                                                              GraphicBuffer::USAGE_SW_WRITE_OFTEN |
                                                              GraphicBuffer::USAGE_HW_TEXTURE,
                                                            allocator
   );
 
--- a/gfx/layers/IMFYCbCrImage.cpp
+++ b/gfx/layers/IMFYCbCrImage.cpp
@@ -219,19 +219,20 @@ IMFYCbCrImage::GetD3D9TextureClient(Comp
 
 TextureClient*
 IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
 {
   if (mTextureClient) {
     return mTextureClient;
   }
 
+  RefPtr<ID3D11Device> device;
+  gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice(&device);
+
   LayersBackend backend = aClient->GetForwarder()->GetCompositorBackendType();
-  ID3D11Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D11ImageBridgeDevice();
-
   if (!device || backend != LayersBackend::LAYERS_D3D11) {
     if (backend == LayersBackend::LAYERS_D3D9 ||
         backend == LayersBackend::LAYERS_D3D11) {
       return GetD3D9TextureClient(aClient);
     }
     return nullptr;
   }
 
--- a/gfx/layers/LayerScope.cpp
+++ b/gfx/layers/LayerScope.cpp
@@ -1197,17 +1197,16 @@ SenderHelper::SendMaskEffect(GLContext* 
     TextureSourceOGL* source = aEffect->mMaskTexture->AsSourceOGL();
     if (!source) {
         return;
     }
 
     // Expose packet creation here, so we could dump secondary mask effect attributes.
     auto packet = MakeUnique<layerscope::Packet>();
     TexturePacket::EffectMask* mask = packet->mutable_texture()->mutable_mask();
-    mask->set_mis3d(aEffect->mIs3D);
     mask->mutable_msize()->set_w(aEffect->mSize.width);
     mask->mutable_msize()->set_h(aEffect->mSize.height);
     auto element = reinterpret_cast<const Float *>(&(aEffect->mMaskTransform));
     for (int i = 0; i < 16; i++) {
         mask->mutable_mmasktransform()->add_m(*element++);
     }
 
     SendTextureSource(aGLContext, aLayerRef, source, false, true, Move(packet));
--- a/gfx/layers/Layers.cpp
+++ b/gfx/layers/Layers.cpp
@@ -1461,21 +1461,17 @@ ContainerLayer::DefaultComputeEffectiveT
   }
   mUseIntermediateSurface = useIntermediateSurface && !GetLocalVisibleRegion().IsEmpty();
   if (useIntermediateSurface) {
     ComputeEffectiveTransformsForChildren(Matrix4x4::From2D(residual));
   } else {
     ComputeEffectiveTransformsForChildren(idealTransform);
   }
 
-  if (idealTransform.CanDraw2D()) {
-    ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
-  } else {
-    ComputeEffectiveTransformForMaskLayers(Matrix4x4());
-  }
+  ComputeEffectiveTransformForMaskLayers(aTransformToSurface);
 }
 
 void
 ContainerLayer::DefaultComputeSupportsComponentAlphaChildren(bool* aNeedsSurfaceCopy)
 {
   if (!(GetContentFlags() & Layer::CONTENT_COMPONENT_ALPHA_DESCENDANT) ||
       !Manager()->AreComponentAlphaLayersEnabled()) {
     mSupportsComponentAlphaChildren = false;
--- a/gfx/layers/TextureDIB.cpp
+++ b/gfx/layers/TextureDIB.cpp
@@ -19,26 +19,26 @@ namespace layers {
   * The coresponding TextureHost depends on the compositor
   */
 class MemoryDIBTextureData : public DIBTextureData
 {
 public:
   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
 
   virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
+  CreateSimilar(ClientIPCAllocator* aAllocator,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
   static
   DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat);
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override
+  virtual void Deallocate(ClientIPCAllocator* aAllocator) override
   {
     mSurface = nullptr;
   }
 
   MemoryDIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                        gfxWindowsSurface* aSurface)
   : DIBTextureData(aSize, aFormat, aSurface)
   {
@@ -56,40 +56,40 @@ public:
   * The coresponding TextureHost depends on the compositor
   */
 class ShmemDIBTextureData : public DIBTextureData
 {
 public:
   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
 
   virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
+  CreateSimilar(ClientIPCAllocator* aAllocator,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
   static
   DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                         ISurfaceAllocator* aAllocator);
+                         ClientIPCAllocator* aAllocator);
 
   void DeallocateData()
   {
     if (mSurface) {
       ::DeleteObject(mBitmap);
       ::DeleteDC(mDC);
       ::CloseHandle(mFileMapping);
       mBitmap = NULL;
       mDC = NULL;
       mFileMapping = NULL;
       mSurface = nullptr;
     }
   }
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) override
+  virtual void Deallocate(ClientIPCAllocator* aAllocator) override
   {
     DeallocateData();
   }
 
   ShmemDIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                       gfxWindowsSurface* aSurface,
                       HANDLE aFileMapping, HANDLE aHostHandle,
                       HDC aDC, HBITMAP aBitmap)
@@ -120,33 +120,33 @@ public:
 already_AddRefed<gfx::DrawTarget>
 DIBTextureData::BorrowDrawTarget()
 {
   return gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(mSurface, mSize);
 }
 
 DIBTextureData*
 DIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                       ISurfaceAllocator* aAllocator)
+                       ClientIPCAllocator* aAllocator)
 {
   if (!aAllocator) {
     return nullptr;
   }
   if (aFormat == gfx::SurfaceFormat::UNKNOWN) {
     return nullptr;
   }
   if (aAllocator->IsSameProcess()) {
     return MemoryDIBTextureData::Create(aSize, aFormat);
   } else {
     return ShmemDIBTextureData::Create(aSize, aFormat, aAllocator);
   }
 }
 
 TextureData*
-MemoryDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
+MemoryDIBTextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
                                     TextureFlags aFlags,
                                     TextureAllocationFlags aAllocFlags) const
 {
   if (!aAllocator) {
     return nullptr;
   }
   return MemoryDIBTextureData::Create(mSize, mFormat);
 }
@@ -199,17 +199,17 @@ MemoryDIBTextureData::UpdateFromSurface(
            srcSurf->GetSize().width * BytesPerPixel(srcSurf->GetFormat()));
   }
 
   srcSurf->Unmap();
   return true;
 }
 
 TextureData*
-ShmemDIBTextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
+ShmemDIBTextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
                                    TextureFlags aFlags,
                                    TextureAllocationFlags aAllocFlags) const
 {
   if (!aAllocator) {
     return nullptr;
   }
   return ShmemDIBTextureData::Create(mSize, mFormat, aAllocator);
 }
@@ -263,19 +263,19 @@ ShmemDIBTextureData::Serialize(SurfaceDe
 
   ::GdiFlush();
   aOutDescriptor = SurfaceDescriptorFileMapping((WindowsHandle)mHostHandle, mFormat, mSize);
   return true;
 }
 
 DIBTextureData*
 ShmemDIBTextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                            ISurfaceAllocator* aAllocator)
+                            ClientIPCAllocator* aAllocator)
 {
-  MOZ_ASSERT(aAllocator->ParentPid() != base::ProcessId());
+  MOZ_ASSERT(aAllocator->AsLayerForwarder()->GetParentPid() != base::ProcessId());
 
   DWORD mapSize = aSize.width * aSize.height * BytesPerPixel(aFormat);
   HANDLE fileMapping = ::CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, mapSize, NULL);
 
   if (!fileMapping) {
     gfxCriticalError() << "Failed to create memory file mapping for " << mapSize << " bytes.";
     return nullptr;
   }
@@ -327,17 +327,17 @@ ShmemDIBTextureData::Create(gfx::IntSize
     ::CloseHandle(fileMapping);
     gfxCriticalError() << "Could not create surface, status: "
                        << surface->CairoStatus();
     return nullptr;
   }
 
   HANDLE hostHandle = NULL;
 
-  if (!ipc::DuplicateHandle(fileMapping, aAllocator->ParentPid(),
+  if (!ipc::DuplicateHandle(fileMapping, aAllocator->AsLayerForwarder()->GetParentPid(),
                             &hostHandle, 0, DUPLICATE_SAME_ACCESS)) {
     gfxCriticalError() << "Failed to duplicate handle to parent process for surface.";
     ::DeleteObject(bitmap);
     ::DeleteDC(dc);
     ::CloseHandle(fileMapping);
     return nullptr;
   }
 
--- a/gfx/layers/TextureDIB.h
+++ b/gfx/layers/TextureDIB.h
@@ -29,17 +29,17 @@ public:
   virtual bool SupportsMoz2D() const override { return true; }
 
   virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
 
   virtual bool HasIntermediateBuffer() const override { return true; }
 
   static
   DIBTextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                         ISurfaceAllocator* aAllocator);
+                         ClientIPCAllocator* aAllocator);
 
 protected:
   DIBTextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                  gfxWindowsSurface* aSurface)
   : mSurface(aSurface)
   , mSize(aSize)
   , mFormat(aFormat)
   {
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -392,16 +392,35 @@ Transform(DataSourceSurface* aDest,
 
 static inline IntRect
 RoundOut(Rect r)
 {
   r.RoundOut();
   return IntRect(r.x, r.y, r.width, r.height);
 }
 
+static void
+SetupMask(const EffectChain& aEffectChain,
+          DrawTarget* aDest,
+          const IntPoint& aOffset,
+          RefPtr<SourceSurface>& aMaskSurface,
+          Matrix& aMaskTransform)
+{
+  if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) {
+    EffectMask *effectMask = static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EffectTypes::MASK].get());
+    aMaskSurface = effectMask->mMaskTexture->AsSourceBasic()->GetSurface(aDest);
+    if (!aMaskSurface) {
+      gfxWarning() << "Invalid sourceMask effect";
+    }
+    MOZ_ASSERT(effectMask->mMaskTransform.Is2D(), "How did we end up with a 3D transform here?!");
+    aMaskTransform = effectMask->mMaskTransform.As2D();
+    aMaskTransform.PostTranslate(-aOffset.x, -aOffset.y);
+  }
+}
+
 void
 BasicCompositor::DrawQuad(const gfx::Rect& aRect,
                           const gfx::Rect& aClipRect,
                           const EffectChain &aEffectChain,
                           gfx::Float aOpacity,
                           const gfx::Matrix4x4& aTransform,
                           const gfx::Rect& aVisibleRect)
 {
@@ -437,36 +456,29 @@ BasicCompositor::DrawQuad(const gfx::Rec
       return;
     }
 
     // Propagate the coordinate offset to our 2D draw target.
     newTransform = Matrix::Translation(transformBounds.x, transformBounds.y);
 
     // When we apply the 3D transformation, we do it against a temporary
     // surface, so undo the coordinate offset.
-    new3DTransform = Matrix4x4::Translation(aRect.x, aRect.y, 0) * aTransform;
+    new3DTransform = aTransform;
+    new3DTransform.PreTranslate(aRect.x, aRect.y, 0);
   }
 
   buffer->PushClipRect(aClipRect);
 
   newTransform.PostTranslate(-offset.x, -offset.y);
   buffer->SetTransform(newTransform);
 
   RefPtr<SourceSurface> sourceMask;
   Matrix maskTransform;
-  if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) {
-    EffectMask *effectMask = static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EffectTypes::MASK].get());
-    sourceMask = effectMask->mMaskTexture->AsSourceBasic()->GetSurface(dest);
-    if (!sourceMask) {
-      gfxWarning() << "Invalid sourceMask effect";
-    }
-    MOZ_ASSERT(effectMask->mMaskTransform.Is2D(), "How did we end up with a 3D transform here?!");
-    MOZ_ASSERT(!effectMask->mIs3D);
-    maskTransform = effectMask->mMaskTransform.As2D();
-    maskTransform.PostTranslate(-offset.x, -offset.y);
+  if (aTransform.Is2D()) {
+    SetupMask(aEffectChain, dest, offset, sourceMask, maskTransform);
   }
 
   CompositionOp blendMode = CompositionOp::OP_OVER;
   if (Effect* effect = aEffectChain.mSecondaryEffects[EffectTypes::BLEND_MODE].get()) {
     blendMode = static_cast<EffectBlendMode*>(effect)->mBlendMode;
   }
 
   switch (aEffectChain.mPrimaryEffect->mType) {
@@ -563,18 +575,50 @@ BasicCompositor::DrawQuad(const gfx::Rec
         );
     if (NS_WARN_IF(!temp)) {
       buffer->PopClip();
       return;
     }
 
     Transform(temp, source, new3DTransform, transformBounds.TopLeft());
 
+    SetupMask(aEffectChain, buffer, offset, sourceMask, maskTransform);
+
+    // Adjust for the fact that our content now start at 0,0 instead
+    // of the top left of transformBounds.
     transformBounds.MoveTo(0, 0);
-    buffer->DrawSurface(temp, transformBounds, transformBounds);
+    maskTransform.PostTranslate(-transformBounds.x, -transformBounds.y);
+
+    if (sourceMask) {
+      // Transform the source by it's normal transform, and then the inverse
+      // of the mask transform so that it's in the mask's untransformed
+      // coordinate space.
+      Matrix old = buffer->GetTransform();
+      Matrix sourceTransform = old;
+
+      Matrix inverseMask = maskTransform;
+      inverseMask.Invert();
+
+      sourceTransform *= inverseMask;
+
+      SurfacePattern source(temp, ExtendMode::CLAMP, sourceTransform);
+
+      buffer->PushClipRect(transformBounds);
+
+      // Mask in the untransformed coordinate space, and then transform
+      // by the mask transform to put the result back into destination
+      // coords.
+      buffer->SetTransform(maskTransform);
+      buffer->MaskSurface(source, sourceMask, Point(0, 0));
+      buffer->SetTransform(old);
+
+      buffer->PopClip();
+    } else {
+      buffer->DrawSurface(temp, transformBounds, transformBounds);
+    }
   }
 
   buffer->PopClip();
 }
 
 void
 BasicCompositor::ClearRect(const gfx::Rect& aRect)
 {
--- a/gfx/layers/basic/TextureClientX11.cpp
+++ b/gfx/layers/basic/TextureClientX11.cpp
@@ -91,32 +91,32 @@ X11TextureData::UpdateFromSurface(gfx::S
   }
 
   dt->CopySurface(aSurface, IntRect(IntPoint(), aSurface->GetSize()), IntPoint());
 
   return true;
 }
 
 void
-X11TextureData::Deallocate(ISurfaceAllocator*)
+X11TextureData::Deallocate(ClientIPCAllocator*)
 {
   mSurface = nullptr;
 }
 
 TextureData*
-X11TextureData::CreateSimilar(ISurfaceAllocator* aAllocator,
+X11TextureData::CreateSimilar(ClientIPCAllocator* aAllocator,
                               TextureFlags aFlags,
                               TextureAllocationFlags aAllocFlags) const
 {
   return X11TextureData::Create(mSize, mFormat, aFlags, aAllocator);
 }
 
 X11TextureData*
 X11TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                       TextureFlags aFlags, ISurfaceAllocator* aAllocator)
+                       TextureFlags aFlags, ClientIPCAllocator* aAllocator)
 {
   MOZ_ASSERT(aSize.width >= 0 && aSize.height >= 0);
   if (aSize.width <= 0 || aSize.height <= 0 ||
       aSize.width > XLIB_IMAGE_SIDE_SIZE_LIMIT ||
       aSize.height > XLIB_IMAGE_SIDE_SIZE_LIMIT) {
     gfxDebug() << "Asking for X11 surface of invalid size " << aSize.width << "x" << aSize.height;
     return nullptr;
   }
--- a/gfx/layers/basic/TextureClientX11.h
+++ b/gfx/layers/basic/TextureClientX11.h
@@ -12,17 +12,17 @@
 
 namespace mozilla {
 namespace layers {
 
 class X11TextureData : public TextureData
 {
 public:
   static X11TextureData* Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
-                                TextureFlags aFlags, ISurfaceAllocator* aAllocator);
+                                TextureFlags aFlags, ClientIPCAllocator* aAllocator);
 
   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
 
   virtual bool Lock(OpenMode aMode, FenceHandle*) override;
 
   virtual void Unlock() override;
 
   virtual gfx::IntSize GetSize() const override { return mSize; }
@@ -30,20 +30,20 @@ public:
   virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
 
   virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
 
   virtual bool SupportsMoz2D() const override { return true; }
 
   virtual bool HasIntermediateBuffer() const override { return false; }
 
-  virtual void Deallocate(ISurfaceAllocator*) override;
+  virtual void Deallocate(ClientIPCAllocator*) override;
 
   virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
+  CreateSimilar(ClientIPCAllocator* aAllocator,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
 
   virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
 
 protected:
   X11TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
                  bool aClientDeallocation, bool aIsCrossProcess,
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -179,25 +179,25 @@ CanvasClientSharedSurface::~CanvasClient
 // For formats compatible with R8G8B8A8.
 static inline void SwapRB_R8G8B8A8(uint8_t* pixel) {
   // [RR, GG, BB, AA]
   Swap(pixel[0], pixel[2]);
 }
 
 class TexClientFactory
 {
-  ISurfaceAllocator* const mAllocator;
+  ClientIPCAllocator* const mAllocator;
   const bool mHasAlpha;
   const gfx::IntSize mSize;
   const gfx::BackendType mBackendType;
   const TextureFlags mBaseTexFlags;
   const LayersBackend mLayersBackend;
 
 public:
-  TexClientFactory(ISurfaceAllocator* allocator, bool hasAlpha,
+  TexClientFactory(ClientIPCAllocator* allocator, bool hasAlpha,
                    const gfx::IntSize& size, gfx::BackendType backendType,
                    TextureFlags baseTexFlags, LayersBackend layersBackend)
     : mAllocator(allocator)
     , mHasAlpha(hasAlpha)
     , mSize(size)
     , mBackendType(backendType)
     , mBaseTexFlags(baseTexFlags)
     , mLayersBackend(layersBackend)
@@ -235,17 +235,17 @@ public:
       }
     }
 
     return ret.forget();
   }
 };
 
 static already_AddRefed<TextureClient>
-TexClientFromReadback(SharedSurface* src, ISurfaceAllocator* allocator,
+TexClientFromReadback(SharedSurface* src, ClientIPCAllocator* allocator,
                       TextureFlags baseFlags, LayersBackend layersBackend)
 {
   auto backendType = gfx::BackendType::CAIRO;
   TexClientFactory factory(allocator, src->mHasAlpha, src->mSize, backendType,
                            baseFlags, layersBackend);
 
   RefPtr<TextureClient> texClient;
 
--- a/gfx/layers/client/ClientLayerManager.cpp
+++ b/gfx/layers/client/ClientLayerManager.cpp
@@ -533,17 +533,17 @@ ClientLayerManager::MakeSnapshotIfRequir
 
           gfx::Matrix oldMatrix = dt->GetTransform();
           dt->SetTransform(rotate * oldMatrix);
           dt->DrawSurface(surf, dstRect, srcRect,
                           DrawSurfaceOptions(),
                           DrawOptions(1.0f, CompositionOp::OP_OVER));
           dt->SetTransform(oldMatrix);
         }
-        mForwarder->DestroySharedSurface(&inSnapshot);
+        mForwarder->DestroySurfaceDescriptor(&inSnapshot);
       }
     }
   }
   mShadowTarget = nullptr;
 }
 
 void
 ClientLayerManager::FlushRendering()
--- a/gfx/layers/client/CompositableClient.cpp
+++ b/gfx/layers/client/CompositableClient.cpp
@@ -57,22 +57,22 @@ public:
   uint64_t mAsyncID;
 };
 
 void
 RemoveTextureFromCompositableTracker::ReleaseTextureClient()
 {
   if (mTextureClient &&
       mTextureClient->GetAllocator() &&
-      !mTextureClient->GetAllocator()->IsImageBridgeChild())
+      !mTextureClient->GetAllocator()->UsesImageBridge())
   {
     TextureClientReleaseTask* task = new TextureClientReleaseTask(mTextureClient);
-    RefPtr<ISurfaceAllocator> allocator = mTextureClient->GetAllocator();
+    RefPtr<ClientIPCAllocator> allocator = mTextureClient->GetAllocator();
     mTextureClient = nullptr;
-    allocator->GetMessageLoop()->PostTask(FROM_HERE, task);
+    allocator->AsClientAllocator()->GetMessageLoop()->PostTask(FROM_HERE, task);
   } else {
     mTextureClient = nullptr;
   }
 }
 
 /* static */ void
 CompositableClient::TransactionCompleteted(PCompositableChild* aActor, uint64_t aTransactionId)
 {
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -73,18 +73,17 @@ ImageClient::RemoveTexture(TextureClient
 {
   RemoveTextureWithWaiter(aTexture);
 }
 
 void
 ImageClient::RemoveTextureWithWaiter(TextureClient* aTexture,
                                      AsyncTransactionWaiter* aAsyncTransactionWaiter)
 {
-  if ((aAsyncTransactionWaiter ||
-      GetForwarder()->IsImageBridgeChild())
+  if ((aAsyncTransactionWaiter || GetForwarder()->UsesImageBridge())
 #ifndef MOZ_WIDGET_GONK
       // If the texture client is taking part in recycling then we should make sure
       // the host has finished with it before dropping the ref and triggering
       // the recycle callback.
       && aTexture->GetRecycleAllocator()
 #endif
      ) {
     RefPtr<AsyncTransactionTracker> request =
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -68,17 +68,17 @@ namespace layers {
 using namespace mozilla::ipc;
 using namespace mozilla::gl;
 using namespace mozilla::gfx;
 
 struct TextureDeallocParams
 {
   TextureData* data;
   RefPtr<TextureChild> actor;
-  RefPtr<ISurfaceAllocator> allocator;
+  RefPtr<ClientIPCAllocator> allocator;
   bool clientDeallocation;
   bool syncDeallocation;
   bool workAroundSharedSurfaceOwnershipIssue;
 };
 
 void DeallocateTextureClient(TextureDeallocParams params);
 
 /**
@@ -139,17 +139,17 @@ public:
     {
       MonitorAutoLock mon(mMonitor);
       mWaitForRecycle = nullptr;
     }
   }
 
   CompositableForwarder* GetForwarder() { return mForwarder; }
 
-  ISurfaceAllocator* GetAllocator() { return mForwarder; }
+  ClientIPCAllocator* GetAllocator() { return mForwarder; }
 
   void ActorDestroy(ActorDestroyReason why) override;
 
   bool IPCOpen() const { return mIPCOpen; }
 
 private:
 
   // AddIPDLReference and ReleaseIPDLReference are only to be called by CreateIPDLActor
@@ -184,25 +184,25 @@ private:
   bool mIPCOpen;
   bool mOwnsTextureData;
 
   friend class TextureClient;
   friend void DeallocateTextureClient(TextureDeallocParams params);
 };
 
 
-static void DestroyTextureData(TextureData* aTextureData, ISurfaceAllocator* aAllocator,
+static void DestroyTextureData(TextureData* aTextureData, ClientIPCAllocator* aAllocator,
                                bool aDeallocate, bool aMainThreadOnly)
 {
   if (!aTextureData) {
     return;
   }
 
   if (aMainThreadOnly && !NS_IsMainThread()) {
-    RefPtr<ISurfaceAllocator> allocatorRef = aAllocator;
+    RefPtr<ClientIPCAllocator> allocatorRef = aAllocator;
     NS_DispatchToMainThread(NS_NewRunnableFunction([aTextureData, allocatorRef, aDeallocate]() -> void {
       DestroyTextureData(aTextureData, allocatorRef, aDeallocate, true);
     }));
     return;
   }
 
   if (aDeallocate) {
     aTextureData->Deallocate(aAllocator);
@@ -244,17 +244,17 @@ DeallocateTextureClient(TextureDeallocPa
     // Nothing to do
     return;
   }
 
   TextureChild* actor = params.actor;
   MessageLoop* ipdlMsgLoop = nullptr;
 
   if (params.allocator) {
-    ipdlMsgLoop = params.allocator->GetMessageLoop();
+    ipdlMsgLoop = params.allocator->AsClientAllocator()->GetMessageLoop();
     if (!ipdlMsgLoop) {
       // An allocator with no message loop means we are too late in the shutdown
       // sequence.
       gfxCriticalError() << "Texture deallocated too late during shutdown";
       return;
     }
   }
 
@@ -278,17 +278,17 @@ DeallocateTextureClient(TextureDeallocPa
     return;
   }
 
   // Below this line, we are either in the IPDL thread or ther is no IPDL
   // thread anymore.
 
   if (!ipdlMsgLoop) {
     // If we don't have a message loop we can't know for sure that we are in
-    // the IPDL thread and use the ISurfaceAllocator.
+    // the IPDL thread and use the ClientIPCAllocator.
     // This should ideally not happen outside of gtest, but some shutdown raciness
     // could put us in this situation.
     params.allocator = nullptr;
   }
 
   if (!actor) {
     // We don't have an IPDL actor, probably because we destroyed the TextureClient
     // before sharing it with the compositor. It means the data cannot be owned by
@@ -692,17 +692,17 @@ TextureClient::SetRecycleAllocator(IText
   } else {
     ClearRecycleCallback();
   }
 }
 
 bool
 TextureClient::InitIPDLActor(CompositableForwarder* aForwarder)
 {
-  MOZ_ASSERT(aForwarder && aForwarder->GetMessageLoop() == mAllocator->GetMessageLoop());
+  MOZ_ASSERT(aForwarder && aForwarder->GetMessageLoop() == mAllocator->AsClientAllocator()->GetMessageLoop());
   if (mActor && !mActor->mDestroyed && mActor->GetForwarder() == aForwarder) {
     return true;
   }
   MOZ_ASSERT(!mActor || mActor->mDestroyed, "Cannot use a texture on several IPC channels.");
 
   SurfaceDescriptor desc;
   if (!ToSurfaceDescriptor(desc)) {
     return false;
@@ -826,17 +826,17 @@ TextureClient::CreateForDrawing(Composit
 
   // Can't do any better than a buffer texture client.
   return TextureClient::CreateForRawBufferAccess(aAllocator, aFormat, aSize,
                                                  moz2DBackend, aTextureFlags, aAllocFlags);
 }
 
 // static
 already_AddRefed<TextureClient>
-TextureClient::CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
+TextureClient::CreateForRawBufferAccess(ClientIPCAllocator* aAllocator,
                                         gfx::SurfaceFormat aFormat,
                                         gfx::IntSize aSize,
                                         gfx::BackendType aMoz2DBackend,
                                         TextureFlags aTextureFlags,
                                         TextureAllocationFlags aAllocFlags)
 {
   // also test the validity of aAllocator
   MOZ_ASSERT(aAllocator && aAllocator->IPCOpen());
@@ -859,17 +859,17 @@ TextureClient::CreateForRawBufferAccess(
     return nullptr;
   }
 
   return MakeAndAddRef<TextureClient>(texData, aTextureFlags, aAllocator);
 }
 
 // static
 already_AddRefed<TextureClient>
-TextureClient::CreateForYCbCr(ISurfaceAllocator* aAllocator,
+TextureClient::CreateForYCbCr(ClientIPCAllocator* aAllocator,
                               gfx::IntSize aYSize,
                               gfx::IntSize aCbCrSize,
                               StereoMode aStereoMode,
                               TextureFlags aTextureFlags)
 {
   // The only reason we allow aAllocator to be null is for gtests
   MOZ_ASSERT(!aAllocator || aAllocator->IPCOpen());
   if (aAllocator && !aAllocator->IPCOpen()) {
@@ -886,17 +886,17 @@ TextureClient::CreateForYCbCr(ISurfaceAl
     return nullptr;
   }
 
   return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
 }
 
 // static
 already_AddRefed<TextureClient>
-TextureClient::CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
+TextureClient::CreateForYCbCrWithBufferSize(ClientIPCAllocator* aAllocator,
                                             gfx::SurfaceFormat aFormat,
                                             size_t aSize,
                                             TextureFlags aTextureFlags)
 {
   // also test the validity of aAllocator
   MOZ_ASSERT(aAllocator && aAllocator->IPCOpen());
   if (!aAllocator || !aAllocator->IPCOpen()) {
     return nullptr;
@@ -907,17 +907,17 @@ TextureClient::CreateForYCbCrWithBufferS
                                                     aTextureFlags);
   if (!data) {
     return nullptr;
   }
 
   return MakeAndAddRef<TextureClient>(data, aTextureFlags, aAllocator);
 }
 
-TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator)
+TextureClient::TextureClient(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator)
 : mAllocator(aAllocator)
 , mActor(nullptr)
 , mData(aData)
 , mFlags(aFlags)
 , mOpenMode(OpenMode::OPEN_NONE)
 #ifdef DEBUG
 , mExpectedDtRefs(0)
 #endif
@@ -1069,17 +1069,17 @@ SyncObject::CreateSyncObject(SyncHandle 
   return MakeAndAddRef<SyncObjectD3D11>(aHandle);
 #else
   MOZ_ASSERT_UNREACHABLE();
   return nullptr;
 #endif
 }
 
 already_AddRefed<TextureClient>
-TextureClient::CreateWithData(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator)
+TextureClient::CreateWithData(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator)
 {
   if (!aData) {
     return nullptr;
   }
   return MakeAndAddRef<TextureClient>(aData, aFlags, aAllocator);
 }
 
 bool
--- a/gfx/layers/client/TextureClient.h
+++ b/gfx/layers/client/TextureClient.h
@@ -43,17 +43,17 @@ namespace gl {
 class SharedSurface_Gralloc;
 }
 
 namespace layers {
 
 class AsyncTransactionWaiter;
 class CompositableForwarder;
 class GrallocTextureData;
-class ISurfaceAllocator;
+class ClientIPCAllocator;
 class CompositableClient;
 struct PlanarYCbCrData;
 class Image;
 class PTextureChild;
 class TextureChild;
 class TextureData;
 struct RawTextureBuffer;
 class RawYCbCrTextureBuffer;
@@ -75,16 +75,20 @@ enum TextureAllocationFlags {
   ALLOC_CLEAR_BUFFER_WHITE = 1 << 2,  // explicit all white
   ALLOC_CLEAR_BUFFER_BLACK = 1 << 3,  // explicit all black
   ALLOC_DISALLOW_BUFFERTEXTURECLIENT = 1 << 4,
 
   // Allocate the texture for out-of-band content updates. This is mostly for
   // TextureClientD3D11, which may otherwise choose D3D10 or non-KeyedMutex
   // surfaces when used on the main thread.
   ALLOC_FOR_OUT_OF_BAND_CONTENT = 1 << 5,
+
+  // Disable any cross-device synchronization. This is also for TextureClientD3D11,
+  // and creates a texture without KeyedMutex.
+  ALLOC_MANUAL_SYNCHRONIZATION = 1 << 6,
 };
 
 #ifdef XP_WIN
 typedef void* SyncHandle;
 #else
 typedef uintptr_t SyncHandle;
 #endif // XP_WIN
 
@@ -198,25 +202,25 @@ public:
   virtual bool HasSynchronization() const { return false; }
 
   virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() { return nullptr; }
 
   virtual bool BorrowMappedData(MappedTextureData&) { return false; }
 
   virtual bool BorrowMappedYCbCrData(MappedYCbCrTextureData&) { return false; }
 
-  virtual void Deallocate(ISurfaceAllocator* aAllocator) = 0;
+  virtual void Deallocate(ClientIPCAllocator* aAllocator) = 0;
 
   /// Depending on the texture's flags either Deallocate or Forget is called.
-  virtual void Forget(ISurfaceAllocator* aAllocator) {}
+  virtual void Forget(ClientIPCAllocator* aAllocator) {}
 
   virtual bool Serialize(SurfaceDescriptor& aDescriptor) = 0;
 
   virtual TextureData*
-  CreateSimilar(ISurfaceAllocator* aAllocator,
+  CreateSimilar(ClientIPCAllocator* aAllocator,
                 TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const { return nullptr; }
 
   virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) { return false; };
 
   virtual bool ReadBack(TextureReadbackSink* aReadbackSink) { return false; }
 
   /// Ideally this should not be exposed and users of TextureClient would use Lock/Unlock
@@ -258,55 +262,55 @@ public:
  * responsibility of the compositable (which would use two Texture pairs).
  * In order to send several different buffers to the compositor side, use
  * several TextureClients.
  */
 class TextureClient
   : public AtomicRefCountedWithFinalize<TextureClient>
 {
 public:
-  explicit TextureClient(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator);
+  explicit TextureClient(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator);
 
   virtual ~TextureClient();
 
   static already_AddRefed<TextureClient>
-  CreateWithData(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator);
+  CreateWithData(TextureData* aData, TextureFlags aFlags, ClientIPCAllocator* aAllocator);
 
   // Creates and allocates a TextureClient usable with Moz2D.
   static already_AddRefed<TextureClient>
   CreateForDrawing(CompositableForwarder* aAllocator,
                    gfx::SurfaceFormat aFormat,
                    gfx::IntSize aSize,
                    BackendSelector aSelector,
                    TextureFlags aTextureFlags,
                    TextureAllocationFlags flags = ALLOC_DEFAULT);
 
   // Creates and allocates a TextureClient supporting the YCbCr format.
   static already_AddRefed<TextureClient>
-  CreateForYCbCr(ISurfaceAllocator* aAllocator,
+  CreateForYCbCr(ClientIPCAllocator* aAllocator,
                  gfx::IntSize aYSize,
                  gfx::IntSize aCbCrSize,
                  StereoMode aStereoMode,
                  TextureFlags aTextureFlags);
 
   // Creates and allocates a TextureClient (can be accessed through raw
   // pointers).
   static already_AddRefed<TextureClient>
-  CreateForRawBufferAccess(ISurfaceAllocator* aAllocator,
+  CreateForRawBufferAccess(ClientIPCAllocator* aAllocator,
                            gfx::SurfaceFormat aFormat,
                            gfx::IntSize aSize,
                            gfx::BackendType aMoz2dBackend,
                            TextureFlags aTextureFlags,
                            TextureAllocationFlags flags = ALLOC_DEFAULT);
 
   // Creates and allocates a TextureClient (can beaccessed through raw
   // pointers) with a certain buffer size. It's unfortunate that we need this.
   // providing format and sizes could let us do more optimization.
   static already_AddRefed<TextureClient>
-  CreateForYCbCrWithBufferSize(ISurfaceAllocator* aAllocator,
+  CreateForYCbCrWithBufferSize(ClientIPCAllocator* aAllocator,
                                gfx::SurfaceFormat aFormat,
                                size_t aSize,
                                TextureFlags aTextureFlags);
 
   // Creates and allocates a TextureClient of the same type.
   already_AddRefed<TextureClient>
   CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
                 TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const;
@@ -572,17 +576,17 @@ public:
    * texture unlock.
    */
   virtual void SetReadbackSink(TextureReadbackSink* aReadbackSink) {
     mReadbackSink = aReadbackSink;
   }
 
   void SyncWithObject(SyncObject* aFence) { mData->SyncWithObject(aFence); }
 
-  ISurfaceAllocator* GetAllocator() { return mAllocator; }
+  ClientIPCAllocator* GetAllocator() { return mAllocator; }
 
   ITextureClientRecycleAllocator* GetRecycleAllocator() { return mRecycleAllocator; }
   void SetRecycleAllocator(ITextureClientRecycleAllocator* aAllocator);
 
   /// If you add new code that uses this method, you are probably doing something wrong.
   TextureData* GetInternalData() { return mData; }
   const TextureData* GetInternalData() const { return mData; }
 
@@ -610,17 +614,17 @@ protected:
    * deserialized.
    * Calling ToSurfaceDescriptor again after it has already returned true,
    * or never constructing a TextureHost with aDescriptor may result in a memory
    * leak (see TextureClientD3D9 for example).
    */
   bool ToSurfaceDescriptor(SurfaceDescriptor& aDescriptor);
 
 
-  RefPtr<ISurfaceAllocator> mAllocator;
+  RefPtr<ClientIPCAllocator> mAllocator;
   RefPtr<TextureChild> mActor;
   RefPtr<ITextureClientRecycleAllocator> mRecycleAllocator;
   RefPtr<AsyncTransactionWaiter> mRemoveFromCompositableWaiter;
 
   TextureData* mData;
   RefPtr<gfx::DrawTarget> mBorrowedDrawTarget;
 
   TextureFlags mFlags;
--- a/gfx/layers/client/TextureClientRecycleAllocator.cpp
+++ b/gfx/layers/client/TextureClientRecycleAllocator.cpp
@@ -130,17 +130,18 @@ TextureClientRecycleAllocator::CreateOrR
 
 already_AddRefed<TextureClient>
 TextureClientRecycleAllocator::CreateOrRecycle(ITextureClientAllocationHelper& aHelper)
 {
   // TextureAllocationFlags is actually used only by ContentClient.
   // This class does not handle ContentClient's TextureClient allocation.
   MOZ_ASSERT(aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_DEFAULT ||
              aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_DISALLOW_BUFFERTEXTURECLIENT ||
-             aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_FOR_OUT_OF_BAND_CONTENT);
+             aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_FOR_OUT_OF_BAND_CONTENT ||
+             aHelper.mAllocationFlags == TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION);
   MOZ_ASSERT(aHelper.mTextureFlags & TextureFlags::RECYCLE);
 
   RefPtr<TextureClientHolder> textureHolder;
 
   {
     MutexAutoLock lock(mLock);
     if (!mPooledClients.empty()) {
       textureHolder = mPooledClients.top();
--- a/gfx/layers/client/TextureClientSharedSurface.cpp
+++ b/gfx/layers/client/TextureClientSharedSurface.cpp
@@ -27,17 +27,17 @@ namespace layers {
 SharedSurfaceTextureData::SharedSurfaceTextureData(UniquePtr<gl::SharedSurface> surf)
   : mSurf(Move(surf))
 {}
 
 SharedSurfaceTextureData::~SharedSurfaceTextureData()
 {}
 
 void
-SharedSurfaceTextureData::Deallocate(ISurfaceAllocator*)
+SharedSurfaceTextureData::Deallocate(ClientIPCAllocator*)
 {}
 
 gfx::IntSize
 SharedSurfaceTextureData::GetSize() const
 {
   return mSurf->mSize;
 }
 
@@ -45,25 +45,25 @@ bool
 SharedSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
 {
   return mSurf->ToSurfaceDescriptor(&aOutDescriptor);
 }
 
 
 SharedSurfaceTextureClient::SharedSurfaceTextureClient(SharedSurfaceTextureData* aData,
                                                        TextureFlags aFlags,
-                                                       ISurfaceAllocator* aAllocator)
+                                                       ClientIPCAllocator* aAllocator)
 : TextureClient(aData, aFlags, aAllocator)
 {
   mWorkaroundAnnoyingSharedSurfaceLifetimeIssues = true;
 }
 
 already_AddRefed<SharedSurfaceTextureClient>
 SharedSurfaceTextureClient::Create(UniquePtr<gl::SharedSurface> surf, gl::SurfaceFactory* factory,
-                                   ISurfaceAllocator* aAllocator, TextureFlags aFlags)
+                                   ClientIPCAllocator* aAllocator, TextureFlags aFlags)
 {
   if (!surf) {
     return nullptr;
   }
   TextureFlags flags = aFlags | TextureFlags::RECYCLE | surf->GetTextureFlags();
   SharedSurfaceTextureData* data = new SharedSurfaceTextureData(Move(surf));
   return MakeAndAddRef<SharedSurfaceTextureClient>(data, flags, aAllocator);
 }
--- a/gfx/layers/client/TextureClientSharedSurface.h
+++ b/gfx/layers/client/TextureClientSharedSurface.h
@@ -49,33 +49,33 @@ public:
   virtual gfx::SurfaceFormat GetFormat() const override {
     return gfx::SurfaceFormat::UNKNOWN;
   }
 
   virtual gfx::IntSize GetSize() const override;
 
   virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
 
-  virtual void Deallocate(ISurfaceAllocator*) override;
+  virtual void Deallocate(ClientIPCAllocator*) override;
 
   gl::SharedSurface* Surf() const { return mSurf.get(); }
 };
 
 class SharedSurfaceTextureClient : public TextureClient
 {
 public:
   SharedSurfaceTextureClient(SharedSurfaceTextureData* aData,
                              TextureFlags aFlags,
-                             ISurfaceAllocator* aAllocator);
+                             ClientIPCAllocator* aAllocator);
 
   ~SharedSurfaceTextureClient();
 
   static already_AddRefed<SharedSurfaceTextureClient>
   Create(UniquePtr<gl::SharedSurface> surf, gl::SurfaceFactory* factory,
-         ISurfaceAllocator* aAllocator, TextureFlags aFlags);
+         ClientIPCAllocator* aAllocator, TextureFlags aFlags);
 
   virtual void SetReleaseFenceHandle(const FenceHandle& aReleaseFenceHandle) override;
 
   virtual FenceHandle GetAndResetReleaseFenceHandle() override;
 
   virtual void SetAcquireFenceHandle(const FenceHandle& aAcquireFenceHandle) override;
 
   virtual const FenceHandle& GetAcquireFenceHandle() const override;
--- a/gfx/layers/client/TiledContentClient.cpp
+++ b/gfx/layers/client/TiledContentClient.cpp
@@ -382,25 +382,26 @@ gfxMemorySharedReadLock::ReadUnlock()
 
 int32_t
 gfxMemorySharedReadLock::GetReadCount()
 {
   NS_ASSERT_OWNINGTHREAD(gfxMemorySharedReadLock);
   return mReadCount;
 }
 
-gfxShmSharedReadLock::gfxShmSharedReadLock(ISurfaceAllocator* aAllocator)
+gfxShmSharedReadLock::gfxShmSharedReadLock(ClientIPCAllocator* aAllocator)
   : mAllocator(aAllocator)
   , mAllocSuccess(false)
 {
   MOZ_COUNT_CTOR(gfxShmSharedReadLock);
   MOZ_ASSERT(mAllocator);
   if (mAllocator) {
 #define MOZ_ALIGN_WORD(x) (((x) + 3) & ~3)
-    if (mAllocator->AllocShmemSection(MOZ_ALIGN_WORD(sizeof(ShmReadLockInfo)), &mShmemSection)) {
+    if (mAllocator->AsLayerForwarder()->GetTileLockAllocator()->AllocShmemSection(
+        MOZ_ALIGN_WORD(sizeof(ShmReadLockInfo)), &mShmemSection)) {
       ShmReadLockInfo* info = GetShmReadLockInfoPtr();
       info->readCount = 1;
       mAllocSuccess = true;
     }
   }
 }
 
 gfxShmSharedReadLock::~gfxShmSharedReadLock()
@@ -422,17 +423,23 @@ int32_t
 gfxShmSharedReadLock::ReadUnlock() {
   if (!mAllocSuccess) {
     return 0;
   }
   ShmReadLockInfo* info = GetShmReadLockInfoPtr();
   int32_t readCount = PR_ATOMIC_DECREMENT(&info->readCount);
   MOZ_ASSERT(readCount >= 0);
   if (readCount <= 0) {
-    mAllocator->FreeShmemSection(mShmemSection);
+    auto fwd = mAllocator->AsLayerForwarder();
+    if (fwd) {
+      fwd->GetTileLockAllocator()->DeallocShmemSection(mShmemSection);
+    } else {
+      // we are on the compositor process
+      FixedSizeSmallShmemSectionAllocator::FreeShmemSection(mShmemSection);
+    }
   }
   return readCount;
 }
 
 int32_t
 gfxShmSharedReadLock::GetReadCount() {
   NS_ASSERT_OWNINGTHREAD(gfxShmSharedReadLock);
   if (!mAllocSuccess) {
--- a/gfx/layers/client/TiledContentClient.h
+++ b/gfx/layers/client/TiledContentClient.h
@@ -92,17 +92,17 @@ private:
 
 class gfxShmSharedReadLock : public gfxSharedReadLock {
 private:
   struct ShmReadLockInfo {
     int32_t readCount;
   };
 
 public:
-  explicit gfxShmSharedReadLock(ISurfaceAllocator* aAllocator);
+  explicit gfxShmSharedReadLock(ClientIPCAllocator* aAllocator);
 
 protected:
   ~gfxShmSharedReadLock();
 
 public:
   virtual int32_t ReadLock() override;
 
   virtual int32_t ReadUnlock() override;
--- a/gfx/layers/composite/CompositableHost.cpp
+++ b/gfx/layers/composite/CompositableHost.cpp
@@ -143,18 +143,17 @@ void
 CompositableHost::SetCompositor(Compositor* aCompositor)
 {
   MOZ_ASSERT(aCompositor);
   mCompositor = aCompositor;
 }
 
 bool
 CompositableHost::AddMaskEffect(EffectChain& aEffects,
-                                const gfx::Matrix4x4& aTransform,
-                                bool aIs3D)
+                                const gfx::Matrix4x4& aTransform)
 {
   CompositableTextureSourceRef source;
   RefPtr<TextureHost> host = GetAsTextureHost();
 
   if (!host) {
     NS_WARNING("Using compositable with no valid TextureHost as mask");
     return false;
   }
@@ -169,17 +168,16 @@ CompositableHost::AddMaskEffect(EffectCh
     host->Unlock();
     return false;
   }
   MOZ_ASSERT(source);
 
   RefPtr<EffectMask> effect = new EffectMask(source,
                                              source->GetSize(),
                                              aTransform);
-  effect->mIs3D = aIs3D;
   aEffects.mSecondaryEffects[EffectTypes::MASK] = effect;
   return true;
 }
 
 void
 CompositableHost::RemoveMaskEffect()
 {
   RefPtr<TextureHost> host = GetAsTextureHost();
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -116,18 +116,17 @@ public:
     return gfx::IntSize();
   }
 
   /**
    * Adds a mask effect using this texture as the mask, if possible.
    * @return true if the effect was added, false otherwise.
    */
   bool AddMaskEffect(EffectChain& aEffects,
-                     const gfx::Matrix4x4& aTransform,
-                     bool aIs3D = false);
+                     const gfx::Matrix4x4& aTransform);
 
   void RemoveMaskEffect();
 
   Compositor* GetCompositor() const
   {
     return mCompositor;
   }
 
--- a/gfx/layers/composite/LayerManagerComposite.cpp
+++ b/gfx/layers/composite/LayerManagerComposite.cpp
@@ -1461,32 +1461,31 @@ LayerManagerComposite::CreateRefLayerCom
   if (LayerManagerComposite::mDestroyed) {
     NS_WARNING("Call on destroyed layer manager");
     return nullptr;
   }
   return RefPtr<RefLayerComposite>(new RefLayerComposite(this)).forget();
 }
 
 LayerManagerComposite::AutoAddMaskEffect::AutoAddMaskEffect(Layer* aMaskLayer,
-                                                            EffectChain& aEffects,
-                                                            bool aIs3D)
+                                                            EffectChain& aEffects)
   : mCompositable(nullptr), mFailed(false)
 {
   if (!aMaskLayer) {
     return;
   }
 
   mCompositable = ToLayerComposite(aMaskLayer)->GetCompositableHost();
   if (!mCompositable) {
     NS_WARNING("Mask layer with no compositable host");
     mFailed = true;
     return;
   }
 
-  if (!mCompositable->AddMaskEffect(aEffects, aMaskLayer->GetEffectiveTransform(), aIs3D)) {
+  if (!mCompositable->AddMaskEffect(aEffects, aMaskLayer->GetEffectiveTransform())) {
     mCompositable = nullptr;
     mFailed = true;
   }
 }
 
 LayerManagerComposite::AutoAddMaskEffect::~AutoAddMaskEffect()
 {
   if (!mCompositable) {
--- a/gfx/layers/composite/LayerManagerComposite.h
+++ b/gfx/layers/composite/LayerManagerComposite.h
@@ -183,18 +183,17 @@ public:
   /**
    * RAII helper class to add a mask effect with the compositable from aMaskLayer
    * to the EffectChain aEffect and notify the compositable when we are done.
    */
   class AutoAddMaskEffect
   {
   public:
     AutoAddMaskEffect(Layer* aMaskLayer,
-                      EffectChain& aEffect,
-                      bool aIs3D = false);
+                      EffectChain& aEffect);
     ~AutoAddMaskEffect();
 
     bool Failed() const { return mFailed; }
   private:
     CompositableHost* mCompositable;
     bool mFailed;
   };
 
@@ -577,26 +576,21 @@ RenderWithAllMasks(Layer* aLayer, Compos
   } else if (ancestorMaskLayerCount > 0) {
     firstMask = aLayer->GetAncestorMaskLayerAt(0);
     maskLayerCount = ancestorMaskLayerCount;
     nextAncestorMaskLayer = 1;
   } else {
     // no mask layers at all
   }
 
-  bool firstMaskIs3D = false;
-  if (ContainerLayer* container = aLayer->AsContainerLayer()) {
-    firstMaskIs3D = !container->GetTransform().CanDraw2D();
-  }
-
   if (maskLayerCount <= 1) {
     // This is the common case. Render in one pass and return.
     EffectChain effectChain(aLayer);
     LayerManagerComposite::AutoAddMaskEffect
-      autoMaskEffect(firstMask, effectChain, firstMaskIs3D);
+      autoMaskEffect(firstMask, effectChain);
     aLayer->AsLayerComposite()->AddBlendModeEffect(effectChain);
     aRenderCallback(effectChain, gfx::Rect(aClipRect));
     return;
   }
 
   // We have multiple mask layers.
   // We split our list of mask layers into three parts:
   //  (1) The first mask
@@ -625,17 +619,17 @@ RenderWithAllMasks(Layer* aLayer, Compos
     return;
   }
 
   // Render the source while applying the first mask.
   aCompositor->SetRenderTarget(firstTarget);
   {
     EffectChain firstEffectChain(aLayer);
     LayerManagerComposite::AutoAddMaskEffect
-      firstMaskEffect(firstMask, firstEffectChain, firstMaskIs3D);
+      firstMaskEffect(firstMask, firstEffectChain);
     aRenderCallback(firstEffectChain, gfx::Rect(aClipRect - surfaceRect.TopLeft()));
     // firstTarget now contains the transformed source with the first mask and
     // opacity already applied.
   }
 
   // Apply the intermediate masks.
   gfx::Rect intermediateClip(surfaceRect - surfaceRect.TopLeft());
   RefPtr<CompositingRenderTarget> previousTarget = firstTarget;
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -796,17 +796,17 @@ ShmemTextureHost::~ShmemTextureHost()
 }
 
 void
 ShmemTextureHost::DeallocateSharedData()
 {
   if (mShmem) {
     MOZ_ASSERT(mDeallocator,
                "Shared memory would leak without a ISurfaceAllocator");
-    mDeallocator->DeallocShmem(*mShmem);
+    mDeallocator->AsShmemAllocator()->DeallocShmem(*mShmem);
     mShmem = nullptr;
   }
 }
 
 void
 ShmemTextureHost::ForgetSharedData()
 {
   if (mShmem) {
--- a/gfx/layers/d3d11/BlendShaderConstants.h
+++ b/gfx/layers/d3d11/BlendShaderConstants.h
@@ -9,18 +9,17 @@
 // These constants are shared between CompositorD3D11 and the blend pixel shader.
 #define PS_LAYER_RGB          0
 #define PS_LAYER_RGBA         1
 #define PS_LAYER_YCBCR        2
 #define PS_LAYER_COLOR        3
 
 // These must be in the same order as the Mask enum.
 #define PS_MASK_NONE         0
-#define PS_MASK_2D           1
-#define PS_MASK_3D           2
+#define PS_MASK              1
 
 // These must be in the same order as CompositionOp.
 #define PS_BLEND_MULTIPLY    0
 #define PS_BLEND_SCREEN      1
 #define PS_BLEND_OVERLAY     2
 #define PS_BLEND_DARKEN      3
 #define PS_BLEND_LIGHTEN     4
 #define PS_BLEND_COLOR_DODGE 5
@@ -45,17 +44,16 @@ BlendOpToShaderConstant(gfx::Composition
 
 } // namespace layers
 } // namespace mozilla
 
 // Sanity checks.
 namespace {
 static inline void BlendShaderConstantAsserts() {
   static_assert(PS_MASK_NONE == int(mozilla::layers::MaskType::MaskNone), "shader constant is out of sync");
-  static_assert(PS_MASK_2D == int(mozilla::layers::MaskType::Mask2d), "shader constant is out of sync");
-  static_assert(PS_MASK_3D == int(mozilla::layers::MaskType::Mask3d), "shader constant is out of sync");
+  static_assert(PS_MASK == int(mozilla::layers::MaskType::Mask), "shader constant is out of sync");
   static_assert(int(mozilla::gfx::CompositionOp::OP_LUMINOSITY) - int(mozilla::gfx::CompositionOp::OP_MULTIPLY) == 14,
                 "shader constants are out of sync");
 }
 } // anonymous namespace
 #endif
 
 #endif // MOZILLA_GFX_LAYERS_D3D11_BLENDSHADERCONSTANTS_H_
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -198,19 +198,17 @@ CompositorD3D11::Initialize()
   bool force = gfxPrefs::LayersAccelerationForceEnabled();
 
   ScopedGfxFeatureReporter reporter("D3D11 Layers", force);
 
   MOZ_ASSERT(gfxPlatform::CanUseDirect3D11());
 
   HRESULT hr;
 
-  mDevice = gfxWindowsPlatform::GetPlatform()->GetD3D11Device();
-
-  if (!mDevice) {
+  if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&mDevice)) {
     return false;
   }
 
   mDevice->GetImmediateContext(getter_AddRefs(mContext));
 
   if (!mContext) {
     gfxCriticalNote << "[D3D11] failed to get immediate context";
     return false;
@@ -490,20 +488,16 @@ CompositorD3D11::CreateRenderTarget(cons
 
   if (aRect.width * aRect.height == 0) {
     return nullptr;
   }
 
   CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aRect.width, aRect.height, 1, 1,
                              D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
 
-  if (mDevice != gfxWindowsPlatform::GetPlatform()->GetD3D11Device()) {
-    gfxCriticalError() << "Out of sync D3D11 devices in CreateRenderTarget";
-  }
-
   RefPtr<ID3D11Texture2D> texture;
   HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
   if (FAILED(hr) || !texture) {
     gfxCriticalNote << "Failed in CreateRenderTarget " << hexa(hr);
     return nullptr;
   }
 
   RefPtr<CompositingRenderTargetD3D11> rt = new CompositingRenderTargetD3D11(texture, aRect.TopLeft());
@@ -527,20 +521,16 @@ CompositorD3D11::CreateTexture(const gfx
   if (aRect.width * aRect.height == 0) {
     return nullptr;
   }
 
   CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
                              aRect.width, aRect.height, 1, 1,
                              D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET);
 
-  if (mDevice != gfxWindowsPlatform::GetPlatform()->GetD3D11Device()) {
-    gfxCriticalError() << "Out of sync D3D11 devices in CreateRenderTargetFromSource";
-  }
-
   RefPtr<ID3D11Texture2D> texture;
   HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
 
   if (FAILED(hr) || !texture) {
     gfxCriticalNote << "Failed in CreateRenderTargetFromSource " << hexa(hr);
     HandleError(hr);
     return nullptr;
   }
@@ -906,22 +896,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
 
   mPSConstants.layerOpacity[0] = aOpacity;
 
   bool restoreBlendMode = false;
 
   MaskType maskType = MaskType::MaskNone;
 
   if (aEffectChain.mSecondaryEffects[EffectTypes::MASK]) {
-    if (aTransform.Is2D()) {
-      maskType = MaskType::Mask2d;
-    } else {
-      MOZ_ASSERT(aEffectChain.mPrimaryEffect->mType == EffectTypes::RGB);
-      maskType = MaskType::Mask3d;
-    }
+    maskType = MaskType::Mask;
 
     EffectMask* maskEffect =
       static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EffectTypes::MASK].get());
     TextureSourceD3D11* source = maskEffect->mMaskTexture->AsSourceD3D11();
 
     if (!source) {
       NS_WARNING("Missing texture source!");
       return;
@@ -1132,20 +1117,16 @@ CompositorD3D11::DrawQuad(const gfx::Rec
 void
 CompositorD3D11::BeginFrame(const nsIntRegion& aInvalidRegion,
                             const Rect* aClipRectIn,
                             const Rect& aRenderBounds,
                             bool aOpaque,
                             Rect* aClipRectOut,
                             Rect* aRenderBoundsOut)
 {
-  if (mDevice != gfxWindowsPlatform::GetPlatform()->GetD3D11Device()) {
-    gfxCriticalError() << "Out of sync D3D11 devices in BeginFrame";
-  }
-
   // Don't composite if we are minimised. Other than for the sake of efficency,
   // this is important because resizing our buffers when mimised will fail and
   // cause a crash when we're restored.
   NS_ASSERTION(mHwnd, "Couldn't find an HWND when initialising?");
   if (::IsIconic(mHwnd) || mDevice->GetDeviceRemovedReason() != S_OK) {
     *aRenderBoundsOut = Rect();
     return;
   }
@@ -1416,20 +1397,16 @@ CompositorD3D11::VerifyBufferSize()
   }
 
   return !mVerifyBuffersFailed;
 }
 
 bool
 CompositorD3D11::UpdateRenderTarget()
 {
-  if (mDevice != gfxWindowsPlatform::GetPlatform()->GetD3D11Device()) {
-    gfxCriticalError() << "Out of sync D3D11 devices in UpdateRenderTarget";
-  }
-
   EnsureSize();
   if (!VerifyBufferSize()) {
     gfxCriticalNote << "Failed VerifyBufferSize in UpdateRenderTarget " << mSize;
     return false;
   }
 
   if (mDefaultRT) {
     return true;
@@ -1474,20 +1451,16 @@ DeviceAttachmentsD3D11::InitSyncObject()
 
   // It's okay to do this on Windows 8. But for now we'll just bail
   // whenever we're using WARP.
   CD3D11_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, 1, 1, 1, 1,
                              D3D11_BIND_SHADER_RESOURCE |
                              D3D11_BIND_RENDER_TARGET);
   desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
 
-  if (mDevice != gfxWindowsPlatform::GetPlatform()->GetD3D11Device()) {
-    gfxCriticalError() << "Out of sync D3D11 devices in InitSyncObject";
-  }
-
   RefPtr<ID3D11Texture2D> texture;
   HRESULT hr = mDevice->CreateTexture2D(&desc, nullptr, getter_AddRefs(texture));
   if (Failed(hr, "create sync texture")) {
     return false;
   }
 
   hr = texture->QueryInterface((IDXGIResource**)getter_AddRefs(mSyncTexture));
   if (Failed(hr, "QI sync texture")) {
@@ -1507,44 +1480,41 @@ DeviceAttachmentsD3D11::InitSyncObject()
   return true;
 }
 
 bool
 DeviceAttachmentsD3D11::InitBlendShaders()
 {
   if (!mVSQuadBlendShader[MaskType::MaskNone]) {
     InitVertexShader(sLayerQuadBlendVS, mVSQuadBlendShader, MaskType::MaskNone);
-    InitVertexShader(sLayerQuadBlendMaskVS, mVSQuadBlendShader, MaskType::Mask2d);
-    InitVertexShader(sLayerQuadBlendMask3DVS, mVSQuadBlendShader, MaskType::Mask3d);
+    InitVertexShader(sLayerQuadBlendMaskVS, mVSQuadBlendShader, MaskType::Mask);
   }
   if (!mBlendShader[MaskType::MaskNone]) {
     InitPixelShader(sBlendShader, mBlendShader, MaskType::MaskNone);
   }
   return mInitOkay;
 }
 
 bool
 DeviceAttachmentsD3D11::CreateShaders()
 {
   InitVertexShader(sLayerQuadVS, mVSQuadShader, MaskType::MaskNone);
-  InitVertexShader(sLayerQuadMaskVS, mVSQuadShader, MaskType::Mask2d);
-  InitVertexShader(sLayerQuadMask3DVS, mVSQuadShader, MaskType::Mask3d);
+  InitVertexShader(sLayerQuadMaskVS, mVSQuadShader, MaskType::Mask);
 
   InitPixelShader(sSolidColorShader, mSolidColorShader, MaskType::MaskNone);
-  InitPixelShader(sSolidColorShaderMask, mSolidColorShader, MaskType::Mask2d);
+  InitPixelShader(sSolidColorShaderMask, mSolidColorShader, MaskType::Mask);
   InitPixelShader(sRGBShader, mRGBShader, MaskType::MaskNone);
-  InitPixelShader(sRGBShaderMask, mRGBShader, MaskType::Mask2d);
+  InitPixelShader(sRGBShaderMask, mRGBShader, MaskType::Mask);
   InitPixelShader(sRGBAShader, mRGBAShader, MaskType::MaskNone);
-  InitPixelShader(sRGBAShaderMask, mRGBAShader, MaskType::Mask2d);
-  InitPixelShader(sRGBAShaderMask3D, mRGBAShader, MaskType::Mask3d);
+  InitPixelShader(sRGBAShaderMask, mRGBAShader, MaskType::Mask);
   InitPixelShader(sYCbCrShader, mYCbCrShader, MaskType::MaskNone);
-  InitPixelShader(sYCbCrShaderMask, mYCbCrShader, MaskType::Mask2d);
+  InitPixelShader(sYCbCrShaderMask, mYCbCrShader, MaskType::Mask);
   if (gfxPrefs::ComponentAlphaEnabled()) {
     InitPixelShader(sComponentAlphaShader, mComponentAlphaShader, MaskType::MaskNone);
-    InitPixelShader(sComponentAlphaShaderMask, mComponentAlphaShader, MaskType::Mask2d);
+    InitPixelShader(sComponentAlphaShaderMask, mComponentAlphaShader, MaskType::Mask);
   }
 
   InitVertexShader(sOculus050VRDistortionVS, getter_AddRefs(mVRDistortionVS[VRHMDType::Oculus050]));
   InitPixelShader(sOculus050VRDistortionPS, getter_AddRefs(mVRDistortionPS[VRHMDType::Oculus050]));
 
   // These are shared
   // XXX rename Oculus050 shaders to something more generic
   mVRDistortionVS[VRHMDType::Cardboard] = mVRDistortionVS[VRHMDType::Oculus050];
@@ -1623,20 +1593,16 @@ CompositorD3D11::PaintToTarget()
   CD3D11_TEXTURE2D_DESC softDesc(bbDesc.Format, bbDesc.Width, bbDesc.Height);
   softDesc.MipLevels = 1;
   softDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
   softDesc.Usage = D3D11_USAGE_STAGING;
   softDesc.BindFlags = 0;
 
   RefPtr<ID3D11Texture2D> readTexture;
 
-  if (mDevice != gfxWindowsPlatform::GetPlatform()->GetD3D11Device()) {
-    gfxCriticalError() << "Out of sync D3D11 devices in PaintToTarget";
-  }
-
   hr = mDevice->CreateTexture2D(&softDesc, nullptr, getter_AddRefs(readTexture));
   if (FAILED(hr)) {
     gfxCriticalErrorOnce(gfxCriticalError::DefaultOptions(false)) << "Failed in PaintToTarget 2";
     HandleError(hr);
     return;
   }
   mContext->CopyResource(readTexture, backBuf);
 
@@ -1676,17 +1642,18 @@ CompositorD3D11::HandleError(HRESULT hr,
   if (SUCCEEDED(hr)) {
     return;
   }
 
   if (aSeverity == Critical) {
     MOZ_CRASH("GFX: Unrecoverable D3D11 error");
   }
 
-  if (mDevice != gfxWindowsPlatform::GetPlatform()->GetD3D11Device()) {
+  RefPtr<ID3D11Device> device;
+  if (!gfxWindowsPlatform::GetPlatform()->GetD3D11Device(&device) || device != mDevice) {
     gfxCriticalError() << "Out of sync D3D11 devices in HandleError, " << (int)mVerifyBuffersFailed;
   }
 
   HRESULT hrOnReset = S_OK;
   bool deviceRemoved = hr == DXGI_ERROR_DEVICE_REMOVED;
 
   if (deviceRemoved && mDevice) {
     hrOnReset = mDevice->GetDeviceRemovedReason();
--- a/gfx/layers/d3d11/CompositorD3D11.hlsl
+++ b/gfx/layers/d3d11/CompositorD3D11.hlsl
@@ -44,22 +44,16 @@ struct VS_INPUT {
 struct VS_OUTPUT {
   float4 vPosition : SV_Position;
   float2 vTexCoords : TEXCOORD0;
 };
 
 struct VS_MASK_OUTPUT {
   float4 vPosition : SV_Position;
   float2 vTexCoords : TEXCOORD0;
-  float2 vMaskCoords : TEXCOORD1;
-};
-
-struct VS_MASK_3D_OUTPUT {
-  float4 vPosition : SV_Position;
-  float2 vTexCoords : TEXCOORD0;
   float3 vMaskCoords : TEXCOORD1;
 };
 
 // Combined struct for the mix-blend compatible vertex shaders.
 struct VS_BLEND_OUTPUT {
   float4 vPosition : SV_Position;
   float2 vTexCoords : TEXCOORD0;
   float3 vMaskCoords : TEXCOORD1;
@@ -148,33 +142,16 @@ VS_MASK_OUTPUT LayerQuadMaskVS(const VS_
   VS_MASK_OUTPUT outp;
   float4 position = TransformedPosition(aVertex.vPosition);
 
   outp.vPosition = VertexPosition(position);
 
   // calculate the position on the mask texture
   outp.vMaskCoords.x = (position.x - vMaskQuad.x) / vMaskQuad.z;
   outp.vMaskCoords.y = (position.y - vMaskQuad.y) / vMaskQuad.w;
-
-  outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
-
-  return outp;
-}
-
-VS_MASK_3D_OUTPUT LayerQuadMask3DVS(const VS_INPUT aVertex)
-{
-  VS_MASK_3D_OUTPUT outp;
-  float4 position = TransformedPosition(aVertex.vPosition);
-
-  outp.vPosition = VertexPosition(position);
-
-  // calculate the position on the mask texture
-  position.xyz /= position.w;
-  outp.vMaskCoords.x = (position.x - vMaskQuad.x) / vMaskQuad.z;
-  outp.vMaskCoords.y = (position.y - vMaskQuad.y) / vMaskQuad.w;
   // We use the w coord to do non-perspective correct interpolation:
   // the quad might be transformed in 3D, in which case it will have some
   // perspective. The graphics card will do perspective-correct interpolation
   // of the texture, but our mask is already transformed and so we require
   // linear interpolation. Therefore, we must correct the interpolation
   // ourselves, we do this by multiplying all coords by w here, and dividing by
   // w in the pixel shader (post-interpolation), we pass w in outp.vMaskCoords.z.
   // See http://en.wikipedia.org/wiki/Texture_mapping#Perspective_correctness
@@ -183,35 +160,28 @@ VS_MASK_3D_OUTPUT LayerQuadMask3DVS(cons
 
   outp.vTexCoords = TexCoords(aVertex.vPosition.xy);
 
   return outp;
 }
 
 float4 RGBAShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
-  float2 maskCoords = aVertex.vMaskCoords;
+  float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
   float mask = tMask.Sample(sSampler, maskCoords).r;
   return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * mask;
 }
 
-float4 RGBAShaderMask3D(const VS_MASK_3D_OUTPUT aVertex) : SV_Target
-{
-  float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
-  float mask = tMask.Sample(LayerTextureSamplerLinear, maskCoords).r;
-  return tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity * mask;
-}
-
 float4 RGBShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
   float4 result;
   result = tRGB.Sample(sSampler, aVertex.vTexCoords) * fLayerOpacity;
   result.a = fLayerOpacity;
 
-  float2 maskCoords = aVertex.vMaskCoords;
+  float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
   float mask = tMask.Sample(sSampler, maskCoords).r;
   return result * mask;
 }
 
 /* From Rec601:
 [R]   [1.1643835616438356,  0.0,                 1.5960267857142858]      [ Y -  16]
 [G] = [1.1643835616438358, -0.3917622900949137, -0.8129676472377708]    x [Cb - 128]
 [B]   [1.1643835616438356,  2.017232142857143,   8.862867620416422e-17]   [Cr - 128]
@@ -235,41 +205,41 @@ float4 CalculateYCbCrColor(const float2 
   color.b = yuv.g * 1.16438 + yuv.b * 2.01723;
   color.a = 1.0f;
 
   return color;
 }
 
 float4 YCbCrShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
-  float2 maskCoords = aVertex.vMaskCoords;
+  float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
   float mask = tMask.Sample(sSampler, maskCoords).r;
 
   return CalculateYCbCrColor(aVertex.vTexCoords) * fLayerOpacity * mask;
 }
 
 PS_OUTPUT ComponentAlphaShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
   PS_OUTPUT result;
 
   result.vSrc = tRGB.Sample(sSampler, aVertex.vTexCoords);
   result.vAlpha = 1.0 - tRGBWhite.Sample(sSampler, aVertex.vTexCoords) + result.vSrc;
   result.vSrc.a = result.vAlpha.g;
 
-  float2 maskCoords = aVertex.vMaskCoords;
+  float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
   float mask = tMask.Sample(sSampler, maskCoords).r;
   result.vSrc *= fLayerOpacity * mask;
   result.vAlpha *= fLayerOpacity * mask;
 
   return result;
 }
 
 float4 SolidColorShaderMask(const VS_MASK_OUTPUT aVertex) : SV_Target
 {
-  float2 maskCoords = aVertex.vMaskCoords;
+  float2 maskCoords = aVertex.vMaskCoords.xy / aVertex.vMaskCoords.z;
   float mask = tMask.Sample(sSampler, maskCoords).r;
   return fLayerColor * mask;
 }
 
 /*
  *  Un-masked versions
  *************************************************************
  */
@@ -323,28 +293,16 @@ VS_BLEND_OUTPUT LayerQuadBlendVS(const V
 
 VS_BLEND_OUTPUT LayerQuadBlendMaskVS(const VS_INPUT aVertex)
 {
   VS_MASK_OUTPUT v = LayerQuadMaskVS(aVertex);
 
   VS_BLEND_OUTPUT o;
   o.vPosition = v.vPosition;
   o.vTexCoords = v.vTexCoords;
-  o.vMaskCoords = float3(v.vMaskCoords, 0);
-  o.vBackdropCoords = BackdropPosition(v.vPosition);
-  return o;
-}
-
-VS_BLEND_OUTPUT LayerQuadBlendMask3DVS(const VS_INPUT aVertex)
-{
-  VS_MASK_3D_OUTPUT v = LayerQuadMask3DVS(aVertex);
-
-  VS_BLEND_OUTPUT o;
-  o.vPosition = v.vPosition;
-  o.vTexCoords = v.vTexCoords;
   o.vMaskCoords = v.vMaskCoords;
   o.vBackdropCoords = BackdropPosition(v.vPosition);
   return o;
 }
 
 // The layer type and mask type are specified as constants. We use these to
 // call the correct pixel shader to determine the source color for blending.
 // Unfortunately this also requires some boilerplate to convert VS_BLEND_OUTPUT
@@ -362,33 +320,26 @@ float4 ComputeBlendSourceColor(const VS_
     } else if (iBlendConfig.x == PS_LAYER_YCBCR) {
       return YCbCrShader(tmp);
     }
     return SolidColorShader(tmp);
   } else if (iBlendConfig.y == PS_MASK_2D) {
     VS_MASK_OUTPUT tmp;
     tmp.vPosition = aVertex.vPosition;
     tmp.vTexCoords = aVertex.vTexCoords;
-    tmp.vMaskCoords = aVertex.vMaskCoords.xy;
+    tmp.vMaskCoords = aVertex.vMaskCoords;
 
     if (iBlendConfig.x == PS_LAYER_RGB) {
       return RGBShaderMask(tmp);
     } else if (iBlendConfig.x == PS_LAYER_RGBA) {
       return RGBAShaderMask(tmp);
     } else if (iBlendConfig.x == PS_LAYER_YCBCR) {
       return YCbCrShaderMask(tmp);
     }
     return SolidColorShaderMask(tmp);
-  } else if (iBlendConfig.y == PS_MASK_3D) {
-    // The only Mask 3D shader is RGBA.
-    VS_MASK_3D_OUTPUT tmp;
-    tmp.vPosition = aVertex.vPosition;
-    tmp.vTexCoords = aVertex.vTexCoords;
-    tmp.vMaskCoords = aVertex.vMaskCoords;
-    return RGBAShaderMask3D(tmp);
   }
 
   return float4(0.0, 0.0, 0.0, 1.0);
 }
 
 float3 ChooseBlendFunc(float3 dest, float3 src)
 {
   [flatten] switch (iBlendConfig.z) {
--- a/gfx/layers/d3d11/CompositorD3D11Shaders.h
+++ b/gfx/layers/d3d11/CompositorD3D11Shaders.h
@@ -1,12 +1,12 @@
 struct ShaderBytes { const void* mData; size_t mLength; };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4x4 mLayerTransform;          // Offset:    0 Size:    64
@@ -20,19 +20,19 @@ struct ShaderBytes { const void* mData; 
 //   float fLayerOpacity;               // Offset:  272 Size:     4 [unused]
 //   uint4 iBlendConfig;                // Offset:  288 Size:    16 [unused]
 //
 // }
 //
 //
 // Resource Bindings:
 //
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// $Globals                          cbuffer      NA          NA    0        1
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// $Globals                          cbuffer      NA          NA            cb0      1 
 //
 //
 //
 // Input signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // POSITION                 0   xy          0     NONE   float   xy  
@@ -78,17 +78,17 @@ struct ShaderBytes { const void* mData; 
     mad r1, c4, r0.x, r1
     mad r1, c6, r0.z, r1
     mad r0, c7, r0.w, r1
     mad oPos.xy, r0.w, c0, r0
     mov oPos.zw, r0
 
 // approximately 15 instruction slots used
 vs_4_0
-dcl_constantbuffer cb0[11], immediateIndexed
+dcl_constantbuffer CB0[11], immediateIndexed
 dcl_input v0.xy
 dcl_output_siv o0.xyzw, position
 dcl_output o1.xy
 dcl_temps 2
 mad r0.xy, v0.xyxx, cb0[10].zwzz, cb0[10].xyxx
 mul r1.xyzw, r0.yyyy, cb0[1].xyzw
 mad r0.xyzw, cb0[0].xyzw, r0.xxxx, r1.xyzw
 add r0.xyzw, r0.xyzw, cb0[3].xyzw
@@ -101,20 +101,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, 141, 229, 
-     88, 115,  31, 138,  49,  78, 
-     16,   5,  63, 222, 239, 137, 
-    213,  18,   1,   0,   0,   0, 
+     68,  88,  66,  67, 112,  85, 
+    167,  74,  15, 232,  29,  85, 
+    162,  39, 212, 215,  65, 102, 
+    169, 150,   1,   0,   0,   0, 
      24,   7,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     152,   1,   0,   0, 160,   3, 
       0,   0,  28,   4,   0,   0, 
     140,   6,   0,   0, 192,   6, 
       0,   0,  65, 111, 110,  57, 
      88,   1,   0,   0,  88,   1, 
       0,   0,   0,   2, 254, 255, 
@@ -377,20 +377,20 @@ const BYTE LayerQuadVS[] =
       1,   0,  19,   0,   1,   0, 
       4,   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,  54,  46,  51, 
-     46,  57,  54,  48,  48,  46, 
-     49,  54,  51,  56,  52,   0, 
-    171, 171,  73,  83,  71,  78, 
+    101, 114,  32,  49,  48,  46, 
+     48,  46,  49,  48,  48,  49, 
+     49,  46,  49,  54,  51,  56, 
+     52,   0,  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, 
@@ -408,17 +408,17 @@ const BYTE LayerQuadVS[] =
      95,  80, 111, 115, 105, 116, 
     105, 111, 110,   0,  84,  69, 
      88,  67,  79,  79,  82,  68, 
       0, 171, 171, 171
 };
 ShaderBytes sLayerQuadVS = { LayerQuadVS, sizeof(LayerQuadVS) };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16
@@ -432,19 +432,19 @@ ShaderBytes sLayerQuadVS = { LayerQuadVS
 //   float4 vMaskQuad;                  // Offset:  224 Size:    16 [unused]
 //   float4x4 mBackdropTransform;       // Offset:  240 Size:    64 [unused]
 //
 // }
 //
 //
 // Resource Bindings:
 //
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// $Globals                          cbuffer      NA          NA    0        1
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// $Globals                          cbuffer      NA          NA            cb0      1 
 //
 //
 //
 // Input signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // SV_Position              0   xyzw        0      POS   float       
@@ -467,29 +467,29 @@ ShaderBytes sLayerQuadVS = { LayerQuadVS
 //
 // Level9 shader bytecode:
 //
     ps_2_x
     mov oC0, c0
 
 // approximately 1 instruction slot used
 ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
+dcl_constantbuffer CB0[1], immediateIndexed
 dcl_output o0.xyzw
 mov o0.xyzw, cb0[0].xyzw
 ret 
 // Approximately 2 instruction slots used
 #endif
 
 const BYTE SolidColorShader[] =
 {
-     68,  88,  66,  67,  46, 104, 
-    157, 133, 222, 110,  60, 127, 
-    132, 226, 126, 208, 247, 164, 
-     42, 238,   1,   0,   0,   0, 
+     68,  88,  66,  67, 232, 227, 
+     42, 205, 188, 244, 239,  58, 
+     34,  67,  23,  11,   8, 108, 
+    224,  50,   1,   0,   0,   0, 
      68,   4,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     132,   0,   0,   0, 204,   0, 
       0,   0,  72,   1,   0,   0, 
     184,   3,   0,   0,  16,   4, 
       0,   0,  65, 111, 110,  57, 
      68,   0,   0,   0,  68,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -631,20 +631,20 @@ const BYTE SolidColorShader[] =
      66,  97,  99, 107, 100, 114, 
     111, 112,  84, 114,  97, 110, 
     115, 102, 111, 114, 109,   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, 
+    105, 108, 101, 114,  32,  49, 
+     48,  46,  48,  46,  49,  48, 
+     48,  49,  49,  46,  49,  54, 
+     51,  56,  52,   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, 
@@ -662,17 +662,17 @@ const BYTE SolidColorShader[] =
       3,   0,   0,   0,   0,   0, 
       0,   0,  15,   0,   0,   0, 
      83,  86,  95,  84,  97, 114, 
     103, 101, 116,   0, 171, 171
 };
 ShaderBytes sSolidColorShader = { SolidColorShader, sizeof(SolidColorShader) };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -686,21 +686,21 @@ ShaderBytes sSolidColorShader = { SolidC
 //   float4 vMaskQuad;                  // Offset:  224 Size:    16 [unused]
 //   float4x4 mBackdropTransform;       // Offset:  240 Size:    64 [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
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// sSampler                          sampler      NA          NA             s0      1 
+// tRGB                              texture  float4          2d             t0      1 
+// $Globals                          cbuffer      NA          NA            cb0      1 
 //
 //
 //
 // Input signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // SV_Position              0   xyzw        0      POS   float       
@@ -735,35 +735,35 @@ ShaderBytes sSolidColorShader = { SolidC
     dcl_2d s0
     texld r0, t0, s0
     mul r0.xyz, r0, c0.x
     mov r0.w, c0.x
     mov oC0, r0
 
 // approximately 4 instruction slots used (1 texture, 3 arithmetic)
 ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
+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.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,  65, 119, 
-     74, 180, 122,  23,  76,  16, 
-    140,  81, 225, 186, 127, 137, 
-     70, 249,   1,   0,   0,   0, 
+     68,  88,  66,  67, 125, 240, 
+    204, 179, 182, 100,  41,   5, 
+      9, 193, 104, 239, 180, 186, 
+    251,   1,   1,   0,   0,   0, 
      76,   5,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     204,   0,   0,   0, 136,   1, 
       0,   0,   4,   2,   0,   0, 
     192,   4,   0,   0,  24,   5, 
       0,   0,  65, 111, 110,  57, 
     140,   0,   0,   0, 140,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -949,20 +949,20 @@ const BYTE RGBShader[] =
      66,  97,  99, 107, 100, 114, 
     111, 112,  84, 114,  97, 110, 
     115, 102, 111, 114, 109,   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, 
+    105, 108, 101, 114,  32,  49, 
+     48,  46,  48,  46,  49,  48, 
+     48,  49,  49,  46,  49,  54, 
+     51,  56,  52,   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, 
@@ -980,17 +980,17 @@ const BYTE RGBShader[] =
       3,   0,   0,   0,   0,   0, 
       0,   0,  15,   0,   0,   0, 
      83,  86,  95,  84,  97, 114, 
     103, 101, 116,   0, 171, 171
 };
 ShaderBytes sRGBShader = { RGBShader, sizeof(RGBShader) };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -1004,21 +1004,21 @@ ShaderBytes sRGBShader = { RGBShader, si
 //   float4 vMaskQuad;                  // Offset:  224 Size:    16 [unused]
 //   float4x4 mBackdropTransform;       // Offset:  240 Size:    64 [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
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// sSampler                          sampler      NA          NA             s0      1 
+// tRGB                              texture  float4          2d             t0      1 
+// $Globals                          cbuffer      NA          NA            cb0      1 
 //
 //
 //
 // Input signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // SV_Position              0   xyzw        0      POS   float       
@@ -1052,34 +1052,34 @@ ShaderBytes sRGBShader = { RGBShader, si
     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_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, 134, 186, 
-    102, 217,  28, 249, 237,  84, 
-     31,  38,   2, 143, 235, 216, 
-    237, 103,   1,   0,   0,   0, 
+     68,  88,  66,  67, 199, 240, 
+    113, 171,  34, 194, 134, 123, 
+    243,  63, 156, 246,   8, 157, 
+     15,  85,   1,   0,   0,   0, 
      40,   5,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     192,   0,   0,   0, 100,   1, 
       0,   0, 224,   1,   0,   0, 
     156,   4,   0,   0, 244,   4, 
       0,   0,  65, 111, 110,  57, 
     128,   0,   0,   0, 128,   0, 
       0,   0,   0,   2, 255, 255, 
@@ -1259,20 +1259,20 @@ const BYTE RGBAShader[] =
      66,  97,  99, 107, 100, 114, 
     111, 112,  84, 114,  97, 110, 
     115, 102, 111, 114, 109,   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, 
+    105, 108, 101, 114,  32,  49, 
+     48,  46,  48,  46,  49,  48, 
+     48,  49,  49,  46,  49,  54, 
+     51,  56,  52,   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, 
@@ -1290,17 +1290,17 @@ const BYTE RGBAShader[] =
       3,   0,   0,   0,   0,   0, 
       0,   0,  15,   0,   0,   0, 
      83,  86,  95,  84,  97, 114, 
     103, 101, 116,   0, 171, 171
 };
 ShaderBytes sRGBAShader = { RGBAShader, sizeof(RGBAShader) };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -1314,22 +1314,22 @@ ShaderBytes sRGBAShader = { RGBAShader, 
 //   float4 vMaskQuad;                  // Offset:  224 Size:    16 [unused]
 //   float4x4 mBackdropTransform;       // Offset:  240 Size:    64 [unused]
 //
 // }
 //
 //
 // Resource Bindings:
 //
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// sSampler                          sampler      NA          NA    0        1
-// tRGB                              texture  float4          2d    0        1
-// tRGBWhite                         texture  float4          2d    4        1
-// $Globals                          cbuffer      NA          NA    0        1
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// sSampler                          sampler      NA          NA             s0      1 
+// tRGB                              texture  float4          2d             t0      1 
+// tRGBWhite                         texture  float4          2d             t4      1 
+// $Globals                          cbuffer      NA          NA            cb0      1 
 //
 //
 //
 // Input signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // SV_Position              0   xyzw        0      POS   float       
@@ -1373,17 +1373,17 @@ ShaderBytes sRGBAShader = { RGBAShader, 
     mov r0.w, r1.y
     mul r1, r1, c0.x
     mov oC1, r1
     mul r0, r0, c0.x
     mov oC0, r0
 
 // approximately 9 instruction slots used (2 texture, 7 arithmetic)
 ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
+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) t4
 dcl_input_ps linear v1.xy
 dcl_output o0.xyzw
 dcl_output o1.xyzw
 dcl_temps 2
 sample r0.xyzw, v1.xyxx, t4.xyzw, s0
@@ -1394,20 +1394,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,  70,  65, 
-    219,  11, 235,  82,  64, 151, 
-     37, 101,  86, 144,  19,   4, 
-    125, 155,   1,   0,   0,   0, 
+     68,  88,  66,  67, 207,  79, 
+     99, 143,  94, 253,  50, 234, 
+    183, 114, 100, 130, 114, 218, 
+    230, 139,   1,   0,   0,   0, 
     168,   6,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
      64,   1,   0,   0, 160,   2, 
       0,   0,  28,   3,   0,   0, 
       4,   6,   0,   0,  92,   6, 
       0,   0,  65, 111, 110,  57, 
       0,   1,   0,   0,   0,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -1647,20 +1647,20 @@ const BYTE ComponentAlphaShader[] =
      66,  97,  99, 107, 100, 114, 
     111, 112,  84, 114,  97, 110, 
     115, 102, 111, 114, 109,   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, 
+    105, 108, 101, 114,  32,  49, 
+     48,  46,  48,  46,  49,  48, 
+     48,  49,  49,  46,  49,  54, 
+     51,  56,  52,   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, 
@@ -1682,17 +1682,17 @@ const BYTE ComponentAlphaShader[] =
       3,   0,   0,   0,   1,   0, 
       0,   0,  15,   0,   0,   0, 
      83,  86,  95,  84,  97, 114, 
     103, 101, 116,   0, 171, 171
 };
 ShaderBytes sComponentAlphaShader = { ComponentAlphaShader, sizeof(ComponentAlphaShader) };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -1706,23 +1706,23 @@ ShaderBytes sComponentAlphaShader = { Co
 //   float4 vMaskQuad;                  // Offset:  224 Size:    16 [unused]
 //   float4x4 mBackdropTransform;       // Offset:  240 Size:    64 [unused]
 //
 // }
 //
 //
 // Resource Bindings:
 //
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// sSampler                          sampler      NA          NA    0        1
-// tY                                texture  float4          2d    1        1
-// tCb                               texture  float4          2d    2        1
-// tCr                               texture  float4          2d    3        1
-// $Globals                          cbuffer      NA          NA    0        1
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// sSampler                          sampler      NA          NA             s0      1 
+// tY                                texture  float4          2d             t1      1 
+// tCb                               texture  float4          2d             t2      1 
+// tCr                               texture  float4          2d             t3      1 
+// $Globals                          cbuffer      NA          NA            cb0      1 
 //
 //
 //
 // Input signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // SV_Position              0   xyzw        0      POS   float       
@@ -1774,17 +1774,17 @@ ShaderBytes sComponentAlphaShader = { Co
     mul r0.y, r0.y, c2.y
     mad r1.z, r0.x, c2.x, r0.y
     mov r1.w, c2.w
     mul r0, r1, c0.x
     mov oC0, r0
 
 // approximately 15 instruction slots used (3 texture, 12 arithmetic)
 ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
+dcl_constantbuffer CB0[2], immediateIndexed
 dcl_sampler s0, mode_default
 dcl_resource_texture2d (float,float,float,float) t1
 dcl_resource_texture2d (float,float,float,float) t2
 dcl_resource_texture2d (float,float,float,float) t3
 dcl_input_ps linear v1.xy
 dcl_output o0.xyzw
 dcl_temps 3
 sample r0.xyzw, v1.xyxx, t3.xyzw, s0
@@ -1802,20 +1802,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,  17, 182, 
-    131, 145, 148,  37, 135, 136, 
-    214,  75, 157,  57,  87,  83, 
-    119, 226,   1,   0,   0,   0, 
+     68,  88,  66,  67,  38, 102, 
+    184,  10,  33,  16, 211, 116, 
+    233, 219, 255, 155, 108,  20, 
+     81, 243,   1,   0,   0,   0, 
      56,   8,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
     220,   1,   0,   0,  44,   4, 
       0,   0, 168,   4,   0,   0, 
     172,   7,   0,   0,   4,   8, 
       0,   0,  65, 111, 110,  57, 
     156,   1,   0,   0, 156,   1, 
       0,   0,   0,   2, 255, 255, 
@@ -2126,20 +2126,20 @@ const BYTE YCbCrShader[] =
      99, 107, 100, 114, 111, 112, 
      84, 114,  97, 110, 115, 102, 
     111, 114, 109,   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, 
+    101, 114,  32,  49,  48,  46, 
+     48,  46,  49,  48,  48,  49, 
+     49,  46,  49,  54,  51,  56, 
+     52,   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, 
@@ -2157,17 +2157,17 @@ const BYTE YCbCrShader[] =
       0,   0,   0,   0,   0,   0, 
      15,   0,   0,   0,  83,  86, 
      95,  84,  97, 114, 103, 101, 
     116,   0, 171, 171
 };
 ShaderBytes sYCbCrShader = { YCbCrShader, sizeof(YCbCrShader) };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4x4 mLayerTransform;          // Offset:    0 Size:    64
@@ -2181,474 +2181,19 @@ ShaderBytes sYCbCrShader = { YCbCrShader
 //   float fLayerOpacity;               // Offset:  272 Size:     4 [unused]
 //   uint4 iBlendConfig;                // Offset:  288 Size:    16 [unused]
 //
 // }
 //
 //
 // 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  
-//
-//
-// Output signature:
-//
-// Name                 Index   Mask Register SysValue  Format   Used
-// -------------------- ----- ------ -------- -------- ------- ------
-// SV_Position              0   xyzw        0      POS   float   xyzw
-// TEXCOORD                 0   xy          1     NONE   float   xy  
-// TEXCOORD                 1     zw        1     NONE   float     zw
-//
-//
-// Constant buffer to DX9 shader constant mappings:
-//
-// Target Reg Buffer  Start Reg # of Regs        Data Conversion
-// ---------- ------- --------- --------- ----------------------
-// c1         cb0             0         2  ( FLT, FLT, FLT, FLT)
-// c3         cb0             3         9  ( FLT, FLT, FLT, FLT)
-//
-//
-// Runtime generated constant mappings:
-//
-// Target Reg                               Constant Description
-// ---------- --------------------------------------------------
-// c0                              Vertex Shader position offset
-//
-//
-// Level9 shader bytecode:
-//
-    vs_2_x
-    dcl_texcoord v0
-    rcp r0.x, c11.z
-    mad r0.yz, v0.xxyw, c10.xzww, c10.xxyw
-    mul r1, r0.z, c2
-    mad r1, c1, r0.y, r1
-    add r1, r1, c3
-    add r0.yz, r1.xxyw, -c11.xxyw
-    mul oT0.w, r0.x, r0.y
-    rcp r0.x, c11.w
-    mul oT0.z, r0.x, r0.z
-    mad oT0.xy, v0, c9.zwzw, c9
-    rcp r0.x, r1.w
-    mul r1.xyz, r0.x, r1
-    add r0, r1, -c8
-    mul r0.xyz, r0.w, r0
-    mul r1, r0.y, c5
-    mad r1, c4, r0.x, r1
-    mad r1, c6, r0.z, r1
-    mad r0, c7, r0.w, r1
-    mad oPos.xy, r0.w, c0, r0
-    mov oPos.zw, r0
-
-// approximately 20 instruction slots used
-vs_4_0
-dcl_constantbuffer cb0[12], immediateIndexed
-dcl_input v0.xy
-dcl_output_siv o0.xyzw, position
-dcl_output o1.xy
-dcl_output o1.zw
-dcl_temps 2
-mad r0.xy, v0.xyxx, cb0[10].zwzz, cb0[10].xyxx
-mul r1.xyzw, r0.yyyy, cb0[1].xyzw
-mad r0.xyzw, cb0[0].xyzw, r0.xxxx, r1.xyzw
-add r0.xyzw, r0.xyzw, cb0[3].xyzw
-div r1.xyz, r0.xyzx, r0.wwww
-mov r1.w, r0.w
-add r0.xy, r0.xyxx, -cb0[11].xyxx
-div o1.zw, r0.xxxy, cb0[11].zzzw
-add r0.xyzw, r1.xyzw, -cb0[8].xyzw
-mul r0.xyz, r0.wwww, r0.xyzx
-mul r1.xyzw, r0.yyyy, cb0[5].xyzw
-mad r1.xyzw, cb0[4].xyzw, r0.xxxx, r1.xyzw
-mad r1.xyzw, cb0[6].xyzw, r0.zzzz, r1.xyzw
-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, 117, 253, 
-    188, 162, 139, 208,  50, 178, 
-     49,   2, 251, 153, 144, 237, 
-    178, 212,   1,   0,   0,   0, 
-    220,   7,   0,   0,   6,   0, 
-      0,   0,  56,   0,   0,   0, 
-    224,   1,   0,   0,  76,   4, 
-      0,   0, 200,   4,   0,   0, 
-     56,   7,   0,   0, 108,   7, 
-      0,   0,  65, 111, 110,  57, 
-    160,   1,   0,   0, 160,   1, 
-      0,   0,   0,   2, 254, 255, 
-     96,   1,   0,   0,  64,   0, 
-      0,   0,   2,   0,  36,   0, 
-      0,   0,  60,   0,   0,   0, 
-     60,   0,   0,   0,  36,   0, 
-      1,   0,  60,   0,   0,   0, 
-      0,   0,   2,   0,   1,   0, 
-      0,   0,   0,   0,   0,   0, 
-      3,   0,   9,   0,   3,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   1,   2, 254, 255, 
-     31,   0,   0,   2,   5,   0, 
-      0, 128,   0,   0,  15, 144, 
-      6,   0,   0,   2,   0,   0, 
-      1, 128,  11,   0, 170, 160, 
-      4,   0,   0,   4,   0,   0, 
-      6, 128,   0,   0, 208, 144, 
-     10,   0, 248, 160,  10,   0, 
-    208, 160,   5,   0,   0,   3, 
-      1,   0,  15, 128,   0,   0, 
-    170, 128,   2,   0, 228, 160, 
-      4,   0,   0,   4,   1,   0, 
-     15, 128,   1,   0, 228, 160, 
-      0,   0,  85, 128,   1,   0, 
-    228, 128,   2,   0,   0,   3, 
-      1,   0,  15, 128,   1,   0, 
-    228, 128,   3,   0, 228, 160, 
-      2,   0,   0,   3,   0,   0, 
-      6, 128,   1,   0, 208, 128, 
-     11,   0, 208, 161,   5,   0, 
-      0,   3,   0,   0,   8, 224, 
-      0,   0,   0, 128,   0,   0, 
-     85, 128,   6,   0,   0,   2, 
-      0,   0,   1, 128,  11,   0, 
-    255, 160,   5,   0,   0,   3, 
-      0,   0,   4, 224,   0,   0, 
-      0, 128,   0,   0, 170, 128, 
-      4,   0,   0,   4,   0,   0, 
-      3, 224,   0,   0, 228, 144, 
-      9,   0, 238, 160,   9,   0, 
-    228, 160,   6,   0,   0,   2, 
-      0,   0,   1, 128,   1,   0, 
-    255, 128,   5,   0,   0,   3, 
-      1,   0,   7, 128,   0,   0, 
-      0, 128,   1,   0, 228, 128, 
-      2,   0,   0,   3,   0,   0, 
-     15, 128,   1,   0, 228, 128, 
-      8,   0, 228, 161,   5,   0, 
-      0,   3,   0,   0,   7, 128, 
-      0,   0, 255, 128,   0,   0, 
-    228, 128,   5,   0,   0,   3, 
-      1,   0,  15, 128,   0,   0, 
-     85, 128,   5,   0, 228, 160, 
-      4,   0,   0,   4,   1,   0, 
-     15, 128,   4,   0, 228, 160, 
-      0,   0,   0, 128,   1,   0, 
-    228, 128,   4,   0,   0,   4, 
-      1,   0,  15, 128,   6,   0, 
-    228, 160,   0,   0, 170, 128, 
-      1,   0, 228, 128,   4,   0, 
-      0,   4,   0,   0,  15, 128, 
-      7,   0, 228, 160,   0,   0, 
-    255, 128,   1,   0, 228, 128, 
-      4,   0,   0,   4,   0,   0, 
-      3, 192,   0,   0, 255, 128, 
-      0,   0, 228, 160,   0,   0, 
-    228, 128,   1,   0,   0,   2, 
-      0,   0,  12, 192,   0,   0, 
-    228, 128, 255, 255,   0,   0, 
-     83,  72,  68,  82, 100,   2, 
-      0,   0,  64,   0,   1,   0, 
-    153,   0,   0,   0,  89,   0, 
-      0,   4,  70, 142,  32,   0, 
-      0,   0,   0,   0,  12,   0, 
-      0,   0,  95,   0,   0,   3, 
-     50,  16,  16,   0,   0,   0, 
-      0,   0, 103,   0,   0,   4, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3,  50,  32, 
-     16,   0,   1,   0,   0,   0, 
-    101,   0,   0,   3, 194,  32, 
-     16,   0,   1,   0,   0,   0, 
-    104,   0,   0,   2,   2,   0, 
-      0,   0,  50,   0,   0,  11, 
-     50,   0,  16,   0,   0,   0, 
-      0,   0,  70,  16,  16,   0, 
-      0,   0,   0,   0, 230, 138, 
-     32,   0,   0,   0,   0,   0, 
-     10,   0,   0,   0,  70, 128, 
-     32,   0,   0,   0,   0,   0, 
-     10,   0,   0,   0,  56,   0, 
-      0,   8, 242,   0,  16,   0, 
-      1,   0,   0,   0,  86,   5, 
-     16,   0,   0,   0,   0,   0, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   1,   0,   0,   0, 
-     50,   0,   0,  10, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      6,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   8, 242,   0,  16,   0, 
-      0,   0,   0,   0,  70,  14, 
-     16,   0,   0,   0,   0,   0, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-     14,   0,   0,   7, 114,   0, 
-     16,   0,   1,   0,   0,   0, 
-     70,   2,  16,   0,   0,   0, 
-      0,   0, 246,  15,  16,   0, 
-      0,   0,   0,   0,  54,   0, 
-      0,   5, 130,   0,  16,   0, 
-      1,   0,   0,   0,  58,   0, 
-     16,   0,   0,   0,   0,   0, 
-      0,   0,   0,   9,  50,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,   0,  16,   0,   0,   0, 
-      0,   0,  70, 128,  32, 128, 
-     65,   0,   0,   0,   0,   0, 
-      0,   0,  11,   0,   0,   0, 
-     14,   0,   0,   8, 194,  32, 
-     16,   0,   1,   0,   0,   0, 
-      6,   4,  16,   0,   0,   0, 
-      0,   0, 166, 142,  32,   0, 
-      0,   0,   0,   0,  11,   0, 
-      0,   0,   0,   0,   0,   9, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      1,   0,   0,   0,  70, 142, 
-     32, 128,  65,   0,   0,   0, 
-      0,   0,   0,   0,   8,   0, 
-      0,   0,  56,   0,   0,   7, 
-    114,   0,  16,   0,   0,   0, 
-      0,   0, 246,  15,  16,   0, 
-      0,   0,   0,   0,  70,   2, 
-     16,   0,   0,   0,   0,   0, 
-     56,   0,   0,   8, 242,   0, 
-     16,   0,   1,   0,   0,   0, 
-     86,   5,  16,   0,   0,   0, 
-      0,   0,  70, 142,  32,   0, 
-      0,   0,   0,   0,   5,   0, 
-      0,   0,  50,   0,   0,  10, 
-    242,   0,  16,   0,   1,   0, 
-      0,   0,  70, 142,  32,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   6,   0,  16,   0, 
-      0,   0,   0,   0,  70,  14, 
-     16,   0,   1,   0,   0,   0, 
-     50,   0,   0,  10, 242,   0, 
-     16,   0,   1,   0,   0,   0, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-    166,  10,  16,   0,   0,   0, 
-      0,   0,  70,  14,  16,   0, 
-      1,   0,   0,   0,  50,   0, 
-      0,  10, 242,  32,  16,   0, 
-      0,   0,   0,   0,  70, 142, 
-     32,   0,   0,   0,   0,   0, 
-      7,   0,   0,   0, 246,  15, 
-     16,   0,   0,   0,   0,   0, 
-     70,  14,  16,   0,   1,   0, 
-      0,   0,  50,   0,   0,  11, 
-     50,  32,  16,   0,   1,   0, 
-      0,   0,  70,  16,  16,   0, 
-      0,   0,   0,   0, 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,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-      0,   0,   0,   0,   4,   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,   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, 104,   2, 
-      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,  52,   2,   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, 
-     10,   0,   0,   0,  96,   0, 
-      0,   0,  48,   1,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  80,   1,   0,   0, 
-      0,   0,   0,   0,  64,   0, 
-      0,   0,   2,   0,   0,   0, 
-     96,   1,   0,   0,   0,   0, 
-      0,   0, 112,   1,   0,   0, 
-     64,   0,   0,   0,  64,   0, 
-      0,   0,   2,   0,   0,   0, 
-     96,   1,   0,   0,   0,   0, 
-      0,   0, 124,   1,   0,   0, 
-    128,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    144,   1,   0,   0,   0,   0, 
-      0,   0, 160,   1,   0,   0, 
-    144,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    176,   1,   0,   0,   0,   0, 
-      0,   0, 192,   1,   0,   0, 
-    160,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    176,   1,   0,   0,   0,   0, 
-      0,   0, 203,   1,   0,   0, 
-    176,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    176,   1,   0,   0,   0,   0, 
-      0,   0, 213,   1,   0,   0, 
-    192,   0,   0,   0,  64,   0, 
-      0,   0,   0,   0,   0,   0, 
-     96,   1,   0,   0,   0,   0, 
-      0,   0, 232,   1,   0,   0, 
-      0,   1,   0,   0,  16,   0, 
-      0,   0,   0,   0,   0,   0, 
-    144,   1,   0,   0,   0,   0, 
-      0,   0, 244,   1,   0,   0, 
-     16,   1,   0,   0,   4,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   2,   0,   0,   0,   0, 
-      0,   0,  20,   2,   0,   0, 
-     32,   1,   0,   0,  16,   0, 
-      0,   0,   0,   0,   0,   0, 
-     36,   2,   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, 
-      1,   0,   3,   0,   1,   0, 
-      4,   0,   0,   0,   0,   0, 
-      0,   0,   0,   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, 109,  66,  97, 
-     99, 107, 100, 114, 111, 112, 
-     84, 114,  97, 110, 115, 102, 
-    111, 114, 109,   0, 102,  76, 
-     97, 121, 101, 114,  67, 111, 
-    108, 111, 114,   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, 
-    105,  66, 108, 101, 110, 100, 
-     67, 111, 110, 102, 105, 103, 
-      0, 171, 171, 171,   1,   0, 
-     19,   0,   1,   0,   4,   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,  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,  79,  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,  12, 
-      0,   0,  92,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,  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
-};
-ShaderBytes sLayerQuadMaskVS = { LayerQuadMaskVS, sizeof(LayerQuadMaskVS) };
-#if 0
-//
-// 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
-//   float4 vTextureCoords;             // Offset:  144 Size:    16
-//   float4 vLayerQuad;                 // Offset:  160 Size:    16
-//   float4 vMaskQuad;                  // Offset:  176 Size:    16
-//   float4x4 mBackdropTransform;       // Offset:  192 Size:    64 [unused]
-//   float4 fLayerColor;                // Offset:  256 Size:    16 [unused]
-//   float fLayerOpacity;               // Offset:  272 Size:     4 [unused]
-//   uint4 iBlendConfig;                // Offset:  288 Size:    16 [unused]
-//
-// }
-//
-//
-// Resource Bindings:
-//
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// $Globals                          cbuffer      NA          NA    0        1
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// $Globals                          cbuffer      NA          NA            cb0      1 
 //
 //
 //
 // Input signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // POSITION                 0   xy          0     NONE   float   xy  
@@ -2684,76 +2229,77 @@ ShaderBytes sLayerQuadMaskVS = { LayerQu
     def c12, 1, 0, 0, 0
     dcl_texcoord v0
     mov r0.z, c12.x
     rcp r0.w, c11.z
     mad r1.xy, v0, c10.zwzw, c10
     mul r2, r1.y, c2
     mad r1, c1, r1.x, r2
     add r1, r1, c3
-    rcp r2.x, r1.w
-    mad r2.yz, r1.xxyw, r2.x, -c11.xxyw
-    mul r1.xyz, r1, r2.x
-    mul r0.x, r0.w, r2.y
+    add r2.xy, r1, -c11
+    mul r0.x, r0.w, r2.x
     rcp r0.w, c11.w
-    mul r0.y, r0.w, r2.z
+    mul r0.y, r0.w, r2.y
     mul oT1.xyz, r0, r1.w
+    mad oT0.xy, v0, c9.zwzw, c9
+    rcp r0.x, r1.w
+    mul r1.xyz, r0.x, r1
     add r0, r1, -c8
-    mad oT0.xy, v0, c9.zwzw, c9
     mul r0.xyz, r0.w, r0
     mul r1, r0.y, c5
     mad r1, c4, r0.x, r1
     mad r1, c6, r0.z, r1
     mad r0, c7, r0.w, r1
     mad oPos.xy, r0.w, c0, r0
     mov oPos.zw, r0
 
 // approximately 22 instruction slots used
 vs_4_0
-dcl_constantbuffer cb0[12], immediateIndexed
+dcl_constantbuffer CB0[12], immediateIndexed
 dcl_input v0.xy
 dcl_output_siv o0.xyzw, position
 dcl_output o1.xy
 dcl_output o2.xyz
-dcl_temps 3
+dcl_temps 4
 mad r0.xy, v0.xyxx, cb0[10].zwzz, cb0[10].xyxx
 mul r1.xyzw, r0.yyyy, cb0[1].xyzw
 mad r0.xyzw, cb0[0].xyzw, r0.xxxx, r1.xyzw
 add r0.xyzw, r0.xyzw, cb0[3].xyzw
-div r0.xyz, r0.xyzx, r0.wwww
-add r1.xyzw, r0.xyzw, -cb0[8].xyzw
+div r1.xyz, r0.xyzx, r0.wwww
+mov r1.w, r0.w
+add r2.xyzw, r1.xyzw, -cb0[8].xyzw
+mul r1.xyz, r2.wwww, r2.xyzx
+mul r3.xyzw, r1.yyyy, cb0[5].xyzw
+mad r3.xyzw, cb0[4].xyzw, r1.xxxx, r3.xyzw
+mad r3.xyzw, cb0[6].xyzw, r1.zzzz, r3.xyzw
+mad o0.xyzw, cb0[7].xyzw, r2.wwww, r3.xyzw
+mad o1.xy, v0.xyxx, cb0[9].zwzz, cb0[9].xyxx
 add r0.xy, r0.xyxx, -cb0[11].xyxx
 div r0.xy, r0.xyxx, cb0[11].zwzz
-mul r1.xyz, r1.wwww, r1.xyzx
-mul r2.xyzw, r1.yyyy, cb0[5].xyzw
-mad r2.xyzw, cb0[4].xyzw, r1.xxxx, r2.xyzw
-mad r2.xyzw, cb0[6].xyzw, r1.zzzz, r2.xyzw
-mad o0.xyzw, cb0[7].xyzw, r1.wwww, r2.xyzw
-mad o1.xy, v0.xyxx, cb0[9].zwzz, cb0[9].xyxx
 mov r0.z, l(1.000000)
-mul o2.xyz, r0.wwww, r0.xyzx
+mul o2.xyz, r1.wwww, r0.xyzx
 ret 
-// Approximately 17 instruction slots used
+// Approximately 18 instruction slots used
 #endif
 
-const BYTE LayerQuadMask3DVS[] =
+const BYTE LayerQuadMaskVS[] =
 {
-     68,  88,  66,  67, 124,  99, 
-    104,  27,   0, 223, 159,   8, 
-    231,  86, 180, 224,  50, 178, 
-     27, 163,   1,   0,   0,   0, 
-     48,   8,   0,   0,   6,   0, 
+     68,  88,  66,  67, 170, 122, 
+    113,  58, 123,  23, 243, 241, 
+    143, 157, 226, 223, 154,  53, 
+    167, 168,   1,   0,   0,   0, 
+     64,   8,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
-     24,   2,   0,   0, 160,   4, 
-      0,   0,  28,   5,   0,   0, 
-    140,   7,   0,   0, 192,   7, 
+     20,   2,   0,   0, 176,   4, 
+      0,   0,  44,   5,   0,   0, 
+    156,   7,   0,   0, 208,   7, 
       0,   0,  65, 111, 110,  57, 
-    216,   1,   0,   0, 216,   1, 
+    212,   1,   0,   0, 212,   1, 
       0,   0,   0,   2, 254, 255, 
-    152,   1,   0,   0,  64,   0, 
+    148,   1,   0,   0,  64,   0, 
       0,   0,   2,   0,  36,   0, 
       0,   0,  60,   0,   0,   0, 
      60,   0,   0,   0,  36,   0, 
       1,   0,  60,   0,   0,   0, 
       0,   0,   2,   0,   1,   0, 
       0,   0,   0,   0,   0,   0, 
       3,   0,   9,   0,   3,   0, 
       0,   0,   0,   0,   0,   0, 
@@ -2775,327 +2321,329 @@ const BYTE LayerQuadMask3DVS[] =
       2,   0,  15, 128,   1,   0, 
      85, 128,   2,   0, 228, 160, 
       4,   0,   0,   4,   1,   0, 
      15, 128,   1,   0, 228, 160, 
       1,   0,   0, 128,   2,   0, 
     228, 128,   2,   0,   0,   3, 
       1,   0,  15, 128,   1,   0, 
     228, 128,   3,   0, 228, 160, 
-      6,   0,   0,   2,   2,   0, 
-      1, 128,   1,   0, 255, 128, 
-      4,   0,   0,   4,   2,   0, 
-      6, 128,   1,   0, 208, 128, 
-      2,   0,   0, 128,  11,   0, 
-    208, 161,   5,   0,   0,   3, 
-      1,   0,   7, 128,   1,   0, 
-    228, 128,   2,   0,   0, 128, 
-      5,   0,   0,   3,   0,   0, 
-      1, 128,   0,   0, 255, 128, 
-      2,   0,  85, 128,   6,   0, 
-      0,   2,   0,   0,   8, 128, 
-     11,   0, 255, 160,   5,   0, 
-      0,   3,   0,   0,   2, 128, 
+      2,   0,   0,   3,   2,   0, 
+      3, 128,   1,   0, 228, 128, 
+     11,   0, 228, 161,   5,   0, 
+      0,   3,   0,   0,   1, 128, 
       0,   0, 255, 128,   2,   0, 
-    170, 128,   5,   0,   0,   3, 
-      1,   0,   7, 224,   0,   0, 
-    228, 128,   1,   0, 255, 128, 
-      2,   0,   0,   3,   0,   0, 
-     15, 128,   1,   0, 228, 128, 
-      8,   0, 228, 161,   4,   0, 
+      0, 128,   6,   0,   0,   2, 
+      0,   0,   8, 128,  11,   0, 
+    255, 160,   5,   0,   0,   3, 
+      0,   0,   2, 128,   0,   0, 
+    255, 128,   2,   0,  85, 128, 
+      5,   0,   0,   3,   1,   0, 
+      7, 224,   0,   0, 228, 128, 
+      1,   0, 255, 128,   4,   0, 
       0,   4,   0,   0,   3, 224, 
       0,   0, 228, 144,   9,   0, 
     238, 160,   9,   0, 228, 160, 
-      5,   0,   0,   3,   0,   0, 
-      7, 128,   0,   0, 255, 128, 
-      0,   0, 228, 128,   5,   0, 
-      0,   3,   1,   0,  15, 128, 
-      0,   0,  85, 128,   5,   0, 
-    228, 160,   4,   0,   0,   4, 
-      1,   0,  15, 128,   4,   0, 
-    228, 160,   0,   0,   0, 128, 
-      1,   0, 228, 128,   4,   0, 
+      6,   0,   0,   2,   0,   0, 
+      1, 128,   1,   0, 255, 128, 
+      5,   0,   0,   3,   1,   0, 
+      7, 128,   0,   0,   0, 128, 
+      1,   0, 228, 128,   2,   0, 
+      0,   3,   0,   0,  15, 128, 
+      1,   0, 228, 128,   8,   0, 
+    228, 161,   5,   0,   0,   3, 
+      0,   0,   7, 128,   0,   0, 
+    255, 128,   0,   0, 228, 128, 
+      5,   0,   0,   3,   1,   0, 
+     15, 128,   0,   0,  85, 128, 
+      5,   0, 228, 160,   4,   0, 
       0,   4,   1,   0,  15, 128, 
-      6,   0, 228, 160,   0,   0, 
-    170, 128,   1,   0, 228, 128, 
-      4,   0,   0,   4,   0,   0, 
-     15, 128,   7,   0, 228, 160, 
-      0,   0, 255, 128,   1,   0, 
+      4,   0, 228, 160,   0,   0, 
+      0, 128,   1,   0, 228, 128, 
+      4,   0,   0,   4,   1,   0, 
+     15, 128,   6,   0, 228, 160, 
+      0,   0, 170, 128,   1,   0, 
     228, 128,   4,   0,   0,   4, 
-      0,   0,   3, 192,   0,   0, 
-    255, 128,   0,   0, 228, 160, 
-      0,   0, 228, 128,   1,   0, 
-      0,   2,   0,   0,  12, 192, 
-      0,   0, 228, 128, 255, 255, 
-      0,   0,  83,  72,  68,  82, 
-    128,   2,   0,   0,  64,   0, 
-      1,   0, 160,   0,   0,   0, 
-     89,   0,   0,   4,  70, 142, 
+      0,   0,  15, 128,   7,   0, 
+    228, 160,   0,   0, 255, 128, 
+      1,   0, 228, 128,   4,   0, 
+      0,   4,   0,   0,   3, 192, 
+      0,   0, 255, 128,   0,   0, 
+    228, 160,   0,   0, 228, 128, 
+      1,   0,   0,   2,   0,   0, 
+     12, 192,   0,   0, 228, 128, 
+    255, 255,   0,   0,  83,  72, 
+     68,  82, 148,   2,   0,   0, 
+     64,   0,   1,   0, 165,   0, 
+      0,   0,  89,   0,   0,   4, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,  12,   0,   0,   0, 
+     95,   0,   0,   3,  50,  16, 
+     16,   0,   0,   0,   0,   0, 
+    103,   0,   0,   4, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3,  50,  32,  16,   0, 
+      1,   0,   0,   0, 101,   0, 
+      0,   3, 114,  32,  16,   0, 
+      2,   0,   0,   0, 104,   0, 
+      0,   2,   4,   0,   0,   0, 
+     50,   0,   0,  11,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  16,  16,   0,   0,   0, 
+      0,   0, 230, 138,  32,   0, 
+      0,   0,   0,   0,  10,   0, 
+      0,   0,  70, 128,  32,   0, 
+      0,   0,   0,   0,  10,   0, 
+      0,   0,  56,   0,   0,   8, 
+    242,   0,  16,   0,   1,   0, 
+      0,   0,  86,   5,  16,   0, 
+      0,   0,   0,   0,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  50,   0, 
+      0,  10, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   6,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  14,  16,   0,   1,   0, 
+      0,   0,   0,   0,   0,   8, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,  14,  16,   0, 
+      0,   0,   0,   0,  70, 142, 
      32,   0,   0,   0,   0,   0, 
-     12,   0,   0,   0,  95,   0, 
-      0,   3,  50,  16,  16,   0, 
-      0,   0,   0,   0, 103,   0, 
-      0,   4, 242,  32,  16,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0, 101,   0,   0,   3, 
-     50,  32,  16,   0,   1,   0, 
-      0,   0, 101,   0,   0,   3, 
-    114,  32,  16,   0,   2,   0, 
-      0,   0, 104,   0,   0,   2, 
+      3,   0,   0,   0,  14,   0, 
+      0,   7, 114,   0,  16,   0, 
+      1,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+    246,  15,  16,   0,   0,   0, 
+      0,   0,  54,   0,   0,   5, 
+    130,   0,  16,   0,   1,   0, 
+      0,   0,  58,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   9, 242,   0,  16,   0, 
+      2,   0,   0,   0,  70,  14, 
+     16,   0,   1,   0,   0,   0, 
+     70, 142,  32, 128,  65,   0, 
+      0,   0,   0,   0,   0,   0, 
+      8,   0,   0,   0,  56,   0, 
+      0,   7, 114,   0,  16,   0, 
+      1,   0,   0,   0, 246,  15, 
+     16,   0,   2,   0,   0,   0, 
+     70,   2,  16,   0,   2,   0, 
+      0,   0,  56,   0,   0,   8, 
+    242,   0,  16,   0,   3,   0, 
+      0,   0,  86,   5,  16,   0, 
+      1,   0,   0,   0,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      5,   0,   0,   0,  50,   0, 
+      0,  10, 242,   0,  16,   0, 
+      3,   0,   0,   0,  70, 142, 
+     32,   0,   0,   0,   0,   0, 
+      4,   0,   0,   0,   6,   0, 
+     16,   0,   1,   0,   0,   0, 
+     70,  14,  16,   0,   3,   0, 
+      0,   0,  50,   0,   0,  10, 
+    242,   0,  16,   0,   3,   0, 
+      0,   0,  70, 142,  32,   0, 
+      0,   0,   0,   0,   6,   0, 
+      0,   0, 166,  10,  16,   0, 
+      1,   0,   0,   0,  70,  14, 
+     16,   0,   3,   0,   0,   0, 
+     50,   0,   0,  10, 242,  32, 
+     16,   0,   0,   0,   0,   0, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,   7,   0,   0,   0, 
+    246,  15,  16,   0,   2,   0, 
+      0,   0,  70,  14,  16,   0, 
       3,   0,   0,   0,  50,   0, 
-      0,  11,  50,   0,  16,   0, 
-      0,   0,   0,   0,  70,  16, 
+      0,  11,  50,  32,  16,   0, 
+      1,   0,   0,   0,  70,  16, 
      16,   0,   0,   0,   0,   0, 
     230, 138,  32,   0,   0,   0, 
-      0,   0,  10,   0,   0,   0, 
+      0,   0,   9,   0,   0,   0, 
      70, 128,  32,   0,   0,   0, 
-      0,   0,  10,   0,   0,   0, 
-     56,   0,   0,   8, 242,   0, 
-     16,   0,   1,   0,   0,   0, 
-     86,   5,  16,   0,   0,   0, 
-      0,   0,  70, 142,  32,   0, 
-      0,   0,   0,   0,   1,   0, 
-      0,   0,  50,   0,   0,  10, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0,  70, 142,  32,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   6,   0,  16,   0, 
-      0,   0,   0,   0,  70,  14, 
-     16,   0,   1,   0,   0,   0, 
-      0,   0,   0,   8, 242,   0, 
-     16,   0,   0,   0,   0,   0, 
-     70,  14,  16,   0,   0,   0, 
-      0,   0,  70, 142,  32,   0, 
-      0,   0,   0,   0,   3,   0, 
-      0,   0,  14,   0,   0,   7, 
-    114,   0,  16,   0,   0,   0, 
-      0,   0,  70,   2,  16,   0, 
-      0,   0,   0,   0, 246,  15, 
-     16,   0,   0,   0,   0,   0, 
-      0,   0,   0,   9, 242,   0, 
-     16,   0,   1,   0,   0,   0, 
-     70,  14,  16,   0,   0,   0, 
-      0,   0,  70, 142,  32, 128, 
-     65,   0,   0,   0,   0,   0, 
-      0,   0,   8,   0,   0,   0, 
+      0,   0,   9,   0,   0,   0, 
       0,   0,   0,   9,  50,   0, 
      16,   0,   0,   0,   0,   0, 
      70,   0,  16,   0,   0,   0, 
       0,   0,  70, 128,  32, 128, 
      65,   0,   0,   0,   0,   0, 
       0,   0,  11,   0,   0,   0, 
      14,   0,   0,   8,  50,   0, 
      16,   0,   0,   0,   0,   0, 
      70,   0,  16,   0,   0,   0, 
       0,   0, 230, 138,  32,   0, 
       0,   0,   0,   0,  11,   0, 
-      0,   0,  56,   0,   0,   7, 
-    114,   0,  16,   0,   1,   0, 
-      0,   0, 246,  15,  16,   0, 
-      1,   0,   0,   0,  70,   2, 
-     16,   0,   1,   0,   0,   0, 
-     56,   0,   0,   8, 242,   0, 
-     16,   0,   2,   0,   0,   0, 
-     86,   5,  16,   0,   1,   0, 
-      0,   0,  70, 142,  32,   0, 
-      0,   0,   0,   0,   5,   0, 
-      0,   0,  50,   0,   0,  10, 
-    242,   0,  16,   0,   2,   0, 
-      0,   0,  70, 142,  32,   0, 
-      0,   0,   0,   0,   4,   0, 
-      0,   0,   6,   0,  16,   0, 
-      1,   0,   0,   0,  70,  14, 
-     16,   0,   2,   0,   0,   0, 
-     50,   0,   0,  10, 242,   0, 
-     16,   0,   2,   0,   0,   0, 
-     70, 142,  32,   0,   0,   0, 
-      0,   0,   6,   0,   0,   0, 
-    166,  10,  16,   0,   1,   0, 
-      0,   0,  70,  14,  16,   0, 
-      2,   0,   0,   0,  50,   0, 
-      0,  10, 242,  32,  16,   0, 
-      0,   0,   0,   0,  70, 142, 
-     32,   0,   0,   0,   0,   0, 
-      7,   0,   0,   0, 246,  15, 
+      0,   0,  54,   0,   0,   5, 
+     66,   0,  16,   0,   0,   0, 
+      0,   0,   1,  64,   0,   0, 
+      0,   0, 128,  63,  56,   0, 
+      0,   7, 114,  32,  16,   0, 
+      2,   0,   0,   0, 246,  15, 
      16,   0,   1,   0,   0,   0, 
-     70,  14,  16,   0,   2,   0, 
-      0,   0,  50,   0,   0,  11, 
-     50,  32,  16,   0,   1,   0, 
-      0,   0,  70,  16,  16,   0, 
-      0,   0,   0,   0, 230, 138, 
-     32,   0,   0,   0,   0,   0, 
-      9,   0,   0,   0,  70, 128, 
-     32,   0,   0,   0,   0,   0, 
-      9,   0,   0,   0,  54,   0, 
-      0,   5,  66,   0,  16,   0, 
-      0,   0,   0,   0,   1,  64, 
-      0,   0,   0,   0, 128,  63, 
-     56,   0,   0,   7, 114,  32, 
-     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,  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,   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, 104,   2, 
-      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,  52,   2,   0,   0, 
-     60,   0,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   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,  18,   0,   0,   0, 
+      4,   0,   0,   0,   0,   0, 
+      0,   0,   4,   0,   0,   0, 
+     15,   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, 
-     10,   0,   0,   0,  96,   0, 
-      0,   0,  48,   1,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,  80,   1,   0,   0, 
-      0,   0,   0,   0,  64,   0, 
-      0,   0,   2,   0,   0,   0, 
-     96,   1,   0,   0,   0,   0, 
-      0,   0, 112,   1,   0,   0, 
-     64,   0,   0,   0,  64,   0, 
-      0,   0,   2,   0,   0,   0, 
-     96,   1,   0,   0,   0,   0, 
-      0,   0, 124,   1,   0,   0, 
-    128,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    144,   1,   0,   0,   0,   0, 
-      0,   0, 160,   1,   0,   0, 
-    144,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    176,   1,   0,   0,   0,   0, 
-      0,   0, 192,   1,   0,   0, 
-    160,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    176,   1,   0,   0,   0,   0, 
-      0,   0, 203,   1,   0,   0, 
-    176,   0,   0,   0,  16,   0, 
-      0,   0,   2,   0,   0,   0, 
-    176,   1,   0,   0,   0,   0, 
-      0,   0, 213,   1,   0,   0, 
-    192,   0,   0,   0,  64,   0, 
-      0,   0,   0,   0,   0,   0, 
-     96,   1,   0,   0,   0,   0, 
-      0,   0, 232,   1,   0,   0, 
-      0,   1,   0,   0,  16,   0, 
-      0,   0,   0,   0,   0,   0, 
-    144,   1,   0,   0,   0,   0, 
-      0,   0, 244,   1,   0,   0, 
-     16,   1,   0,   0,   4,   0, 
-      0,   0,   0,   0,   0,   0, 
-      4,   2,   0,   0,   0,   0, 
-      0,   0,  20,   2,   0,   0, 
-     32,   1,   0,   0,  16,   0, 
-      0,   0,   0,   0,   0,   0, 
-     36,   2,   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, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      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,  82,  68, 
+     69,  70, 104,   2,   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, 
+     52,   2,   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,  10,   0, 
+      0,   0,  96,   0,   0,   0, 
+     48,   1,   0,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     80,   1,   0,   0,   0,   0, 
+      0,   0,  64,   0,   0,   0, 
+      2,   0,   0,   0,  96,   1, 
+      0,   0,   0,   0,   0,   0, 
+    112,   1,   0,   0,  64,   0, 
+      0,   0,  64,   0,   0,   0, 
+      2,   0,   0,   0,  96,   1, 
+      0,   0,   0,   0,   0,   0, 
+    124,   1,   0,   0, 128,   0, 
+      0,   0,  16,   0,   0,   0, 
+      2,   0,   0,   0, 144,   1, 
+      0,   0,   0,   0,   0,   0, 
+    160,   1,   0,   0, 144,   0, 
+      0,   0,  16,   0,   0,   0, 
+      2,   0,   0,   0, 176,   1, 
+      0,   0,   0,   0,   0,   0, 
+    192,   1,   0,   0, 160,   0, 
+      0,   0,  16,   0,   0,   0, 
+      2,   0,   0,   0, 176,   1, 
+      0,   0,   0,   0,   0,   0, 
+    203,   1,   0,   0, 176,   0, 
+      0,   0,  16,   0,   0,   0, 
+      2,   0,   0,   0, 176,   1, 
+      0,   0,   0,   0,   0,   0, 
+    213,   1,   0,   0, 192,   0, 
+      0,   0,  64,   0,   0,   0, 
+      0,   0,   0,   0,  96,   1, 
+      0,   0,   0,   0,   0,   0, 
+    232,   1,   0,   0,   0,   1, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0, 144,   1, 
+      0,   0,   0,   0,   0,   0, 
+    244,   1,   0,   0,  16,   1, 
+      0,   0,   4,   0,   0,   0, 
+      0,   0,   0,   0,   4,   2, 
+      0,   0,   0,   0,   0,   0, 
+     20,   2,   0,   0,  32,   1, 
+      0,   0,  16,   0,   0,   0, 
+      0,   0,   0,   0,  36,   2, 
+      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,   1,   0, 
+      3,   0,   1,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   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,  84, 
-    101, 120, 116, 117, 114, 101, 
-     67, 111, 111, 114, 100, 115, 
-      0, 171,   1,   0,   3,   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, 109,  66,  97,  99, 107, 
+    100, 114, 111, 112,  84, 114, 
+     97, 110, 115, 102, 111, 114, 
+    109,   0, 102,  76,  97, 121, 
+    101, 114,  67, 111, 108, 111, 
+    114,   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, 105,  66, 
+    108, 101, 110, 100,  67, 111, 
+    110, 102, 105, 103,   0, 171, 
+    171, 171,   1,   0,  19,   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, 109,  66,  97, 
-     99, 107, 100, 114, 111, 112, 
-     84, 114,  97, 110, 115, 102, 
-    111, 114, 109,   0, 102,  76, 
-     97, 121, 101, 114,  67, 111, 
-    108, 111, 114,   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, 
-    105,  66, 108, 101, 110, 100, 
-     67, 111, 110, 102, 105, 103, 
-      0, 171, 171, 171,   1,   0, 
-     19,   0,   1,   0,   4,   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,  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,  79,  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, 
+     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,  49, 
+     48,  46,  48,  46,  49,  48, 
+     48,  49,  49,  46,  49,  54, 
+     51,  56,  52,   0,  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, 
-      1,   0,   0,   0,   3,  12, 
-      0,   0,  92,   0,   0,   0, 
-      1,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      2,   0,   0,   0,   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
+      0,   0,   0,   0,   3,   3, 
+      0,   0,  80,  79,  83,  73, 
+     84,  73,  79,  78,   0, 171, 
+    171, 171,  79,  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,  12,   0,   0, 
+     92,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      3,   0,   0,   0,   2,   0, 
+      0,   0,   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
 };
-ShaderBytes sLayerQuadMask3DVS = { LayerQuadMask3DVS, sizeof(LayerQuadMask3DVS) };
+ShaderBytes sLayerQuadMaskVS = { LayerQuadMaskVS, sizeof(LayerQuadMaskVS) };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16
@@ -3109,31 +2657,31 @@ ShaderBytes sLayerQuadMask3DVS = { Layer
 //   float4 vMaskQuad;                  // Offset:  224 Size:    16 [unused]
 //   float4x4 mBackdropTransform;       // Offset:  240 Size:    64 [unused]
 //
 // }
 //
 //
 // Resource Bindings:
 //
-// Name                                 Type  Format         Dim Slot Elements
-// ------------------------------ ---------- ------- ----------- ---- --------
-// sSampler                          sampler      NA          NA    0        1
-// tMask                             texture  float4          2d    5        1
-// $Globals                          cbuffer      NA          NA    0        1
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// sSampler                          sampler      NA          NA             s0      1 
+// tMask                             texture  float4          2d             t5      1 
+// $Globals                          cbuffer      NA          NA            cb0      1 
 //
 //
 //
 // Input signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // SV_Position              0   xyzw        0      POS   float       
 // TEXCOORD                 0   xy          1     NONE   float       
-// TEXCOORD                 1     zw        1     NONE   float     zw
+// TEXCOORD                 1   xyz         2     NONE   float   xyz 
 //
 //
 // Output signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // SV_Target                0   xyzw        0   TARGET   float   xyzw
 //
@@ -3150,270 +2698,280 @@ ShaderBytes sLayerQuadMask3DVS = { Layer
 // Target Sampler Source Sampler  Source Resource
 // -------------- --------------- ----------------
 // s0             s0              t5               
 //
 //
 // Level9 shader bytecode:
 //
     ps_2_x
-    dcl t0
+    dcl t1.xyz
     dcl_2d s0
-    mov r0.xy, t0.wzzw
+    rcp r0.w, t1.z
+    mul r0.xy, r0.w, t1
     texld r0, r0, s0
     mul r0, r0.x, c0
     mov oC0, r0
 
-// approximately 4 instruction slots used (1 texture, 3 arithmetic)
+// approximately 5 instruction slots used (1 texture, 4 arithmetic)
 ps_4_0
-dcl_constantbuffer cb0[1], immediateIndexed
+dcl_constantbuffer CB0[1], immediateIndexed
 dcl_sampler s0, mode_default
 dcl_resource_texture2d (float,float,float,float) t5
-dcl_input_ps linear v1.zw
+dcl_input_ps linear v2.xyz
 dcl_output o0.xyzw
 dcl_temps 1
-sample r0.xyzw, v1.zwzz, t5.xyzw, s0
+div r0.xy, v2.xyxx, v2.zzzz
+sample r0.xyzw, r0.xyxx, t5.xyzw, s0
 mul o0.xyzw, r0.xxxx, cb0[0].xyzw
 ret 
-// Approximately 3 instruction slots used
+// Approximately 4 instruction slots used
 #endif
 
 const BYTE SolidColorShaderMask[] =
 {
-     68,  88,  66,  67, 179, 163, 
-    177, 178,  96,   7, 246,  20, 
-     94, 198, 166,  18, 116, 245, 
-    163,  94,   1,   0,   0,   0, 
-     76,   5,   0,   0,   6,   0, 
+     68,  88,  66,  67, 136,  34, 
+    160,  50,  38, 225, 198,  78, 
+    252,  58, 191, 192, 204,  38, 
+     60, 224,   1,   0,   0,   0, 
+    120,   5,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
-    204,   0,   0,   0, 112,   1, 
-      0,   0, 236,   1,   0,   0, 
-    168,   4,   0,   0,  24,   5, 
+    220,   0,   0,   0, 156,   1, 
+      0,   0,  24,   2,   0,   0, 
+    212,   4,   0,   0,  68,   5, 
       0,   0,  65, 111, 110,  57, 
-    140,   0,   0,   0, 140,   0, 
+    156,   0,   0,   0, 156,   0, 
       0,   0,   0,   2, 255, 255, 
-     88,   0,   0,   0,  52,   0, 
+    104,   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,   5,   0, 
       0,   0,   0,   0,   0,   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, 
+      0, 128,   1,   0,   7, 176, 
      31,   0,   0,   2,   0,   0, 
       0, 144,   0,   8,  15, 160, 
-      1,   0,   0,   2,   0,   0, 
-      3, 128,   0,   0, 235, 176, 
-     66,   0,   0,   3,   0,   0, 
-     15, 128,   0,   0, 228, 128, 
-      0,   8, 228, 160,   5,   0, 
+      6,   0,   0,   2,   0,   0, 
+      8, 128,   1,   0, 170, 176, 
+      5,   0,   0,   3,   0,   0, 
+      3, 128,   0,   0, 255, 128, 
+      1,   0, 228, 176,  66,   0, 
       0,   3,   0,   0,  15, 128, 
-      0,   0,   0, 128,   0,   0, 
-    228, 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, 228, 128,   0,   8, 
+    228, 160,   5,   0,   0,   3, 
+      0,   0,  15, 128,   0,   0, 
+      0, 128,   0,   0, 228, 160, 
+      1,   0,   0,   2,   0,   8, 
+     15, 128,   0,   0, 228, 128, 
+    255, 255,   0,   0,  83,  72, 
+     68,  82, 184,   0,   0,   0, 
+     64,   0,   0,   0,  46,   0, 
+      0,   0,  89,   0,   0,   4, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     90,   0,   0,   3,   0,  96, 
+     16,   0,   0,   0,   0,   0, 
+     88,  24,   0,   4,   0, 112, 
+     16,   0,   5,   0,   0,   0, 
+     85,  85,   0,   0,  98,  16, 
+      0,   3, 114,  16,  16,   0, 
+      2,   0,   0,   0, 101,   0, 
+      0,   3, 242,  32,  16,   0, 
+      0,   0,   0,   0, 104,   0, 
+      0,   2,   1,   0,   0,   0, 
+     14,   0,   0,   7,  50,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  16,  16,   0,   2,   0, 
+      0,   0, 166,  26,  16,   0, 
+      2,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      0,   0,   0,   0,  70,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70, 126,  16,   0,   5,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  56,   0, 
+      0,   8, 242,  32,  16,   0, 
+      0,   0,   0,   0,   6,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70, 142,  32,   0,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+     62,   0,   0,   1,  83,  84, 
+     65,  84, 116,   0,   0,   0, 
+      4,   0,   0,   0,   1,   0, 
+      0,   0,   0,   0,   0,   0, 
+      2,   0,   0,   0,   2,   0, 
+      0,   0,   0,   0,   0,   0, 
       0,   0,   0,   0,   1,   0, 
-      0,   0,  90,   0,   0,   3, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  88,  24,   0,   4, 
-      0, 112,  16,   0,   5,   0, 
-      0,   0,  85,  85,   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,   1,   0, 
-      0,   0,  69,   0,   0,   9, 
-    242,   0,  16,   0,   0,   0, 
-      0,   0, 230,  26,  16,   0, 
-      1,   0,   0,   0,  70, 126, 
-     16,   0,   5,   0,   0,   0, 
-      0,  96,  16,   0,   0,   0, 
-      0,   0,  56,   0,   0,   8, 
-    242,  32,  16,   0,   0,   0, 
-      0,   0,   6,   0,  16,   0, 
-      0,   0,   0,   0,  70, 142, 
-     32,   0,   0,   0,   0,   0, 
-      0,   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,   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, 
+    180,   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, 128,   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, 
+      5,   0,   0,   0,   1,   0, 
+      0,   0,  13,   0,   0,   0, 
+    139,   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, 180,   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, 128,   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,   5,   0, 
-      0,   0,   1,   0,   0,   0, 
-     13,   0,   0,   0, 139,   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,  77,  97, 
-    115, 107,   0,  36,  71, 108, 
-    111,  98,  97, 108, 115,   0, 
-    139,   0,   0,   0,  10,   0, 
-      0,   0, 172,   0,   0,   0, 
-     48,   1,   0,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-    156,   1,   0,   0,   0,   0, 
-      0,   0,  16,   0,   0,   0, 
-      2,   0,   0,   0, 168,   1, 
-      0,   0,   0,   0,   0,   0, 
-    184,   1,   0,   0,  16,   0, 
-      0,   0,   4,   0,   0,   0, 
-      0,   0,   0,   0, 200,   1, 
-      0,   0,   0,   0,   0,   0, 
-    216,   1,   0,   0,  32,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0, 232,   1, 
-      0,   0,   0,   0,   0,   0, 
-    248,   1,   0,   0,  48,   0, 
-      0,   0,  64,   0,   0,   0, 
-      0,   0,   0,   0,   8,   2, 
-      0,   0,   0,   0,   0,   0, 
-     24,   2,   0,   0, 112,   0, 
-      0,   0,  64,   0,   0,   0, 
-      0,   0,   0,   0,   8,   2, 
-      0,   0,   0,   0,   0,   0, 
-     36,   2,   0,   0, 176,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0, 168,   1, 
-      0,   0,   0,   0,   0,   0, 
-     56,   2,   0,   0, 192,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,  72,   2, 
-      0,   0,   0,   0,   0,   0, 
-     88,   2,   0,   0, 208,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,  72,   2, 
-      0,   0,   0,   0,   0,   0, 
-     99,   2,   0,   0, 224,   0, 
-      0,   0,  16,   0,   0,   0, 
-      0,   0,   0,   0,  72,   2, 
-      0,   0,   0,   0,   0,   0, 
-    109,   2,   0,   0, 240,   0, 
-      0,   0,  64,   0,   0,   0, 
-      0,   0,   0,   0,   8,   2, 
+      0,   0, 115,  83,  97, 109, 
+    112, 108, 101, 114,   0, 116, 
+     77,  97, 115, 107,   0,  36, 
+     71, 108, 111,  98,  97, 108, 
+    115,   0, 139,   0,   0,   0, 
+     10,   0,   0,   0, 172,   0, 
+      0,   0,  48,   1,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 156,   1,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   0,   2,   0,   0,   0, 
+    168,   1,   0,   0,   0,   0, 
+      0,   0, 184,   1,   0,   0, 
+     16,   0,   0,   0,   4,   0, 
+      0,   0,   0,   0,   0,   0, 
+    200,   1,   0,   0,   0,   0, 
+      0,   0, 216,   1,   0,   0, 
+     32,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    232,   1,   0,   0,   0,   0, 
+      0,   0, 248,   1,   0,   0, 
+     48,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+      8,   2,   0,   0,   0,   0, 
+      0,   0,  24,   2,   0,   0, 
+    112,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+      8,   2,   0,   0,   0,   0, 
+      0,   0,  36,   2,   0,   0, 
+    176,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    168,   1,   0,   0,   0,   0, 
+      0,   0,  56,   2,   0,   0, 
+    192,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+     72,   2,   0,   0,   0,   0, 
+      0,   0,  88,   2,   0,   0, 
+    208,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+     72,   2,   0,   0,   0,   0, 
+      0,   0,  99,   2,   0,   0, 
+    224,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+     72,   2,   0,   0,   0,   0, 
+      0,   0, 109,   2,   0,   0, 
+    240,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+      8,   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, 
-     67, 111, 108, 111, 114,   0, 
+     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, 105,  66, 108, 101, 
+    110, 100,  67, 111, 110, 102, 
+    105, 103,   0, 171, 171, 171, 
+      1,   0,  19,   0,   1,   0, 
+      4,   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, 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, 
-    105,  66, 108, 101, 110, 100, 
-     67, 111, 110, 102, 105, 103, 
-      0, 171, 171, 171,   1,   0, 
-     19,   0,   1,   0,   4,   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, 109, 
-     66,  97,  99, 107, 100, 114, 
-    111, 112,  84, 114,  97, 110, 
-    115, 102, 111, 114, 109,   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, 104,   0,   0,   0, 
-      3,   0,   0,   0,   8,   0, 
-      0,   0,  80,   0,   0,   0, 
-      0,   0,   0,   0,   1,   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, 109,  66,  97,  99, 107, 
+    100, 114, 111, 112,  84, 114, 
+     97, 110, 115, 102, 111, 114, 
+    109,   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,  49,  48,  46,  48,  46, 
+     49,  48,  48,  49,  49,  46, 
+     49,  54,  51,  56,  52,   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,   0,   0,   0,  92,   0, 
+      0,   0,   1,   0,   0,   0, 
+      0,   0,   0,   0,   3,   0, 
+      0,   0,   2,   0,   0,   0, 
+      7,   7,   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,  92,   0,   0,   0, 
-      0,   0,   0,   0,   0,   0, 
-      0,   0,   3,   0,   0,   0, 
-      1,   0,   0,   0,   3,   0, 
-      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
+      0,   0,  83,  86,  95,  84, 
+     97, 114, 103, 101, 116,   0, 
+    171, 171
 };
 ShaderBytes sSolidColorShaderMask = { SolidColorShaderMask, sizeof(SolidColorShaderMask) };
 #if 0
 //
-// Generated by Microsoft (R) HLSL Shader Compiler 6.3.9600.16384
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
 //
 //
 // Buffer Definitions: 
 //
 // cbuffer $Globals
 // {
 //
 //   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
@@ -3427,32 +2985,410 @@ ShaderBytes sSolidColorShaderMask = { So
 //   float4 vMaskQuad;                  // Offset:  224 Size:    16 [unused]
 //   float4x4 mBackdropTransform;       // Offset:  240 Size:    64 [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    5        1
-// $Globals                          cbuffer      NA          NA    0        1
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// sSampler                          sampler      NA          NA             s0      1 
+// tRGB                              texture  float4          2d             t0      1 
+// tMask                             texture  float4          2d             t5      1 
+// $Globals                          cbuffer      NA          NA            cb0      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
+// TEXCOORD                 1   xyz         2     NONE   float   xyz 
+//
+//
+// 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               
+// s1             s0              t5               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    dcl t0.xy
+    dcl t1.xyz
+    dcl_2d s0
+    dcl_2d s1
+    rcp r0.w, t1.z
+    mul r0.xy, r0.w, t1
+    texld r1, t0, s0
+    texld r0, r0, s1
+    mul r1.xyz, r1, c0.x
+    mov r1.w, c0.x
+    mul r0, r0.x, r1
+    mov oC0, r0
+
+// approximately 8 instruction slots used (2 texture, 6 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) t5
+dcl_input_ps linear v1.xy
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 2
+sample r0.xyzw, v1.xyxx, t0.xyzw, s0
+mul r0.xyz, r0.xyzx, cb0[1].xxxx
+div r1.xy, v2.xyxx, v2.zzzz
+sample r1.xyzw, r1.xyxx, t5.xyzw, s0
+mov r0.w, cb0[1].x
+mul o0.xyzw, r0.xyzw, r1.xxxx
+ret 
+// Approximately 7 instruction slots used
+#endif
+
+const BYTE RGBShaderMask[] =
+{
+     68,  88,  66,  67,  79, 247, 
+    118, 147, 119, 222,  85,  19, 
+    212, 225, 110,  66, 228, 229, 
+    204, 201,   1,   0,   0,   0, 
+     92,   6,   0,   0,   6,   0, 
+      0,   0,  56,   0,   0,   0, 
+     36,   1,   0,   0,  88,   2, 
+      0,   0, 212,   2,   0,   0, 
+    184,   5,   0,   0,  40,   6, 
+      0,   0,  65, 111, 110,  57, 
+    228,   0,   0,   0, 228,   0, 
+      0,   0,   0,   2, 255, 255, 
+    172,   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,   0,   0, 
+      0,   0,   5,   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,   3, 176,  31,   0, 
+      0,   2,   0,   0,   0, 128, 
+      1,   0,   7, 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,   6,   0, 
+      0,   2,   0,   0,   8, 128, 
+      1,   0, 170, 176,   5,   0, 
+      0,   3,   0,   0,   3, 128, 
+      0,   0, 255, 128,   1,   0, 
+    228, 176,  66,   0,   0,   3, 
+      1,   0,  15, 128,   0,   0, 
+    228, 176,   0,   8, 228, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 128, 
+      1,   8, 228, 160,   5,   0, 
+      0,   3,   1,   0,   7, 128, 
+      1,   0, 228, 128,   0,   0, 
+      0, 160,   1,   0,   0,   2, 
+      1,   0,   8, 128,   0,   0, 
+      0, 160,   5,   0,   0,   3, 
+      0,   0,  15, 128,   0,   0, 
+      0, 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,  44,   1,   0,   0, 
+     64,   0,   0,   0,  75,   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, 
+      5,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0,  98,  16,   0,   3, 
+    114,  16,  16,   0,   2,   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, 114,   0,  16,   0, 
+      0,   0,   0,   0,  70,   2, 
+     16,   0,   0,   0,   0,   0, 
+      6, 128,  32,   0,   0,   0, 
+      0,   0,   1,   0,   0,   0, 
+     14,   0,   0,   7,  50,   0, 
+     16,   0,   1,   0,   0,   0, 
+     70,  16,  16,   0,   2,   0, 
+      0,   0, 166,  26,  16,   0, 
+      2,   0,   0,   0,  69,   0, 
+      0,   9, 242,   0,  16,   0, 
+      1,   0,   0,   0,  70,   0, 
+     16,   0,   1,   0,   0,   0, 
+     70, 126,  16,   0,   5,   0, 
+      0,   0,   0,  96,  16,   0, 
+      0,   0,   0,   0,  54,   0, 
+      0,   6, 130,   0,  16,   0, 
+      0,   0,   0,   0,  10, 128, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  56,   0, 
+      0,   7, 242,  32,  16,   0, 
+      0,   0,   0,   0,  70,  14, 
+     16,   0,   0,   0,   0,   0, 
+      6,   0,  16,   0,   1,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   7,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   3,   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,   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, 220,   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, 
+    168,   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,  13,   0, 
+      0,   0, 170,   0,   0,   0, 
+      2,   0,   0,   0,   5,   0, 
+      0,   0,   4,   0,   0,   0, 
+    255, 255, 255, 255,   5,   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, 
+     10,   0,   0,   0, 212,   0, 
+      0,   0,  48,   1,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 196,   1,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    208,   1,   0,   0,   0,   0, 
+      0,   0, 224,   1,   0,   0, 
+     16,   0,   0,   0,   4,   0, 
+      0,   0,   2,   0,   0,   0, 
+    240,   1,   0,   0,   0,   0, 
+      0,   0,   0,   2,   0,   0, 
+     32,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+     16,   2,   0,   0,   0,   0, 
+      0,   0,  32,   2,   0,   0, 
+     48,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+     48,   2,   0,   0,   0,   0, 
+      0,   0,  64,   2,   0,   0, 
+    112,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+     48,   2,   0,   0,   0,   0, 
+      0,   0,  76,   2,   0,   0, 
+    176,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    208,   1,   0,   0,   0,   0, 
+      0,   0,  96,   2,   0,   0, 
+    192,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    112,   2,   0,   0,   0,   0, 
+      0,   0, 128,   2,   0,   0, 
+    208,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    112,   2,   0,   0,   0,   0, 
+      0,   0, 139,   2,   0,   0, 
+    224,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    112,   2,   0,   0,   0,   0, 
+      0,   0, 149,   2,   0,   0, 
+    240,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+     48,   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, 105,  66, 108, 101, 
+    110, 100,  67, 111, 110, 102, 
+    105, 103,   0, 171, 171, 171, 
+      1,   0,  19,   0,   1,   0, 
+      4,   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, 109,  66,  97,  99, 107, 
+    100, 114, 111, 112,  84, 114, 
+     97, 110, 115, 102, 111, 114, 
+    109,   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,  49,  48,  46,  48,  46, 
+     49,  48,  48,  49,  49,  46, 
+     49,  54,  51,  56,  52,   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,   2,   0,   0,   0, 
+      7,   7,   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
+};
+ShaderBytes sRGBShaderMask = { RGBShaderMask, sizeof(RGBShaderMask) };
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer $Globals
+// {
+//
+//   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
+//   float fLayerOpacity;               // Offset:   16 Size:     4
+//   uint4 iBlendConfig;                // Offset:   32 Size:    16 [unused]
+//   float4x4 mLayerTransform;          // Offset:   48 Size:    64 [unused]
+//   float4x4 mProjection;              // Offset:  112 Size:    64 [unused]
+//   float4 vRenderTargetOffset;        // Offset:  176 Size:    16 [unused]
+//   float4 vTextureCoords;             // Offset:  192 Size:    16 [unused]
+//   float4 vLayerQuad;                 // Offset:  208 Size:    16 [unused]
+//   float4 vMaskQuad;                  // Offset:  224 Size:    16 [unused]
+//   float4x4 mBackdropTransform;       // Offset:  240 Size:    64 [unused]
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// sSampler                          sampler      NA          NA             s0      1 
+// tRGB                              texture  float4          2d             t0      1 
+// tMask                             texture  float4          2d             t5      1 
+// $Globals                          cbuffer      NA          NA            cb0      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   xyz         2     NONE   float   xyz 
 //
 //
 // Output signature:
 //
 // Name                 Index   Mask Register SysValue  Format   Used
 // -------------------- ----- ------ -------- -------- ------- ------
 // SV_Target                0   xyzw        0   TARGET   float   xyzw
 //
@@ -3470,235 +3406,1220 @@ ShaderBytes sSolidColorShaderMask = { So
 // -------------- --------------- ----------------
 // s0             s0              t0               
 // s1             s0              t5               
 //
 //
 // Level9 shader bytecode:
 //
     ps_2_x
-    dcl t0
+    dcl t0.xy
+    dcl t1.xyz
     dcl_2d s0
     dcl_2d s1
-    mov r0.xy, t0.wzzw
+    rcp r0.w, t1.z
+    mul r0.xy, r0.w, t1
     texld r1, t0, s0
     texld r0, r0, s1
-    mul r1.xyz, r1, c0.x
-    mov r1.w, c0.x
+    mul r1, r1, c0.x
     mul r0, r0.x, r1
     mov oC0, r0
 
 // approximately 7 instruction slots used (2 texture, 5 arithmetic)
 ps_4_0
-dcl_constantbuffer cb0[2], immediateIndexed
+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) t5
 dcl_input_ps linear v1.xy
-dcl_input_ps linear v1.zw
+dcl_input_ps linear v2.xyz
 dcl_output o0.xyzw
 dcl_temps 2
-sample r0.xyzw, v1.xyxx, t0.xyzw, s0
-mul r0.xyz, r0.xyzx, cb0[1].xxxx
-sample r1.xyzw, v1.zwzz, t5.xyzw, s0
-mov r0.w, cb0[1].x
-mul o0.xyzw, r0.xyzw, r1.xxxx
+div r0.xy, v2.xyxx, v2.zzzz
+sample r0.xyzw, r0.xyxx, t5.xyzw, s0
+sample r1.xyzw, v1.xyxx, t0.xyzw, s0
+mul r1.xyzw, r1.xyzw, cb0[1].xxxx
+mul o0.xyzw, r0.xxxx, r1.xyzw
 ret 
 // Approximately 6 instruction slots used
 #endif
 
-const BYTE RGBShaderMask[] =
+const BYTE RGBAShaderMask[] =
 {
-     68,  88,  66,  67, 194, 201, 
-     10, 158,  40, 223, 107,  77, 
-    239,  65, 209,  32,   8, 192, 
-    127, 244,   1,   0,   0,   0, 
-     36,   6,   0,   0,   6,   0, 
+     68,  88,  66,  67, 100,  50, 
+    112, 237, 158, 118, 201, 119, 
+    153, 231, 223, 176, 232, 201, 
+    145, 152,   1,   0,   0,   0, 
+     56,   6,   0,   0,   6,   0, 
       0,   0,  56,   0,   0,   0, 
-      8,   1,   0,   0,  32,   2, 
-      0,   0, 156,   2,   0,   0, 
-    128,   5,   0,   0, 240,   5, 
+     24,   1,   0,   0,  52,   2, 
+      0,   0, 176,   2,   0,   0, 
+    148,   5,   0,   0,   4,   6, 
       0,   0,  65, 111, 110,  57, 
-    200,   0,   0,   0, 200,   0, 
+    216,   0,   0,   0, 216,   0, 
       0,   0,   0,   2, 255, 255, 
-    144,   0,   0,   0,  56,   0, 
+    160,   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,   0,   0, 
       0,   0,   5,   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,   0,   3, 176,  31,   0, 
+      0,   2,   0,   0,   0, 128, 
+      1,   0,   7, 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, 
+      1,   8,  15, 160,   6,   0, 
+      0,   2,   0,   0,   8, 128, 
+      1,   0, 170, 176,   5,   0, 
+      0,   3,   0,   0,   3, 128, 
+      0,   0, 255, 128,   1,   0, 
+    228, 176,  66,   0,   0,   3, 
+      1,   0,  15, 128,   0,   0, 
+    228, 176,   0,   8, 228, 160, 
+     66,   0,   0,   3,   0,   0, 
+     15, 128,   0,   0, 228, 128, 
+      1,   8, 228, 160,   5,   0, 
       0,   3,   1,   0,  15, 128, 
-      0,   0, 228, 176,   0,   8, 
+      1,   0, 228, 128,   0,   0, 
+      0, 160,   5,   0,   0,   3, 
+      0,   0,  15, 128,   0,   0, 
+      0, 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,  20,   1,   0,   0, 
+     64,   0,   0,   0,  69,   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, 
+      5,   0,   0,   0,  85,  85, 
+      0,   0,  98,  16,   0,   3, 
+     50,  16,  16,   0,   1,   0, 
+      0,   0,  98,  16,   0,   3, 
+    114,  16,  16,   0,   2,   0, 
+      0,   0, 101,   0,   0,   3, 
+    242,  32,  16,   0,   0,   0, 
+      0,   0, 104,   0,   0,   2, 
+      2,   0,   0,   0,  14,   0, 
+      0,   7,  50,   0,  16,   0, 
+      0,   0,   0,   0,  70,  16, 
+     16,   0,   2,   0,   0,   0, 
+    166,  26,  16,   0,   2,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   0,   0, 
+      0,   0,  70,   0,  16,   0, 
+      0,   0,   0,   0,  70, 126, 
+     16,   0,   5,   0,   0,   0, 
+      0,  96,  16,   0,   0,   0, 
+      0,   0,  69,   0,   0,   9, 
+    242,   0,  16,   0,   1,   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,   1,   0, 
+      0,   0,  70,  14,  16,   0, 
+      1,   0,   0,   0,   6, 128, 
+     32,   0,   0,   0,   0,   0, 
+      1,   0,   0,   0,  56,   0, 
+      0,   7, 242,  32,  16,   0, 
+      0,   0,   0,   0,   6,   0, 
+     16,   0,   0,   0,   0,   0, 
+     70,  14,  16,   0,   1,   0, 
+      0,   0,  62,   0,   0,   1, 
+     83,  84,  65,  84, 116,   0, 
+      0,   0,   6,   0,   0,   0, 
+      2,   0,   0,   0,   0,   0, 
+      0,   0,   3,   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,   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, 220,   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, 
+    168,   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,  13,   0, 
+      0,   0, 170,   0,   0,   0, 
+      2,   0,   0,   0,   5,   0, 
+      0,   0,   4,   0,   0,   0, 
+    255, 255, 255, 255,   5,   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, 
+     10,   0,   0,   0, 212,   0, 
+      0,   0,  48,   1,   0,   0, 
+      0,   0,   0,   0,   0,   0, 
+      0,   0, 196,   1,   0,   0, 
+      0,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    208,   1,   0,   0,   0,   0, 
+      0,   0, 224,   1,   0,   0, 
+     16,   0,   0,   0,   4,   0, 
+      0,   0,   2,   0,   0,   0, 
+    240,   1,   0,   0,   0,   0, 
+      0,   0,   0,   2,   0,   0, 
+     32,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+     16,   2,   0,   0,   0,   0, 
+      0,   0,  32,   2,   0,   0, 
+     48,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+     48,   2,   0,   0,   0,   0, 
+      0,   0,  64,   2,   0,   0, 
+    112,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+     48,   2,   0,   0,   0,   0, 
+      0,   0,  76,   2,   0,   0, 
+    176,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    208,   1,   0,   0,   0,   0, 
+      0,   0,  96,   2,   0,   0, 
+    192,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    112,   2,   0,   0,   0,   0, 
+      0,   0, 128,   2,   0,   0, 
+    208,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    112,   2,   0,   0,   0,   0, 
+      0,   0, 139,   2,   0,   0, 
+    224,   0,   0,   0,  16,   0, 
+      0,   0,   0,   0,   0,   0, 
+    112,   2,   0,   0,   0,   0, 
+      0,   0, 149,   2,   0,   0, 
+    240,   0,   0,   0,  64,   0, 
+      0,   0,   0,   0,   0,   0, 
+     48,   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, 105,  66, 108, 101, 
+    110, 100,  67, 111, 110, 102, 
+    105, 103,   0, 171, 171, 171, 
+      1,   0,  19,   0,   1,   0, 
+      4,   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, 109,  66,  97,  99, 107, 
+    100, 114, 111, 112,  84, 114, 
+     97, 110, 115, 102, 111, 114, 
+    109,   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,  49,  48,  46,  48,  46, 
+     49,  48,  48,  49,  49,  46, 
+     49,  54,  51,  56,  52,   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,   2,   0,   0,   0, 
+      7,   7,   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
+};
+ShaderBytes sRGBAShaderMask = { RGBAShaderMask, sizeof(RGBAShaderMask) };
+#if 0
+//
+// Generated by Microsoft (R) HLSL Shader Compiler 10.0.10011.16384
+//
+//
+// Buffer Definitions: 
+//
+// cbuffer $Globals
+// {
+//
+//   float4 fLayerColor;                // Offset:    0 Size:    16 [unused]
+//   float fLayerOpacity;               // Offset:   16 Size:     4
+//   uint4 iBlendConfig;                // Offset:   32 Size:    16 [unused]
+//   float4x4 mLayerTransform;          // Offset:   48 Size:    64 [unused]
+//   float4x4 mProjection;              // Offset:  112 Size:    64 [unused]
+//   float4 vRenderTargetOffset;        // Offset:  176 Size:    16 [unused]
+//   float4 vTextureCoords;             // Offset:  192 Size:    16 [unused]
+//   float4 vLayerQuad;                 // Offset:  208 Size:    16 [unused]
+//   float4 vMaskQuad;                  // Offset:  224 Size:    16 [unused]
+//   float4x4 mBackdropTransform;       // Offset:  240 Size:    64 [unused]
+//
+// }
+//
+//
+// Resource Bindings:
+//
+// Name                                 Type  Format         Dim      HLSL Bind  Count
+// ------------------------------ ---------- ------- ----------- -------------- ------
+// sSampler                          sampler      NA          NA             s0      1 
+// tY                                texture  float4          2d             t1      1 
+// tCb                               texture  float4          2d             t2      1 
+// tCr                               texture  float4          2d             t3      1 
+// tMask                             texture  float4          2d             t5      1 
+// $Globals                          cbuffer      NA          NA            cb0      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   xyz         2     NONE   float   xyz 
+//
+//
+// 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              t1               
+// s1             s0              t2               
+// s2             s0              t3               
+// s3             s0              t5               
+//
+//
+// Level9 shader bytecode:
+//
+    ps_2_x
+    def c1, -0.50195998, -0.0627499968, 1.59603, 0.812969983
+    def c2, 1.16437995, 2.01723003, 0.391759992, 1
+    dcl t0.xy
+    dcl t1.xyz
+    dcl_2d s0
+    dcl_2d s1
+    dcl_2d s2
+    dcl_2d s3
+    texld r0, t0, s0
+    texld r1, t0, s2
+    add r0.y, r1.x, c1.x
+    mul r0.yz, r0.y, c1.xzww
+    add r0.x, r0.x, c1.y
+    mad r0.z, r0.x, c2.x, -r0.z
+    mad r1.x, r0.x, c2.x, r0.y
+    rcp r0.y, t1.z
+    mul r2.xy, r0.y, t1
+    texld r3, t0, s1
+    texld r2, r2, s3
+    add r0.y, r3.x, c1.x
+    mad r1.y, r0.y, -c2.z, r0.z
+    mul r0.y, r0.y, c2.y
+    mad r1.z, r0.x, c2.x, r0.y
+    mov r1.w, c2.w
+    mul r0, r1, c0.x
+    mul r0, r2.x, r0
+    mov oC0, r0
+
+// approximately 19 instruction slots used (4 texture, 15 arithmetic)
+ps_4_0
+dcl_constantbuffer CB0[2], immediateIndexed
+dcl_sampler s0, mode_default
+dcl_resource_texture2d (float,float,float,float) t1
+dcl_resource_texture2d (float,float,float,float) t2
+dcl_resource_texture2d (float,float,float,float) t3
+dcl_resource_texture2d (float,float,float,float) t5
+dcl_input_ps linear v1.xy
+dcl_input_ps linear v2.xyz
+dcl_output o0.xyzw
+dcl_temps 3
+sample r0.xyzw, v1.xyxx, t3.xyzw, s0
+add r0.x, r0.x, l(-0.501960)
+mul r0.xy, r0.xxxx, l(1.596030, 0.812970, 0.000000, 0.000000)
+sample r1.xyzw, v1.xyxx, t1.xyzw, s0
+add r0.z, r1.x, l(-0.062750)
+mad r0.y, r0.z, l(1.164380), -r0.y
+mad r1.x, r0.z, l(1.164380), r0.x
+sample r2.xyzw, v1.xyxx, t2.xyzw, s0
+add r0.x, r2.x, l(-0.