Browse Source

More build backports

Ian Neal 2 months ago
parent
commit
f5bfaebdc6

+ 31 - 0
mozilla-release/patches/1359905-65a1.patch

@@ -0,0 +1,31 @@
+# HG changeset patch
+# User Gian-Carlo Pascutto <gcp@mozilla.com>
+# Date 1544020387 0
+# Node ID cceb6f9235a1fc81f1fe2e72be3fb93cd4f5e05c
+# Parent  4b4a87e520a34a445e1220119f9f1cc2c96e334d
+Bug 1359905 - Enable fstack-protector-strong on js/. r=glandium
+
+Differential Revision: https://phabricator.services.mozilla.com/D13570
+
+diff --git a/js/src/old-configure.in b/js/src/old-configure.in
+--- a/js/src/old-configure.in
++++ b/js/src/old-configure.in
+@@ -468,17 +468,17 @@ CXXFLAGS="$CXXFLAGS $MOZ_HARDENING_CFLAG
+ LDFLAGS="$LDFLAGS $MOZ_HARDENING_LDFLAGS_JS"
+ 
+ dnl ========================================================
+ dnl System overrides of the defaults for target
+ dnl ========================================================
+ 
+ case "$target" in
+ *-darwin*)
+-    MOZ_OPTIMIZE_FLAGS="-O3 -fno-stack-protector"
++    MOZ_OPTIMIZE_FLAGS="-O3"
+     CFLAGS="$CFLAGS -fno-common"
+     CXXFLAGS="$CXXFLAGS -fno-common -stdlib=libc++"
+     DSO_LDOPTS=''
+     STRIP="$STRIP -x -S"
+     LDFLAGS="$LDFLAGS -lobjc"
+     # The ExceptionHandling framework is needed for Objective-C exception
+     # logging code in nsObjCExceptions.h. Currently we only use that in debug
+     # builds.

+ 3 - 11
mozilla-release/patches/1397263-6-64a1.patch

@@ -2,7 +2,7 @@
 # User Nathan Froyd <froydnj@mozilla.com>
 # User Nathan Froyd <froydnj@mozilla.com>
 # Date 1538612969 14400
 # Date 1538612969 14400
 # Node ID d678adeaddcd50c3d49c6a4afe3395f1a10853e1
 # Node ID d678adeaddcd50c3d49c6a4afe3395f1a10853e1
-# Parent  c7d294975ffe4b319f7ae716e3869ce6050f4e6f
+# Parent  153c43e606fd8395b859e1fa4085ccbddf975613
 Bug 1397263 - move --enable-accessibility to moz.configure; r=mshal
 Bug 1397263 - move --enable-accessibility to moz.configure; r=mshal
 
 
 diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure
 diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure
@@ -47,7 +47,7 @@ diff --git a/old-configure.in b/old-configure.in
  
  
  case "$target_os" in
  case "$target_os" in
      mingw*)
      mingw*)
-@@ -2186,45 +2185,16 @@ AC_SUBST(MOZ_ENABLE_DBUS)
+@@ -2186,37 +2185,16 @@ AC_SUBST(MOZ_ENABLE_DBUS)
  
  
  dnl =========================================================
  dnl =========================================================
  dnl = Whether to exclude hyphenations files in the build
  dnl = Whether to exclude hyphenations files in the build
@@ -76,14 +76,6 @@ diff --git a/old-configure.in b/old-configure.in
 -    esac
 -    esac
 -    AC_DEFINE(ACCESSIBILITY)
 -    AC_DEFINE(ACCESSIBILITY)
 -fi
 -fi
--
--dnl ========================================================
--dnl Accessibility is required for the linuxgl widget
--dnl backend
--dnl ========================================================
--if test "${MOZ_WIDGET_TOOLKIT}" = "linuxgl" -a "$ACCESSIBILITY" != "1"; then
--    AC_MSG_ERROR(["Accessibility is required for the linuxgl widget backend"])
--fi
 -
 -
  AC_TRY_COMPILE([#include <linux/ethtool.h>],
  AC_TRY_COMPILE([#include <linux/ethtool.h>],
                 [ struct ethtool_cmd cmd; cmd.speed_hi = 0; ],
                 [ struct ethtool_cmd cmd; cmd.speed_hi = 0; ],
@@ -93,7 +85,7 @@ diff --git a/old-configure.in b/old-configure.in
  
  
  if test -n "$MOZ_WEBRTC"; then
  if test -n "$MOZ_WEBRTC"; then
      if test -n "$MOZ_X11"; then
      if test -n "$MOZ_X11"; then
-@@ -3622,17 +3592,16 @@ AC_SUBST(MOZ_PREF_EXTENSIONS)
+@@ -3614,17 +3592,16 @@ AC_SUBST(MOZ_PREF_EXTENSIONS)
  AC_SUBST_LIST(MOZ_DEBUG_LDFLAGS)
  AC_SUBST_LIST(MOZ_DEBUG_LDFLAGS)
  AC_SUBST(WARNINGS_AS_ERRORS)
  AC_SUBST(WARNINGS_AS_ERRORS)
  AC_SUBST_LIST(WARNINGS_CFLAGS)
  AC_SUBST_LIST(WARNINGS_CFLAGS)

+ 36 - 0
mozilla-release/patches/1481864-63a1.patch

@@ -0,0 +1,36 @@
+# HG changeset patch
+# User Nathan Froyd <froydnj@mozilla.com>
+# Date 1534800164 14400
+# Node ID dfd04e76e5a6617227c9da8c6961564446cf0f9d
+# Parent  5eecc0f3362e81735530a10e27b82a912cc24257
+Bug 1481864 - disable the sandbox on aarch64 windows by default; r=gps
+
+The Chromium sandbox doesn't have the necessary arch-specific support.
+
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -2060,16 +2060,23 @@ if test -n "$MOZ_TSAN" -o -n "$MOZ_ASAN"
+     # Bug 1287971: LSan also conflicts with sandboxing on Linux.
+     case $OS_TARGET in
+     Linux|Android)
+         MOZ_SANDBOX=
+         ;;
+     esac
+ fi
+ 
++case "$OS_TARGET:$CPU_ARCH" in
++WINNT:aarch64)
++    # No sandbox support on AArch64 Windows.
++    MOZ_SANDBOX=
++    ;;
++esac
++
+ MOZ_ARG_DISABLE_BOOL(sandbox,
+ [  --disable-sandbox        Disable sandboxing support],
+     MOZ_SANDBOX=,
+     MOZ_SANDBOX=1)
+ 
+ dnl ========================================================
+ dnl = Content process sandboxing
+ dnl ========================================================

+ 233 - 0
mozilla-release/patches/1483780-1-64a1.patch

@@ -0,0 +1,233 @@
+# HG changeset patch
+# User Thomas P. <pdknsk+mozilla@gmail.com>
+# Date 1537478498 0
+# Node ID 5ab8b903147a0cc97b21d278299840b9e38aa1f6
+# Parent  c304fc3634f88a96e2dd3d19ccd414d9d3d9a947
+Bug 1483780: enable sanitizer-less libfuzzer builds r=froydnj
+
+diff --git a/build/autoconf/sanitize.m4 b/build/autoconf/sanitize.m4
+--- a/build/autoconf/sanitize.m4
++++ b/build/autoconf/sanitize.m4
+@@ -111,16 +111,23 @@ if test -n "$MOZ_SIGNED_OVERFLOW_SANITIZ
+     CXXFLAGS="$SANITIZER_BLACKLISTS $CXXFLAGS"
+     AC_DEFINE(MOZ_UBSAN)
+     MOZ_PATH_PROG(LLVM_SYMBOLIZER, llvm-symbolizer)
+ fi
+ AC_SUBST(MOZ_SIGNED_OVERFLOW_SANITIZE)
+ AC_SUBST(MOZ_UNSIGNED_OVERFLOW_SANITIZE)
+ AC_SUBST(MOZ_UBSAN)
+ 
++dnl =======================================================
++dnl = Required for stand-alone (sanitizer-less) libFuzzer.
++dnl =======================================================
++if test -n "$LIBFUZZER"; then
++   LDFLAGS="$LIBFUZZER_FLAGS -rdynamic $LDFLAGS"
++fi
++
+ # The LLVM symbolizer is used by all sanitizers
+ AC_SUBST(LLVM_SYMBOLIZER)
+ 
+ dnl ========================================================
+ dnl = Test for whether the compiler is compatible with the
+ dnl = given sanitize options.
+ dnl ========================================================
+ AC_TRY_LINK(,,,AC_MSG_ERROR([compiler is incompatible with sanitize options]))
+diff --git a/build/moz.configure/toolchain.configure b/build/moz.configure/toolchain.configure
+--- a/build/moz.configure/toolchain.configure
++++ b/build/moz.configure/toolchain.configure
+@@ -2267,22 +2267,33 @@ add_gcc_flag(
+ add_gcc_flag(
+     '-D_GLIBCXX_USE_CXX11_ABI=0', host_cxx_compiler,
+     when=libstdcxx_version(
+         'MOZ_LIBSTDCXX_HOST_VERSION', host_cxx_compiler, host))
+ 
+ 
+ @depends(c_compiler.try_compile(flags=['-fsanitize=fuzzer-no-link'],
+          check_msg='whether the C compiler supports -fsanitize=fuzzer-no-link'))
+-def have_libfuzzer_flag_fuzzer_no_link(value):
++def libfuzzer_flags(value):
+     if value:
+-        return True
+-
+-
+-set_config('HAVE_LIBFUZZER_FLAG_FUZZER_NO_LINK', have_libfuzzer_flag_fuzzer_no_link)
++        no_link_flag_supported = True
++        # recommended for (and only supported by) clang >= 6
++        use_flags = ['-fsanitize=fuzzer-no-link']
++    else:
++        no_link_flag_supported = False
++        use_flags = ['-fsanitize-coverage=trace-pc-guard,trace-cmp']
++
++    return namespace(
++        no_link_flag_supported=no_link_flag_supported,
++        use_flags=use_flags,
++    )
++
++set_config('HAVE_LIBFUZZER_FLAG_FUZZER_NO_LINK', libfuzzer_flags.no_link_flag_supported)
++set_config('LIBFUZZER_FLAGS', libfuzzer_flags.use_flags)
++add_old_configure_assignment('LIBFUZZER_FLAGS', libfuzzer_flags.use_flags)
+ 
+ # Shared library building
+ # ==============================================================
+ 
+ # XXX: The use of makefile constructs in these variables is awful.
+ @depends(target, c_compiler)
+ def make_shared_library(target, compiler):
+     if target.os == 'WINNT':
+diff --git a/config/rules.mk.1483780-1.later b/config/rules.mk.1483780-1.later
+new file mode 100644
+--- /dev/null
++++ b/config/rules.mk.1483780-1.later
+@@ -0,0 +1,65 @@
++--- rules.mk
+++++ rules.mk
++@@ -907,16 +907,17 @@ endif
++ ifdef MOZ_USING_SCCACHE
++ sccache_wrap := RUSTC_WRAPPER='$(CCACHE)'
++ endif
++ 
++ ifndef MOZ_ASAN
++ ifndef MOZ_TSAN
++ ifndef MOZ_UBSAN
++ ifndef MOZ_CODE_COVERAGE
+++ifndef FUZZING_INTERFACES
++ # Pass the compilers and flags in use to cargo for use in build scripts.
++ # * Don't do this for ASAN/TSAN builds because we don't pass our custom linker (see below)
++ #   which will muck things up.
++ # * Don't do this for code coverage builds because the way rustc invokes the linker doesn't
++ #   work with GCC 6: https://bugzilla.mozilla.org/show_bug.cgi?id=1477305
++ #
++ # We don't pass HOST_{CC,CXX} down in any form because our host value might not match
++ # what cargo chooses and there's no way to control cargo's selection, so we just have to
++@@ -938,16 +939,17 @@ else
++ cargo_c_compiler_envs := \
++  CC_$(rust_cc_env_name)="$(CC)" \
++  CXX_$(rust_cc_env_name)="$(CXX)" \
++  CFLAGS_$(rust_cc_env_name)="$(COMPUTED_CFLAGS)" \
++  CXXFLAGS_$(rust_cc_env_name)="$(COMPUTED_CXXFLAGS)" \
++  AR_$(rust_cc_env_name)="$(AR)" \
++  $(NULL)
++ endif # WINNT
+++endif # FUZZING_INTERFACES
++ endif # MOZ_CODE_COVERAGE
++ endif # MOZ_UBSAN
++ endif # MOZ_TSAN
++ endif # MOZ_ASAN
++ 
++ # We use the + prefix to pass down the jobserver fds to cargo, but we
++ # don't use the prefix when make -n is used, so that cargo doesn't run
++ # in that case)
++@@ -1003,24 +1005,26 @@ cargo_linker_env_var := CARGO_TARGET_$(R
++ # have to pass in any special linker options on Windows.
++ ifneq (WINNT,$(OS_ARCH))
++ 
++ # Defining all of this for ASan/TSan builds results in crashes while running
++ # some crates's build scripts (!), so disable it for now.
++ ifndef MOZ_ASAN
++ ifndef MOZ_TSAN
++ ifndef MOZ_UBSAN
+++ifndef FUZZING_INTERFACES
++ # Cargo needs the same linker flags as the C/C++ compiler,
++ # but not the final libraries. Filter those out because they
++ # cause problems on macOS 10.7; see bug 1365993 for details.
++ # Also, we don't want to pass PGO flags until cargo supports them.
++ target_cargo_env_vars := \
++ 	MOZ_CARGO_WRAP_LDFLAGS="$(filter-out -fsanitize=cfi% -framework Cocoa -lobjc AudioToolbox ExceptionHandling -fprofile-%,$(LDFLAGS))" \
++ 	MOZ_CARGO_WRAP_LD="$(CC)" \
++ 	$(cargo_linker_env_var)=$(topsrcdir)/build/cargo-linker
+++endif # FUZZING_INTERFACES
++ endif # MOZ_UBSAN
++ endif # MOZ_TSAN
++ endif # MOZ_ASAN
++ 
++ endif # ifneq WINNT
++ 
++ ifdef RUST_LIBRARY_FILE
++ 
+diff --git a/js/moz.configure b/js/moz.configure
+--- a/js/moz.configure
++++ b/js/moz.configure
+@@ -413,19 +413,21 @@ with only_when('--enable-compile-environ
+         if fuzzing and (afl or libfuzzer):
+             return True
+ 
+     set_config('FUZZING', enable_fuzzing)
+     set_define('FUZZING', enable_fuzzing)
+ 
+     set_config('LIBFUZZER', enable_libfuzzer)
+     set_define('LIBFUZZER', enable_libfuzzer)
++    add_old_configure_assignment('LIBFUZZER', enable_libfuzzer)
+ 
+     set_config('FUZZING_INTERFACES', enable_fuzzing_interfaces)
+     set_define('FUZZING_INTERFACES', enable_fuzzing_interfaces)
++    add_old_configure_assignment('FUZZING_INTERFACES', enable_fuzzing_interfaces)
+ 
+ # Enable pipeline operator
+ # ===================================================
+ js_option('--enable-pipeline-operator', default=False, help='Enable pipeline operator')
+ 
+ @depends('--enable-pipeline-operator')
+ def enable_pipeline_operator(value):
+     if value:
+diff --git a/js/src/old-configure.in b/js/src/old-configure.in
+--- a/js/src/old-configure.in
++++ b/js/src/old-configure.in
+@@ -339,17 +339,17 @@ dnl ====================================
+ dnl GNU specific defaults
+ dnl ========================================================
+ if test "$GNU_CC"; then
+     DSO_LDOPTS='-shared'
+     if test "$GCC_USE_GNU_LD"; then
+         # Some tools like ASan use a runtime library that is only
+         # linked against executables, so we must allow undefined
+         # symbols for shared objects in some cases.
+-        if test -z "$MOZ_ASAN$MOZ_MSAN$MOZ_UBSAN$MOZ_TSAN"; then
++        if test -z "$MOZ_ASAN$MOZ_MSAN$MOZ_UBSAN$MOZ_TSAN$FUZZING_INTERFACES"; then
+             # Don't allow undefined symbols in libraries
+             DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
+         fi
+     fi
+     WARNINGS_AS_ERRORS='-Werror'
+     DSO_CFLAGS=''
+ 
+     if test "$OS_ARCH" != "WINNT"; then
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -454,17 +454,17 @@ if test "$GNU_CC"; then
+       ;;
+     esac
+ 
+     DSO_LDOPTS='-shared'
+     if test "$GCC_USE_GNU_LD"; then
+         # Some tools like ASan use a runtime library that is only
+         # linked against executables, so we must allow undefined
+         # symbols for shared objects in some cases.
+-        if test -z "$MOZ_ASAN$MOZ_MSAN$MOZ_UBSAN$MOZ_TSAN"; then
++        if test -z "$MOZ_ASAN$MOZ_MSAN$MOZ_UBSAN$MOZ_TSAN$FUZZING_INTERFACES"; then
+             # Don't allow undefined symbols in libraries
+             DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
+ 
+             # BSDs need `environ' exposed for posix_spawn (bug 753046)
+             case "$OS_TARGET" in
+             DragonFly|FreeBSD|NetBSD|OpenBSD)
+                 if test -n "$HAVE_LINKER_SUPPORT_IGNORE_UNRESOLVED"; then
+                     DSO_LDOPTS="$DSO_LDOPTS -Wl,--ignore-unresolved-symbol,environ"
+diff --git a/tools/fuzzing/libfuzzer-flags.mozbuild b/tools/fuzzing/libfuzzer-flags.mozbuild
+--- a/tools/fuzzing/libfuzzer-flags.mozbuild
++++ b/tools/fuzzing/libfuzzer-flags.mozbuild
+@@ -1,13 +1,8 @@
+ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+ # vim: set filetype=python:
+ # This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+ libfuzzer_flags = []
+-
+-if CONFIG['HAVE_LIBFUZZER_FLAG_FUZZER_NO_LINK']:
+-    libfuzzer_flags += ['-fsanitize=fuzzer-no-link']
+-else:
+-    # Older Clang versions (<= 5) only support an older set of libFuzzer flags
+-    libfuzzer_flags += ['-fsanitize-coverage=trace-pc-guard,trace-cmp']
++libfuzzer_flags += CONFIG['LIBFUZZER_FLAGS']

+ 23 - 0
mozilla-release/patches/1483780-2-64a1.patch

@@ -0,0 +1,23 @@
+# HG changeset patch
+# User Andreea Pavel <apavel@mozilla.com>
+# Date 1537503232 -10800
+# Node ID eb6bde5f4dfdd0cfa544b0d99a4bb1153224d33b
+# Parent  10a88940d26d8b9fa0bad1ff7b899a4f41d66704
+Bug 1483780 - additional patch to sanitizer-less-4 r=test-fix
+
+diff --git a/tools/fuzzing/libfuzzer-flags.mozbuild b/tools/fuzzing/libfuzzer-flags.mozbuild
+--- a/tools/fuzzing/libfuzzer-flags.mozbuild
++++ b/tools/fuzzing/libfuzzer-flags.mozbuild
+@@ -1,8 +1,11 @@
+ # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+ # vim: set filetype=python:
+ # This Source Code Form is subject to the terms of the Mozilla Public
+ # License, v. 2.0. If a copy of the MPL was not distributed with this
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ 
+ libfuzzer_flags = []
+-libfuzzer_flags += CONFIG['LIBFUZZER_FLAGS']
++
++if CONFIG['LIBFUZZER_FLAGS']:
++    libfuzzer_flags += CONFIG['LIBFUZZER_FLAGS']
++

+ 37 - 0
mozilla-release/patches/1494958-64a1.patch

@@ -0,0 +1,37 @@
+# HG changeset patch
+# User Nathan Froyd <froydnj@mozilla.com>
+# Date 1538509266 14400
+# Node ID f9572cfd7bac75d4493f44206cd27958d74269d0
+# Parent  51b5d89de3ba2d3794f7321ae8827e4177962d35
+Bug 1494958 - remove linuxgl/accessibility check in old-configure.in; r=ted.mielczarek
+
+linuxgl is not a widget toolkit we support nowadays.
+
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -2239,24 +2239,16 @@ if test "$ACCESSIBILITY"; then
+             else
+                 AC_MSG_ERROR([You have accessibility enabled, but widl could not be found. Add --disable-accessibility to your mozconfig or install widl. See https://developer.mozilla.org/en-US/docs/Cross_Compile_Mozilla_for_Mingw32 for details.])
+             fi
+         fi
+     esac
+     AC_DEFINE(ACCESSIBILITY)
+ fi
+ 
+-dnl ========================================================
+-dnl Accessibility is required for the linuxgl widget
+-dnl backend
+-dnl ========================================================
+-if test "${MOZ_WIDGET_TOOLKIT}" = "linuxgl" -a "$ACCESSIBILITY" != "1"; then
+-    AC_MSG_ERROR(["Accessibility is required for the linuxgl widget backend"])
+-fi
+-
+ AC_TRY_COMPILE([#include <linux/ethtool.h>],
+                [ struct ethtool_cmd cmd; cmd.speed_hi = 0; ],
+                MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI=1)
+ 
+ AC_SUBST(MOZ_WEBRTC_HAVE_ETHTOOL_SPEED_HI)
+ 
+ if test -n "$MOZ_WEBRTC"; then
+     if test -n "$MOZ_X11"; then

+ 40 - 0
mozilla-release/patches/1508547-1-65a1.patch

@@ -0,0 +1,40 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1542762787 0
+# Node ID 6f3303d415f7920900d800869ce901eed060c889
+# Parent  94570181066658552dc9f24799b322ff634fad7f
+Bug 1508547 - Disable the machine outliner on Android. r=dmajor
+
+It's enabled by default as of clang 7 with -Oz on aarch64 (that is,
+afaict, the only platform where it's enabled), and regresses our
+performance on speedometer.
+
+Differential Revision: https://phabricator.services.mozilla.com/D12394
+
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -608,16 +608,23 @@ case "$target" in
+ 
+     MOZ_GFX_OPTIMIZE_MOBILE=1
+     if test -z "$CLANG_CC"; then
+         MOZ_OPTIMIZE_FLAGS="-freorder-blocks -fno-reorder-functions -Os"
+     else
+         # From https://github.com/android-ndk/ndk/issues/133#issuecomment-308549264
+         # -Oz is smaller than -Os on clang.
+         MOZ_OPTIMIZE_FLAGS="-Oz"
++        # Disable the outliner, which causes performance regressions, and is
++        # enabled on some platforms at -Oz.
++        DISABLE_OUTLINER="-mno-outline"
++        _SAVE_CFLAGS=$CFLAGS
++        CFLAGS="$CFLAGS $DISABLE_OUTLINER"
++        AC_TRY_COMPILE(,,[MOZ_OPTIMIZE_FLAGS="$MOZ_OPTIMIZE_FLAGS $DISABLE_OUTLINER"])
++        CFLAGS="$_SAVE_CFLAGS"
+     fi
+     ;;
+ 
+ *-*linux*)
+     if test "$GNU_CC" -o "$GNU_CXX"; then
+         MOZ_PGO_OPTIMIZE_FLAGS="-O3"
+         if test -n "$MOZ_DEBUG"; then
+             MOZ_OPTIMIZE_FLAGS="-Os"

+ 48 - 0
mozilla-release/patches/1508547-2-65a1.patch

@@ -0,0 +1,48 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1542751849 0
+# Node ID 8540104bb0bd811f9fd45b160dbe38a67c9aa5cd
+# Parent  a751a5cbc55032d6865f9759e94346c3e735d751
+Bug 1508547 - Switch Android builds to clang 7 again. r=dmajor
+
+Bug 1492663 upgraded those builds to clang 7, and bug 1503330 brought
+them back to clang 6 because of speedometer regressions.
+
+With the previous change, the regression doesn't happen any more,
+allowing to upgrade again.
+
+Depends on D12394
+
+Differential Revision: https://phabricator.services.mozilla.com/D12395
+
+diff --git a/build/build-clang/clang-6-linux64.json b/build/build-clang/clang-6-linux64.json
+deleted file mode 100644
+--- a/build/build-clang/clang-6-linux64.json
++++ /dev/null
+@@ -1,26 +0,0 @@
+-{
+-    "llvm_revision": "335538",
+-    "stages": "3",
+-    "build_libcxx": true,
+-    "build_type": "Release",
+-    "assertions": false,
+-    "llvm_repo": "https://llvm.org/svn/llvm-project/llvm/tags/RELEASE_601/final",
+-    "clang_repo": "https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_601/final",
+-    "lld_repo": "https://llvm.org/svn/llvm-project/lld/tags/RELEASE_601/final",
+-    "compiler_repo": "https://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_601/final",
+-    "libcxx_repo": "https://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_601/final",
+-    "libcxxabi_repo": "https://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_601/final",
+-    "python_path": "/usr/bin/python2.7",
+-    "gcc_dir": "/builds/worker/workspace/build/src/gcc",
+-    "cc": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+-    "cxx": "/builds/worker/workspace/build/src/gcc/bin/g++",
+-    "as": "/builds/worker/workspace/build/src/gcc/bin/gcc",
+-    "patches": [
+-      "static-llvm-symbolizer.patch",
+-      "find_symbolizer_linux.patch",
+-      "r322325.patch",
+-      "r322401.patch",
+-      "r325356.patch",
+-      "r339636.patch"
+-    ]
+-}

+ 74 - 0
mozilla-release/patches/1516228-1-66a1.patch

@@ -0,0 +1,74 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1548344027 0
+# Node ID 8456feb780f7a4b44dc879268e6390aa4f4ce0b1
+# Parent  f638856845113e0d8be636af303895b1b438a581
+Bug 1516228 - Add a configure check for llvm-objdump. r=firefox-build-system-reviewers,mshal
+
+Differential Revision: https://phabricator.services.mozilla.com/D17462
+
+diff --git a/build/moz.configure/init.configure b/build/moz.configure/init.configure
+--- a/build/moz.configure/init.configure
++++ b/build/moz.configure/init.configure
+@@ -4,16 +4,19 @@
+ # 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('util.configure')
+ include('checks.configure')
+ 
+ # Make `toolkit` available when toolkit/moz.configure is not included.
+ toolkit = dependable(None)
++# Likewise with `bindgen_config_paths` when
++# build/moz.configure/bindgen.configure is not included.
++bindgen_config_paths = dependable(None)
+ 
+ option(env='DIST', nargs=1, help='DIST directory')
+ 
+ 
+ # Do not allow objdir == srcdir builds.
+ # ==============================================================
+ @depends('--help', 'DIST')
+ @imports(_from='__builtin__', _import='open')
+diff --git a/moz.configure b/moz.configure
+--- a/moz.configure
++++ b/moz.configure
+@@ -584,16 +584,38 @@ def nsis_flags(host):
+         return '-nocd'
+     return ''
+ 
+ set_config('MAKENSISU_FLAGS', nsis_flags)
+ 
+ check_prog('7Z', ('7z', '7za'), allow_missing=True, when=target_is_windows)
+ 
+ 
++@depends(c_compiler, bindgen_config_paths)
++def llvm_objdump(c_compiler, bindgen_config_paths):
++    clang = None
++    if c_compiler and c_compiler.type == 'clang':
++        clang = c_compiler.compiler
++    elif c_compiler and c_compiler.type == 'clang-cl':
++        clang = os.path.join(os.path.dirname(c_compiler.compiler), 'clang')
++    elif bindgen_config_paths:
++        clang = bindgen_config_paths.clang_path
++    llvm_objdump = 'llvm-objdump'
++    if clang:
++        out = check_cmd_output(clang, '--print-prog-name=llvm-objdump',
++                               onerror=lambda: None)
++        if out:
++            llvm_objdump = out.rstrip()
++    return (llvm_objdump,)
++
++
++check_prog('LLVM_OBJDUMP', llvm_objdump, what='llvm-objdump',
++           when='--enable-compile-environment')
++
++
+ js_option('--enable-dtrace', help='Build with dtrace support')
+ 
+ dtrace = check_header('sys/sdt.h', when='--enable-dtrace',
+                       onerror=lambda: die('dtrace enabled but sys/sdt.h not found'))
+ 
+ set_config('HAVE_DTRACE', True, when=dtrace)
+ set_define('INCLUDE_MOZILLA_DTRACE', True, when=dtrace)
+ add_old_configure_assignment('enable_dtrace', 'yes', when=dtrace)

+ 59 - 0
mozilla-release/patches/1516228-2no3or4-66a1.patch

@@ -0,0 +1,59 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1548344458 0
+# Node ID 94dd43dcc7f2e444b8a1b201a84fb082da8b5dcd
+# Parent  a5f4bf2847968d240ecb504180a932603b714aab
+Bug 1516228 - Use llvm-objdump instead of objdump in old-configure. r=mshal
+
+Depends on D17462
+
+Differential Revision: https://phabricator.services.mozilla.com/D17463
+
+diff --git a/build/autoconf/compiler-opts.m4 b/build/autoconf/compiler-opts.m4
+--- a/build/autoconf/compiler-opts.m4
++++ b/build/autoconf/compiler-opts.m4
+@@ -109,17 +109,17 @@ if test "$GNU_CC" -a "$GCC_USE_GNU_LD" -
+         LD_SUPPORTS_ICF,
+         [echo 'int foo() {return 42;}' \
+               'int bar() {return 42;}' \
+               'int main() {return foo() - bar();}' > conftest.${ac_ext}
+         # If the linker supports ICF, foo and bar symbols will have
+         # the same address
+         if AC_TRY_COMMAND([${CC-cc} -o conftest${ac_exeext} $LDFLAGS -Wl,--icf=safe -ffunction-sections conftest.${ac_ext} $LIBS 1>&2]) &&
+            test -s conftest${ac_exeext} &&
+-           objdump -t conftest${ac_exeext} | awk changequote(<<, >>)'{a[<<$>>6] = <<$>>1} END {if (a["foo"] && (a["foo"] != a["bar"])) { exit 1 }}'changequote([, ]); then
++           $LLVM_OBJDUMP -t conftest${ac_exeext} | awk changequote(<<, >>)'{a[<<$>>6] = <<$>>1} END {if (a["foo"] && (a["foo"] != a["bar"])) { exit 1 }}'changequote([, ]); then
+             LD_SUPPORTS_ICF=yes
+         else
+             LD_SUPPORTS_ICF=no
+         fi
+         rm -rf conftest*])
+     if test "$LD_SUPPORTS_ICF" = yes; then
+         _SAVE_LDFLAGS="$LDFLAGS -Wl,--icf=safe"
+         LDFLAGS="$LDFLAGS -Wl,--icf=safe -Wl,--print-icf-sections"
+diff --git a/moz.configure b/moz.configure
+--- a/moz.configure
++++ b/moz.configure
+@@ -602,18 +602,20 @@ def llvm_objdump(c_compiler, bindgen_con
+     if clang:
+         out = check_cmd_output(clang, '--print-prog-name=llvm-objdump',
+                                onerror=lambda: None)
+         if out:
+             llvm_objdump = out.rstrip()
+     return (llvm_objdump,)
+ 
+ 
+-check_prog('LLVM_OBJDUMP', llvm_objdump, what='llvm-objdump',
+-           when='--enable-compile-environment')
++llvm_objdump = check_prog('LLVM_OBJDUMP', llvm_objdump, what='llvm-objdump',
++                          when='--enable-compile-environment')
++
++add_old_configure_assignment('LLVM_OBJDUMP', llvm_objdump)
+ 
+ 
+ js_option('--enable-dtrace', help='Build with dtrace support')
+ 
+ dtrace = check_header('sys/sdt.h', when='--enable-dtrace',
+                       onerror=lambda: die('dtrace enabled but sys/sdt.h not found'))
+ 
+ set_config('HAVE_DTRACE', True, when=dtrace)

+ 290 - 0
mozilla-release/patches/1516228-5-66a1.patch

@@ -0,0 +1,290 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1548372749 0
+# Node ID d1b523e67100557e4adceabe8ca6ea434f6cb5e7
+# Parent  2e12f8ff052c6449f80f0b4fe0cca5fb00a6e313
+Bug 1516228 - Use llvm-objdump for symbol related tests in check_binary.py. r=mshal
+
+Depends on D17466
+
+Differential Revision: https://phabricator.services.mozilla.com/D17467
+
+diff --git a/python/mozbuild/mozbuild/action/check_binary.py b/python/mozbuild/mozbuild/action/check_binary.py
+--- a/python/mozbuild/mozbuild/action/check_binary.py
++++ b/python/mozbuild/mozbuild/action/check_binary.py
+@@ -1,53 +1,54 @@
+ # 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/.
+ 
+ from __future__ import absolute_import, print_function, unicode_literals
+ 
+ import argparse
+ import os
++import re
+ import subprocess
+ import sys
+ 
+ from packaging.version import Version
+ 
+ import buildconfig
+ from mozbuild.util import memoize
+ from mozpack.executables import (
+     get_type,
+     ELF,
+     MACHO,
++    UNKNOWN,
+ )
+ 
+ 
+ STDCXX_MAX_VERSION = Version('3.4.19')
+ CXXABI_MAX_VERSION = Version('1.3.7')
+ GLIBC_MAX_VERSION = Version('2.17')
+ LIBGCC_MAX_VERSION = Version('4.8')
+ 
+ HOST = {
+     'MOZ_LIBSTDCXX_VERSION':
+         buildconfig.substs.get('MOZ_LIBSTDCXX_HOST_VERSION'),
+     'platform': buildconfig.substs['HOST_OS_ARCH'],
+     'readelf': 'readelf',
+-    'nm': 'nm',
+ }
+ 
+ TARGET = {
+     'MOZ_LIBSTDCXX_VERSION':
+         buildconfig.substs.get('MOZ_LIBSTDCXX_TARGET_VERSION'),
+     'platform': buildconfig.substs['OS_TARGET'],
+     'readelf': '{}readelf'.format(
+         buildconfig.substs.get('TOOLCHAIN_PREFIX', '')),
+-    'nm': '{}nm'.format(buildconfig.substs.get('TOOLCHAIN_PREFIX', '')),
+-    'readobj': '{}readobj'.format(buildconfig.substs.get('TOOLCHAIN_PREFIX', '')),
+ }
+ 
++ADDR_RE = re.compile(r'[0-9a-f]{8,16}')
++
+ if buildconfig.substs.get('HAVE_64BIT_BUILD'):
+     GUESSED_NSMODULE_SIZE = 8
+ else:
+     GUESSED_NSMODULE_SIZE = 4
+ 
+ 
+ get_type = memoize(get_type)
+ 
+@@ -71,62 +72,107 @@ def at_least_one(iter):
+     saw_one = False
+     for item in iter:
+         saw_one = True
+         yield item
+     if not saw_one:
+         raise Empty()
+ 
+ 
+-def iter_readelf_symbols(target, binary):
+-    for line in get_output(target['readelf'], '-sW', binary):
+-        data = line.split()
+-        if len(data) >= 8 and data[0].endswith(':') and data[0][:-1].isdigit():
+-            n, addr, size, type, bind, vis, index, name = data[:8]
++# Iterates the symbol table on ELF and MACHO, and the export table on
++# COFF/PE.
++def iter_symbols(binary):
++    ty = get_type(binary)
++    # XXX: Static libraries on ELF, MACHO and COFF/PE systems are all
++    # ar archives. So technically speaking, the following is wrong
++    # but is enough for now. llvm-objdump -t can actually be used on all
++    # platforms for static libraries, but its format is different for
++    # Windows .obj files, so the following won't work for them, but
++    # it currently doesn't matter.
++    if ty == UNKNOWN and open(binary).read(8) == '!<arch>\n':
++        ty = ELF
++    if ty in (ELF, MACHO):
++        for line in get_output(buildconfig.substs['LLVM_OBJDUMP'], '-t',
++                               binary):
++            m = ADDR_RE.match(line)
++            if not m:
++                continue
++            addr = int(m.group(0), 16)
++            # The second "column" is 7 one-character items that can be
++            # whitespaces. We don't have use for their value, so just skip
++            # those.
++            rest = line[m.end() + 9:].split()
++            # The number of remaining colums will vary between ELF and MACHO.
++            # On ELF, we have:
++            #   Section Size .hidden? Name
++            # On Macho, the size is skipped.
++            # In every case, the symbol name is last.
++            name = rest[-1]
+             if '@' in name:
+                 name, ver = name.rsplit('@', 1)
+                 while name.endswith('@'):
+                     name = name[:-1]
+             else:
+                 ver = None
+             yield {
+-                'addr': int(addr, 16),
+-                # readelf output may contain decimal values or hexadecimal
+-                # values prefixed with 0x for the size. Let python autodetect.
+-                'size': int(size, 0),
+-                'type': type,
+-                'binding': bind,
+-                'visibility': vis,
+-                'index': index,
++                'addr': addr,
++                'size': int(rest[1], 16) if ty == ELF else 0,
+                 'name': name,
+-                'version': ver,
++                'version': ver or None,
++            }
++    else:
++        export_table = False
++        for line in get_output(buildconfig.substs['LLVM_OBJDUMP'], '-p',
++                               binary):
++            if line.strip() == 'Export Table:':
++                export_table = True
++                continue
++            elif not export_table:
++                continue
++
++            cols = line.split()
++            # The data we're interested in comes in 3 columns, and the first
++            # column is a number.
++            if len(cols) != 3 or not cols[0].isdigit():
++                continue
++            _, rva, name = cols
++            # - The MSVC mangling has some type info following `@@`
++            # - Any namespacing that can happen on the symbol appears as a
++            #   suffix, after a `@`.
++            # - Mangled symbols are prefixed with `?`.
++            name = name.split('@@')[0].split('@')[0].lstrip('?')
++            yield {
++                'addr': int(rva, 16),
++                'size': 0,
++                'name': name,
++                'version': None,
+             }
+ 
+ 
+ def iter_readelf_dynamic(target, binary):
+     for line in get_output(target['readelf'], '-d', binary):
+         data = line.split(None, 2)
+         if data and len(data) == 3 and data[0].startswith('0x'):
+             yield data[1].rstrip(')').lstrip('('), data[2]
+ 
+ 
+ def check_dep_versions(target, binary, lib, prefix, max_version):
+     if get_type(binary) != ELF:
+         raise Skip()
+     unwanted = []
+     prefix = prefix + '_'
+     try:
+-        for sym in at_least_one(iter_readelf_symbols(target, binary)):
+-            if sym['index'] == 'UND' and sym['version'] and \
++        for sym in at_least_one(iter_symbols(binary)):
++            if sym['addr'] == 0 and sym['version'] and \
+                     sym['version'].startswith(prefix):
+                 version = Version(sym['version'][len(prefix):])
+                 if version > max_version:
+                     unwanted.append(sym)
+     except Empty:
+-        raise RuntimeError('Could not parse readelf output?')
++        raise RuntimeError('Could not parse llvm-objdump output?')
+     if unwanted:
+         print('\n'.join([
+             'TEST-NOTICE We do not want these {} symbol versions to be used:'.format(lib)
+         ] + [
+             ' {} ({})'.format(s['name'], s['version']) for s in unwanted
+         ]), file=sys.stderr)
+ 
+ 
+@@ -178,73 +224,35 @@ def check_nsmodules(target, binary):
+ 
+     test_msvc = (buildconfig.substs.get('CC_TYPE') in ('msvc', 'clang-cl') and \
+         buildconfig.substs.get('DEVELOPER_OPTIONS'))
+     test_clang_win = (buildconfig.substs.get('CC_TYPE') == 'clang' and \
+         buildconfig.substs.get('OS_ARCH') == 'WINNT')
+     test_gcc_win = (buildconfig.substs.get('CC_TYPE') == 'gcc' and \
+         buildconfig.substs.get('OS_ARCH') == 'WINNT')
+ 
+-    if buildconfig.substs.get('CC_TYPE') in ('msvc', 'clang-cl'):
+-        for line in get_output('dumpbin.exe', '-exports', binary):
+-            data = line.split(None, 3)
+-            if data and len(data) == 4 and data[0].isdigit() and \
+-                    ishex(data[1]) and ishex(data[2]):
+-                # - Some symbols in the table can be aliases, and appear as
+-                #   `foo = bar`.
+-                # - The MSVC mangling has some type info following `@@`
+-                # - Any namespacing that can happen on the symbol appears as a
+-                #   suffix, after a `@`.
+-                # - Mangled symbols are prefixed with `?`.
+-                name = data[3].split(' = ')[0].split('@@')[0].split('@')[0] \
+-                              .lstrip('?')
+-                if name.endswith('_NSModule') or name in (
+-                        '__start_kPStaticModules',
+-                        '__stop_kPStaticModules'):
+-                    symbols.append((int(data[2], 16), GUESSED_NSMODULE_SIZE,
+-                                    name))
+-    else:
+-        # MinGW-Clang, when building pdbs, doesn't include the symbol table into
+-        # the final module. To get the NSModule info, we can look at the exported
+-        # symbols. (#1475562)
+-        if test_clang_win:
+-            readobj_output = get_output(target['readobj'], '-coff-exports', binary)
+-            # Transform the output of readobj into nm-like output
+-            output = []
+-            for line in readobj_output:
+-                if "Name" in line:
+-                    name = line.replace("Name:", "").strip()
+-                elif "RVA" in line:
+-                    rva = line.replace("RVA:", "").strip()
+-                    output.append("%s r %s" % (name, rva))
+-        else:
+-            output = get_output(target['nm'], '-P', binary)
+-
+-        for line in output:
+-            data = line.split()
+-            # Some symbols may not have a size listed at all.
+-            if len(data) == 3:
+-                data.append('0')
+-            if len(data) == 4:
+-                sym, _, addr, size = data
+-                # NSModules symbols end with _NSModule or _NSModuleE when
+-                # C++-mangled.
+-                if sym.endswith(('_NSModule', '_NSModuleE')):
+-                    if test_gcc_win and any(x in data[0] for x in [".refptr", "_GLOBAL"]):
+-                        continue
+-                    # On mac, nm doesn't actually print anything other than 0
+-                    # for the size. So take our best guess.
+-                    size = int(size, 16) or GUESSED_NSMODULE_SIZE
+-                    symbols.append((int(addr, 16), size, sym))
+-                elif sym.endswith(('__start_kPStaticModules',
+-                                   '__stop_kPStaticModules')):
+-                    # On ELF and mac systems, these symbols have no size, such
+-                    # that the first actual NSModule has the same address as
+-                    # the start symbol.
+-                    symbols.append((int(addr, 16), 0, sym))
++    for sym in iter_symbols(binary):
++        if sym['addr'] == 0:
++            continue
++        name = sym['name']
++        # NSModules symbols end with _NSModule or _NSModuleE when C++-mangled.
++        if name.endswith(('_NSModule', '_NSModuleE')):
++            if test_gcc_win and any(x in data[0] for x in [".refptr", "_GLOBAL"]):
++                continue
++            # We don't have a valid size in the symbol list for macho and coff.
++            # Use our guesstimate.
++            size = sym['size'] or GUESSED_NSMODULE_SIZE
++            symbols.append((sym['addr'], size, name))
++        elif name in ('__start_kPStaticModules', '__stop_kPStaticModules'):
++            # For coff, these symbols have a size.
++            if get_type(binary) not in (ELF, MACHO):
++                size = GUESSED_NSMODULE_SIZE
++            else:
++                size = 0
++            symbols.append((sym['addr'], size, name))
+     if not symbols:
+         raise RuntimeError('Could not find NSModules')
+ 
+     def print_symbols(symbols):
+         for addr, size, sym in symbols:
+             print('%x %d %s' % (addr, size, sym))
+ 
+     symbols = sorted(symbols)

+ 5699 - 0
mozilla-release/patches/1517077-66a1.patch

@@ -0,0 +1,5699 @@
+# HG changeset patch
+# User Jeff Muizelaar <jrmuizel@gmail.com>
+# Date 1546276838 18000
+# Node ID 1d586f7cf0c599b0152964b7bfd23f866547b4de
+# Parent  91bd06633f6b7c39a133e1c88c045d8db1a89463
+Bug 1517077. Remove Cairo D2D backend. r=lsalzman
+
+We don't use this anymore. Let's get rid of it.
+
+Differential Revision: https://phabricator.services.mozilla.com/D15557
+
+diff --git a/gfx/cairo/cairo/src/cairo-d2d-private.fx b/gfx/cairo/cairo/src/cairo-d2d-private.fx
+deleted file mode 100644
+--- a/gfx/cairo/cairo/src/cairo-d2d-private.fx
++++ /dev/null
+@@ -1,96 +0,0 @@
+-// We store vertex coordinates and the quad shape in a constant buffer, this is
+-// easy to update and allows us to use a single call to set the x, y, w, h of
+-// the quad.
+-// The QuadDesc and TexCoords both work as follows:
+-// The x component is the quad left point, the y component is the top point
+-// the z component is the width, and the w component is the height. The quad
+-// are specified in viewport coordinates, i.e. { -1.0f, 1.0f, 2.0f, -2.0f }
+-// would cover the entire viewport (which runs from <-1.0f, 1.0f> left to right
+-// and <-1.0f, 1.0f> -bottom- to top. The TexCoords desc is specified in texture
+-// space <0, 1.0f> left to right and top to bottom. The input vertices of the
+-// shader stage always form a rectangle from {0, 0} - {1, 1}
+-cbuffer cb0
+-{
+-    float4 QuadDesc;
+-    float4 TexCoords;
+-    float4 TextColor;
+-}
+-
+-struct VS_OUTPUT
+-{
+-    float4 Position : SV_Position;
+-    float2 TexCoord : TEXCOORD0;
+-};
+-
+-struct PS_OUTPUT
+-{
+-    float4 color;
+-    float4 alpha;
+-};
+-
+-Texture2D tex;
+-
+-BlendState bTextBlend
+-{
+-  AlphaToCoverageEnable = FALSE;
+-  BlendEnable[0] = TRUE;
+-  SrcBlend = Src1_Color;
+-  DestBlend = Inv_Src1_Color;
+-  BlendOp = Add;
+-  SrcBlendAlpha = Src1_Alpha;
+-  DestBlendAlpha = Inv_Src1_Alpha;
+-  BlendOpAlpha = Add;
+-  RenderTargetWriteMask[0] = 0x0F; // All
+-};
+-
+-sampler sSampler = sampler_state {
+-    Texture = tex;
+-    AddressU = Clamp;
+-    AddressV = Clamp;
+-};
+-
+-VS_OUTPUT SampleTextureVS(float3 pos : POSITION)
+-{
+-    VS_OUTPUT Output;
+-    Output.Position.w = 1.0f;
+-    Output.Position.x = pos.x * QuadDesc.z + QuadDesc.x;
+-    Output.Position.y = pos.y * QuadDesc.w + QuadDesc.y;
+-    Output.Position.z = 0;
+-    Output.TexCoord.x = pos.x * TexCoords.z + TexCoords.x;
+-    Output.TexCoord.y = pos.y * TexCoords.w + TexCoords.y;
+-    return Output;
+-}
+-
+-float4 SampleTexturePS( VS_OUTPUT In) : SV_Target
+-{
+-    return tex.Sample(sSampler, In.TexCoord);
+-};
+-
+-PS_OUTPUT SampleTextTexturePS( VS_OUTPUT In) : SV_Target
+-{
+-    PS_OUTPUT output;
+-    output.color = TextColor;
+-    output.alpha.rgba = tex.Sample(sSampler, In.TexCoord).bgrg * TextColor.a;
+-    return output;
+-};
+-
+-technique10 SampleTexture
+-{
+-    pass P0
+-    {
+-        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
+-        SetGeometryShader(NULL);
+-        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTexturePS()));
+-    }
+-}
+-
+-technique10 SampleTextTexture
+-{
+-    pass P0
+-    {
+-        SetBlendState(bTextBlend, float4( 0.0f, 0.0f, 0.0f, 0.0f ), 0xFFFFFFFF );
+-        SetVertexShader(CompileShader(vs_4_0_level_9_3, SampleTextureVS()));
+-        SetGeometryShader(NULL);
+-        SetPixelShader(CompileShader(ps_4_0_level_9_3, SampleTextTexturePS()));
+-    }
+-}
+diff --git a/gfx/cairo/cairo/src/cairo-d2d-private.h b/gfx/cairo/cairo/src/cairo-d2d-private.h
+deleted file mode 100644
+--- a/gfx/cairo/cairo/src/cairo-d2d-private.h
++++ /dev/null
+@@ -1,191 +0,0 @@
+-/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+-/* Cairo - a vector graphics library with display and print output
+- *
+- * Copyright © 2010 Mozilla Foundation
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it either under the terms of the GNU Lesser General Public
+- * License version 2.1 as published by the Free Software Foundation
+- * (the "LGPL") or, at your option, under the terms of the Mozilla
+- * Public License Version 1.1 (the "MPL"). If you do not alter this
+- * notice, a recipient may use your version of this file under either
+- * the MPL or the LGPL.
+- *
+- * You should have received a copy of the LGPL along with this library
+- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- * You should have received a copy of the MPL along with this library
+- * in the file COPYING-MPL-1.1
+- *
+- * The contents of this file are subject to the Mozilla Public License
+- * Version 1.1 (the "License"); you may not use this file except in
+- * compliance with the License. You may obtain a copy of the License at
+- * http://www.mozilla.org/MPL/
+- *
+- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+- * the specific language governing rights and limitations.
+- *
+- * The Original Code is the cairo graphics library.
+- *
+- * The Initial Developer of the Original Code is the Mozilla Foundation
+- *
+- * Contributor(s):
+- *	Bas Schouten <bschouten@mozilla.com>
+- */
+-#ifndef CAIRO_D2D_PRIVATE_H
+-#define CAIRO_D2D_PRIVATE_H
+-
+-#ifdef CAIRO_HAS_D2D_SURFACE
+-
+-#include <windows.h>
+-#include <d2d1.h>
+-#include <d3d10.h>
+-#include <dxgi.h>
+-
+-#include "cairoint.h"
+-#include "cairo-surface-clipper-private.h"
+-
+-#include "cairo-win32-refptr.h"
+-#include "cairo-d2d-private-fx.h"
+-#include "cairo-win32.h"
+-#include "cairo-list-private.h"
+-
+-/* describes the type of the currently applied clip so that we can pop it */
+-struct d2d_clip_t;
+-
+-#define MAX_OPERATORS CAIRO_OPERATOR_HSL_LUMINOSITY + 1
+-
+-struct _cairo_d2d_device
+-{
+-    cairo_device_t base;
+-
+-    HMODULE mD3D10_1;
+-    RefPtr<ID3D10Device1> mD3D10Device;
+-    RefPtr<ID3D10Effect> mSampleEffect;
+-    RefPtr<ID3D10InputLayout> mInputLayout;
+-    RefPtr<ID3D10Buffer> mQuadBuffer;
+-    RefPtr<ID3D10RasterizerState> mRasterizerState;
+-    RefPtr<ID3D10BlendState> mBlendStates[MAX_OPERATORS];
+-    /** Texture used for manual glyph rendering */
+-    RefPtr<ID3D10Texture2D> mTextTexture;
+-    RefPtr<ID3D10ShaderResourceView> mTextTextureView;
+-    int mVRAMUsage;
+-};
+-
+-const unsigned int TEXT_TEXTURE_WIDTH = 2048;
+-const unsigned int TEXT_TEXTURE_HEIGHT = 512;
+-typedef struct _cairo_d2d_device cairo_d2d_device_t;
+-
+-struct _cairo_d2d_surface {
+-    _cairo_d2d_surface() : d2d_clip(NULL), clipping(false), isDrawing(false),
+-            textRenderingState(TEXT_RENDERING_UNINITIALIZED)
+-    {
+-	_cairo_clip_init (&this->clip);
+-        cairo_list_init(&this->dependent_surfaces);
+-    }
+-    
+-    ~_cairo_d2d_surface();
+-
+-
+-    cairo_surface_t base;
+-    /* Device used by this surface 
+-     * NOTE: In upstream cairo this is in the surface base class */
+-    cairo_d2d_device_t *device;
+-
+-    /** Render target of the texture we render to */
+-    RefPtr<ID2D1RenderTarget> rt;
+-    /** Surface containing our backstore */
+-    RefPtr<ID3D10Resource> surface;
+-    /** 
+-     * Surface used to temporarily store our surface if a bitmap isn't available
+-     * straight from our render target surface.
+-     */
+-    RefPtr<ID3D10Texture2D> bufferTexture;
+-    /** Backbuffer surface hwndrt renders to (NULL if not a window surface) */
+-    RefPtr<IDXGISurface> backBuf;
+-    /** Bitmap shared with texture and rendered to by rt */
+-    RefPtr<ID2D1Bitmap> surfaceBitmap;
+-    /** Swap chain holding our backbuffer (NULL if not a window surface) */
+-    RefPtr<IDXGISwapChain> dxgiChain;
+-    /** Window handle of the window we belong to */
+-    HWND hwnd;
+-    /** Format of the surface */
+-    cairo_format_t format;
+-
+-    cairo_clip_t clip;
+-    d2d_clip_t *d2d_clip;
+-
+-
+-    /** Mask layer used by surface_mask to push opacity masks */
+-    RefPtr<ID2D1Layer> maskLayer;
+-    /**
+-     * Layer used for clipping when tiling, and also for clearing out geometries
+-     * - lazily initialized 
+-     */
+-    RefPtr<ID2D1Layer> helperLayer;
+-    /** If this layer currently is clipping, used to prevent excessive push/pops */
+-    bool clipping;
+-    /** Brush used for bitmaps */
+-    RefPtr<ID2D1BitmapBrush> bitmapBrush;
+-    /** Brush used for solid colors */
+-    RefPtr<ID2D1SolidColorBrush> solidColorBrush;
+-    /** Indicates if our render target is currently in drawing mode */
+-    bool isDrawing;
+-    /** Indicates if text rendering is initialized */
+-    enum TextRenderingState {
+-        TEXT_RENDERING_UNINITIALIZED,
+-        TEXT_RENDERING_NO_CLEARTYPE,
+-        TEXT_RENDERING_NORMAL,
+-        TEXT_RENDERING_GDI_CLASSIC
+-    };
+-    TextRenderingState textRenderingState;
+-
+-    RefPtr<ID3D10RenderTargetView> buffer_rt_view;
+-    RefPtr<ID3D10ShaderResourceView> buffer_sr_view;
+-
+-    // Other d2d surfaces which depend on this one and need to be flushed if
+-    // it is drawn to. This is required for situations where this surface is
+-    // drawn to another surface, but may be modified before the other surface
+-    // has flushed. When the flush of the other surface then happens and the
+-    // drawing command is actually executed, the contents of this surface will
+-    // no longer be what it was when the drawing command was issued.
+-    cairo_list_t dependent_surfaces;
+-    //cairo_surface_clipper_t clipper;
+-};
+-typedef struct _cairo_d2d_surface cairo_d2d_surface_t;
+-
+-struct _cairo_d2d_surface_entry
+-{
+-    cairo_list_t link;
+-    cairo_d2d_surface_t *surface;
+-};
+-
+-typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
+-    D2D1_FACTORY_TYPE factoryType,
+-    REFIID iid,
+-    CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
+-    void **factory
+-);
+-
+-typedef HRESULT (WINAPI*D3D10CreateDevice1Func)(
+-  IDXGIAdapter *pAdapter,
+-  D3D10_DRIVER_TYPE DriverType,
+-  HMODULE Software,
+-  UINT Flags,
+-  D3D10_FEATURE_LEVEL1 HardwareLevel,
+-  UINT SDKVersion,
+-  ID3D10Device1 **ppDevice
+-);
+-
+-typedef HRESULT (WINAPI*D3D10CreateEffectFromMemoryFunc)(
+-    void *pData,
+-    SIZE_T DataLength,
+-    UINT FXFlags,
+-    ID3D10Device *pDevice, 
+-    ID3D10EffectPool *pEffectPool,
+-    ID3D10Effect **ppEffect
+-);
+-
+-#endif /* CAIRO_HAS_D2D_SURFACE */
+-#endif /* CAIRO_D2D_PRIVATE_H */
+diff --git a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
+deleted file mode 100644
+--- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
++++ /dev/null
+@@ -1,4864 +0,0 @@
+-/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
+-/* Cairo - a vector graphics library with display and print output
+- *
+- * Copyright © 2010 Mozilla Foundation
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it either under the terms of the GNU Lesser General Public
+- * License version 2.1 as published by the Free Software Foundation
+- * (the "LGPL") or, at your option, under the terms of the Mozilla
+- * Public License Version 1.1 (the "MPL"). If you do not alter this
+- * notice, a recipient may use your version of this file under either
+- * the MPL or the LGPL.
+- *
+- * You should have received a copy of the LGPL along with this library
+- * in the file COPYING-LGPL-2.1; if not, write to the Free Software
+- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+- * You should have received a copy of the MPL along with this library
+- * in the file COPYING-MPL-1.1
+- *
+- * The contents of this file are subject to the Mozilla Public License
+- * Version 1.1 (the "License"); you may not use this file except in
+- * compliance with the License. You may obtain a copy of the License at
+- * http://www.mozilla.org/MPL/
+- *
+- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
+- * OF ANY KIND, either express or implied. See the LGPL or the MPL for
+- * the specific language governing rights and limitations.
+- *
+- * The Original Code is the cairo graphics library.
+- *
+- * The Initial Developer of the Original Code is the Mozilla Foundation
+- *
+- * Contributor(s):
+- *	Bas Schouten <bschouten@mozilla.com>
+- */
+-#define INITGUID
+-
+-#include "cairoint.h"
+-#include "cairo-d2d-private.h"
+-#include "cairo-dwrite-private.h"
+-
+-#include "cairo-win32.h"
+-#include "cairo-analysis-surface-private.h"
+-#include "cairo-error-private.h"
+-
+-// Required for using placement new.
+-#include <new>
+-
+-#include "d2d1_1.h"
+-
+-#define CAIRO_INT_STATUS_SUCCESS (cairo_int_status_t)CAIRO_STATUS_SUCCESS
+-
+-struct Vertex
+-{
+-    float position[2];
+-};
+-
+-// This factory is not device dependent, we can store it. But will clear it
+-// if there are no devices left needing it.
+-static ID2D1Factory *sD2DFactory = NULL;
+-static HMODULE sD2DModule;
+-
+-static void
+-_cairo_d2d_release_factory()
+-{
+-    int refcnt = sD2DFactory->Release();
+-    if (!refcnt) {
+-	// Once the last reference goes, free the library.
+-	sD2DFactory = NULL;
+-	FreeLibrary(sD2DModule);
+-    }
+-}
+-
+-/**
+- * Set a blending mode for an operator. This will also return a boolean that
+- * reports if for this blend mode the entire surface needs to be blended. This
+- * is true whenever the DEST blend is not ONE when src alpha is 0.
+- */
+-static cairo_int_status_t
+-_cairo_d2d_set_operator(cairo_d2d_device_t *device,
+-			cairo_operator_t op)
+-{
+-    assert(op < MAX_OPERATORS);
+-    if (op >= MAX_OPERATORS) {
+-	// Eep! Someone forgot to update MAX_OPERATORS probably.
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    if (device->mBlendStates[static_cast<size_t>(op)]) {
+-	device->mD3D10Device->OMSetBlendState(device->mBlendStates[op], NULL, 0xffffffff);
+-	return CAIRO_INT_STATUS_SUCCESS;
+-    }
+-
+-    D3D10_BLEND_DESC desc;
+-    memset(&desc, 0, sizeof(desc));
+-    desc.BlendEnable[0] = TRUE;
+-    desc.AlphaToCoverageEnable = FALSE;
+-    desc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;
+-
+-    switch (op) {
+-	case CAIRO_OPERATOR_OVER:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ONE;
+-	    break;
+-	case CAIRO_OPERATOR_ADD:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ONE;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ONE;
+-	    break;
+-	case CAIRO_OPERATOR_IN:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ZERO;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_DEST_ALPHA;
+-	    break;
+-	case CAIRO_OPERATOR_OUT:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ZERO;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_INV_DEST_ALPHA;
+-	    break;
+-	case CAIRO_OPERATOR_ATOP:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_DEST_ALPHA;
+-	    break;
+-	case CAIRO_OPERATOR_DEST:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ONE;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ZERO;
+-	    break;
+-	case CAIRO_OPERATOR_DEST_OVER:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_ONE;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_INV_DEST_ALPHA;
+-	    break;
+-	case CAIRO_OPERATOR_DEST_IN:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_SRC_ALPHA;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ZERO;
+-	    break;
+-	case CAIRO_OPERATOR_DEST_OUT:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_ZERO;
+-	    break;
+-	case CAIRO_OPERATOR_DEST_ATOP:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_SRC_ALPHA;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_INV_DEST_ALPHA;
+-	    break;
+-	case CAIRO_OPERATOR_XOR:
+-	    desc.BlendOp = desc.BlendOpAlpha = D3D10_BLEND_OP_ADD;
+-	    desc.DestBlend = desc.DestBlendAlpha = D3D10_BLEND_INV_SRC_ALPHA;
+-	    desc.SrcBlend = desc.SrcBlendAlpha = D3D10_BLEND_INV_DEST_ALPHA;
+-	    break;
+-	default:
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-    };
+-    device->mD3D10Device->CreateBlendState(&desc, &device->mBlendStates[op]);
+-
+-    device->mD3D10Device->OMSetBlendState(device->mBlendStates[op], NULL, 0xffffffff);
+-    return CAIRO_INT_STATUS_SUCCESS;
+-}
+-
+-cairo_device_t *
+-cairo_d2d_create_device_from_d3d10device(ID3D10Device1 *d3d10device)
+-{
+-    HRESULT hr;
+-    D3D10_RASTERIZER_DESC rastDesc;
+-    D3D10_INPUT_ELEMENT_DESC layout[] =
+-    {
+-	{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D10_INPUT_PER_VERTEX_DATA, 0 },
+-    };
+-    D3D10_PASS_DESC passDesc;
+-    ID3D10EffectTechnique *technique;
+-    Vertex vertices[] = { {{0.0, 0.0}}, {{1.0, 0.0}}, {{0.0, 1.0}}, {{1.0, 1.0}} };
+-    CD3D10_BUFFER_DESC bufferDesc(sizeof(vertices), D3D10_BIND_VERTEX_BUFFER);
+-    D3D10_SUBRESOURCE_DATA data;
+-    CD3D10_TEXTURE2D_DESC textDesc(DXGI_FORMAT_B8G8R8A8_UNORM,
+-				   TEXT_TEXTURE_WIDTH,
+-				   TEXT_TEXTURE_HEIGHT,
+-				   1, 1);
+-
+-    cairo_d2d_device_t *device = new cairo_d2d_device_t;
+-
+-    device->mD3D10Device = d3d10device;
+-
+-    device->mD3D10_1 = LoadLibraryA("d3d10_1.dll");
+-    D3D10CreateEffectFromMemoryFunc createEffect = (D3D10CreateEffectFromMemoryFunc)
+-	GetProcAddress(device->mD3D10_1, "D3D10CreateEffectFromMemory");
+-    D2D1CreateFactoryFunc createD2DFactory;
+-
+-    if (!createEffect) {
+-	goto FAILED;
+-    }
+-
+-    if (!sD2DFactory) {
+-	sD2DModule = LoadLibraryW(L"d2d1.dll");
+-	createD2DFactory = (D2D1CreateFactoryFunc)
+-	    GetProcAddress(sD2DModule, "D2D1CreateFactory");
+-	if (!createD2DFactory) {
+-	    goto FAILED;
+-	}
+-	D2D1_FACTORY_OPTIONS options;
+-#ifdef DEBUG
+-	options.debugLevel = D2D1_DEBUG_LEVEL_INFORMATION;
+-#else
+-	options.debugLevel = D2D1_DEBUG_LEVEL_NONE;
+-#endif
+-	hr = createD2DFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
+-			      __uuidof(ID2D1Factory),
+-			      &options,
+-			      (void**)&sD2DFactory);
+-	if (FAILED(hr)) {
+-	    goto FAILED;
+-	}
+-    } else {
+-	sD2DFactory->AddRef();
+-    }
+-
+-    device->mD3D10Device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_LINESTRIP);
+-    createEffect((void*)g_main, sizeof(g_main), 0, device->mD3D10Device, NULL, &device->mSampleEffect);
+-
+-    technique = device->mSampleEffect->GetTechniqueByName("SampleTexture");
+-    technique->GetPassByIndex(0)->GetDesc(&passDesc);
+-
+-
+-    hr = device->mD3D10Device->CreateInputLayout(layout,
+-						 sizeof(layout) / sizeof(D3D10_INPUT_ELEMENT_DESC),
+-						 passDesc.pIAInputSignature,
+-						 passDesc.IAInputSignatureSize,
+-						 &device->mInputLayout);
+-    if (FAILED(hr)) {
+-	goto FAILED;
+-    }
+-
+-    data.pSysMem = (void*)vertices;
+-    hr = device->mD3D10Device->CreateBuffer(&bufferDesc, &data, &device->mQuadBuffer);
+-    if (FAILED(hr)) {
+-	goto FAILED;
+-    }
+-
+-    memset(&rastDesc, 0, sizeof(rastDesc));
+-    rastDesc.CullMode = D3D10_CULL_NONE;
+-    rastDesc.FillMode = D3D10_FILL_SOLID;
+-    rastDesc.DepthClipEnable = TRUE;
+-    hr = device->mD3D10Device->CreateRasterizerState(&rastDesc, &device->mRasterizerState);
+-    if (FAILED(hr)) {
+-	goto FAILED;
+-    }
+-    device->base.refcount = 1;
+-
+-    // We start out with TEXT_TEXTURE roughly in VRAM usage.
+-    device->mVRAMUsage = TEXT_TEXTURE_WIDTH * TEXT_TEXTURE_HEIGHT * 4;
+-
+-    // We create this with USAGE_DEFAULT, our intention is to have VRAM reserved
+-    // for text usage. We actually store glyph data in STAGING textures for the
+-    // rendering pipeline to read and copy it to this VRAM texture.
+-    textDesc.Usage = D3D10_USAGE_DEFAULT;
+-    hr = device->mD3D10Device->CreateTexture2D(&textDesc, NULL, &device->mTextTexture);
+-    if (FAILED(hr)) {
+-	goto FAILED;
+-    }
+-
+-    hr = device->mD3D10Device->CreateShaderResourceView(device->mTextTexture,
+-							NULL,
+-							&device->mTextTextureView);
+-
+-    return &device->base;
+-FAILED:
+-    delete &device->base;
+-    return NULL;
+-}
+-
+-cairo_device_t *
+-cairo_d2d_create_device()
+-{
+-    HMODULE d3d10module = LoadLibraryA("d3d10_1.dll");
+-    D3D10CreateDevice1Func createD3DDevice = (D3D10CreateDevice1Func)
+-	GetProcAddress(d3d10module, "D3D10CreateDevice1");
+-
+-    if (!createD3DDevice) {
+-	return NULL;
+-    }
+-
+-    RefPtr<ID3D10Device1> d3ddevice;
+-
+-    /**
+-     * On usage of D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS:
+-     * documentation on D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS
+-     * can be misleading. In fact, that flag gives no such indication. I pointed this
+-     * out to Bas in my email. However, Microsoft is in fact using this flag to
+-     * indicate "light weight" DX applications. By light weight they are essentially
+-     * referring to applications that are not games. The idea is that when you create
+-     * a DX game, the driver assumes that you will pretty much have a single instance
+-     * and therefore it doesn't try to hold back when it comes to GPU resource
+-     * allocation as long as it can crank out performance. In other words, the
+-     * priority in regular DX applications is to make that one application run as fast
+-     * as you can. For "light weight" applications, including D2D applications, the
+-     * priorities are a bit different. Now you are no longer going to have a single
+-     * (or very few) instances. You can have a lot of them (say, for example, a
+-     * separate DX context/device per browser tab). In such cases, the GPU resource
+-     * allocation scheme changes.
+-     */
+-    HRESULT hr = createD3DDevice(
+-	NULL, 
+-	D3D10_DRIVER_TYPE_HARDWARE,
+-	NULL,
+-	D3D10_CREATE_DEVICE_BGRA_SUPPORT |
+-	D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
+-	D3D10_FEATURE_LEVEL_10_1,
+-	D3D10_1_SDK_VERSION,
+-	&d3ddevice);
+-    if (FAILED(hr)) {
+-	hr = createD3DDevice(
+-	    NULL, 
+-	    D3D10_DRIVER_TYPE_HARDWARE,
+-	    NULL,
+-	    D3D10_CREATE_DEVICE_BGRA_SUPPORT |
+-	    D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
+-	    D3D10_FEATURE_LEVEL_10_0,
+-	    D3D10_1_SDK_VERSION,
+-	    &d3ddevice);
+-	if (FAILED(hr)) {
+-	    /* This is not guaranteed to be too fast! */
+-	    hr = createD3DDevice(
+-		NULL, 
+-		D3D10_DRIVER_TYPE_HARDWARE,
+-		NULL,
+-		D3D10_CREATE_DEVICE_BGRA_SUPPORT |
+-		D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
+-		D3D10_FEATURE_LEVEL_9_3,
+-		D3D10_1_SDK_VERSION,
+-		&d3ddevice);
+-
+-	}
+-    }
+-    if (FAILED(hr)) {
+-	return NULL;
+-    }
+-
+-    cairo_device_t *device = cairo_d2d_create_device_from_d3d10device(d3ddevice);
+-
+-    // Free our reference to the modules. The created device should have its own.
+-    FreeLibrary(d3d10module);
+-    return device;
+-}
+-
+-int
+-cairo_release_device(cairo_device_t *device)
+-{
+-    int newrefcnt = --device->refcount;
+-    if (!newrefcnt) {
+-	// Call the correct destructor
+-	cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
+-	HMODULE d3d10_1 = d2d_device->mD3D10_1;
+-	delete d2d_device;
+-	_cairo_d2d_release_factory();
+-	FreeLibrary(d3d10_1);
+-    }
+-    return newrefcnt;
+-}
+-
+-int
+-cairo_addref_device(cairo_device_t *device)
+-{
+-    return ++device->refcount;
+-}
+-
+-void
+-cairo_d2d_finish_device(cairo_device_t *device)
+-{
+-    cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
+-    // Here it becomes interesting, this flush method is generally called when
+-    // interop is going on between our device and another device. The
+-    // synchronisation between these devices is not always that great. The
+-    // device flush method may flush the device's command queue, but it gives
+-    // no guarantee that the device will actually be done with those commands,
+-    // and so the surface may still not be complete when the external device
+-    // chooses to use it. The EVENT query will actually tell us when the GPU
+-    // is completely done with our commands.
+-    D3D10_QUERY_DESC queryDesc;
+-    queryDesc.MiscFlags = 0;
+-    queryDesc.Query = D3D10_QUERY_EVENT;
+-    RefPtr<ID3D10Query> query;
+-
+-    d2d_device->mD3D10Device->CreateQuery(&queryDesc, &query);
+-
+-    // QUERY_EVENT does not use Begin(). It's disabled.
+-    query->End();
+-
+-    BOOL done = FALSE;
+-    while (!done) {
+-	// This will return S_OK and done = FALSE when the GPU is not done, and
+-	// S_OK and done = TRUE when the GPU is done. Any other return value
+-	// means we need to break out or risk an infinite loop.
+-	if (FAILED(query->GetData(&done, sizeof(BOOL), 0))) {
+-	    break;
+-	}
+-	if (FAILED(d2d_device->mD3D10Device->GetDeviceRemovedReason())) {
+-	    break;
+-	}
+-    }
+-}
+-
+-ID3D10Device1*
+-cairo_d2d_device_get_device(cairo_device_t *device)
+-{
+-    cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
+-    return d2d_device->mD3D10Device;  
+-}
+-
+-static void
+-_cairo_d2d_setup_for_blend(cairo_d2d_device_t *device)
+-{
+-    device->mD3D10Device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+-    device->mD3D10Device->IASetInputLayout(device->mInputLayout);
+-
+-    UINT stride = sizeof(Vertex);
+-    UINT offset = 0;
+-    ID3D10Buffer *buff = device->mQuadBuffer;
+-    device->mD3D10Device->IASetVertexBuffers(0, 1, &buff, &stride, &offset);
+-
+-    device->mD3D10Device->RSSetState(device->mRasterizerState);
+-}
+-
+-// Contains our cache usage - perhaps this should be made threadsafe.
+-static int cache_usage = 0;
+-
+-/**
+- * Create a similar surface which will blend effectively to
+- * another surface. For D2D, this will create another texture.
+- * Within the types we use blending is always easy.
+- *
+- * \param surface Surface this needs to be similar to
+- * \param content Content type of the new surface
+- * \param width Width of the new surface
+- * \param height Height of the new surface
+- * \return New surface
+- */
+-static cairo_surface_t*
+-_cairo_d2d_create_similar(void			*surface,
+-			  cairo_content_t	 content,
+-			  int			 width,
+-			  int			 height);
+-
+-/**
+- * Release all the data held by a surface, the surface structure
+- * itsself will be freed by cairo.
+- *
+- * \param surface Surface to clean up
+- */
+-static cairo_status_t
+-_cairo_d2d_finish(void	    *surface);
+-
+-/**
+- * Get a read-only image surface that contains the pixel data
+- * of a D2D surface.
+- *
+- * \param abstract_surface D2D surface to acquire the image from
+- * \param image_out Pointer to where we should store the image surface pointer
+- * \param image_extra Pointer where to store extra data we want to know about
+- * at the point of release.
+- * \return CAIRO_STATUS_SUCCESS for success
+- */
+-static cairo_status_t
+-_cairo_d2d_acquire_source_image(void                    *abstract_surface,
+-				cairo_image_surface_t  **image_out,
+-				void                   **image_extra);
+-
+-/**
+- * Release a read-only image surface that was obtained using acquire_source_image
+- *
+- * \param abstract_surface D2D surface to acquire the image from
+- * \param image_out Pointer to where we should store the image surface pointer
+- * \param image_extra Pointer where to store extra data we want to know about
+- * at the point of release.
+- * \return CAIRO_STATUS_SUCCESS for success
+- */
+-static void
+-_cairo_d2d_release_source_image(void                   *abstract_surface,
+-				cairo_image_surface_t  *image,
+-				void                   *image_extra);
+-
+-/**
+- * Get a read-write image surface that contains the pixel data
+- * of a D2D surface.
+- *
+- * \param abstract_surface D2D surface to acquire the image from
+- * \param image_out Pointer to where we should store the image surface pointer
+- * \param image_extra Pointer where to store extra data we want to know about
+- * at the point of release.
+- * \return CAIRO_STATUS_SUCCESS for success
+- */
+-static cairo_status_t
+-_cairo_d2d_acquire_dest_image(void                    *abstract_surface,
+-			      cairo_rectangle_int_t   *interest_rect,
+-			      cairo_image_surface_t  **image_out,
+-			      cairo_rectangle_int_t   *image_rect,
+-			      void                   **image_extra);
+-
+-/**
+- * Release a read-write image surface that was obtained using acquire_source_image
+- *
+- * \param abstract_surface D2D surface to acquire the image from
+- * \param image_out Pointer to where we should store the image surface pointer
+- * \param image_extra Pointer where to store extra data we want to know about
+- * at the point of release.
+- * \return CAIRO_STATUS_SUCCESS for success
+- */
+-static void
+-_cairo_d2d_release_dest_image(void                    *abstract_surface,
+-			      cairo_rectangle_int_t   *interest_rect,
+-			      cairo_image_surface_t   *image,
+-			      cairo_rectangle_int_t   *image_rect,
+-			      void                    *image_extra);
+-
+-/**
+- * Flush this surface, only after this operation is the related hardware texture
+- * guaranteed to contain all the results of the executed drawing operations.
+- *
+- * \param surface D2D surface to flush
+- * \return CAIRO_STATUS_SUCCESS or CAIRO_SURFACE_TYPE_MISMATCH
+- */
+-static cairo_status_t
+-_cairo_d2d_flush(void                  *surface);
+-
+-/**
+- * Fill a path on this D2D surface.
+- *
+- * \param surface The surface to apply this operation to, must be
+- * a D2D surface
+- * \param op The operator to use
+- * \param source The source pattern to fill this path with
+- * \param path The path to fill
+- * \param fill_rule The fill rule to uses on the path
+- * \param tolerance The tolerance applied to the filling
+- * \param antialias The anti-alias mode to use
+- * \param clip The clip of this operation
+- * \return Return code, this can be CAIRO_ERROR_SURFACE_TYPE_MISMATCH,
+- * CAIRO_INT_STATUS_UNSUPPORTED or CAIRO_STATUS_SUCCESS
+- */
+-static cairo_int_status_t
+-_cairo_d2d_fill(void			*surface,
+-		cairo_operator_t	 op,
+-		const cairo_pattern_t	*source,
+-		cairo_path_fixed_t	*path,
+-		cairo_fill_rule_t	 fill_rule,
+-		double			 tolerance,
+-		cairo_antialias_t	 antialias,
+-		cairo_clip_t		*clip);
+-
+-/**
+- * Paint this surface, applying the operation to the entire surface
+- *
+- * \param surface The surface to apply this operation to, must be
+- * a D2D surface
+- * \param op Operator to use when painting
+- * \param source The pattern to fill this surface with, source of the op
+- * \param clip The clip of this operation
+- * \return Return code, this can be CAIRO_ERROR_SURFACE_TYPE_MISMATCH,
+- * CAIRO_INT_STATUS_UNSUPPORTED or CAIRO_STATUS_SUCCESS
+- */
+-static cairo_int_status_t
+-_cairo_d2d_paint(void			*surface,
+-		 cairo_operator_t	 op,
+-		 const cairo_pattern_t	*source,
+-		 cairo_clip_t		*clip);
+-
+-/**
+- * Paint something on the surface applying a certain mask to that
+- * source.
+- *
+- * \param surface The surface to apply this oepration to, must be
+- * a D2D surface
+- * \param op Operator to use
+- * \param source Source for this operation
+- * \param mask Pattern to mask source with
+- * \param clip The clip of this operation
+- * \return Return code, this can be CAIRO_ERROR_SURFACE_TYPE_MISMATCH,
+- * CAIRO_INT_STATUS_UNSUPPORTED or CAIRO_STATUS_SUCCESS
+- */
+-static cairo_int_status_t
+-_cairo_d2d_mask(void			*surface,
+-		cairo_operator_t	 op,
+-		const cairo_pattern_t	*source,
+-		const cairo_pattern_t	*mask,
+-		cairo_clip_t		*clip);
+-
+-/**
+- * Show a glyph run on the target D2D surface.
+- *
+- * \param surface The surface to apply this oepration to, must be
+- * a D2D surface
+- * \param op Operator to use
+- * \param source Source for this operation
+- * \param glyphs Glyphs to draw
+- * \param num_gluphs Amount of glyphs stored at glyphs
+- * \param scaled_font Scaled font to draw
+- * \param remaining_glyphs Pointer to store amount of glyphs still
+- * requiring drawing.
+- * \param clip The clip of this operation
+- * \return CAIRO_ERROR_SURFACE_TYPE_MISMATCH, CAIRO_ERROR_FONT_TYPE_MISMATCH,
+- * CAIRO_INT_STATUS_UNSUPPORTED or CAIRO_STATUS_SUCCESS
+- */
+-static cairo_int_status_t
+-_cairo_d2d_show_glyphs (void			*surface,
+-			cairo_operator_t	 op,
+-			const cairo_pattern_t	*source,
+-			cairo_glyph_t		*glyphs,
+-			int			 num_glyphs,
+-			cairo_scaled_font_t	*scaled_font,
+-			cairo_clip_t		*clip,
+-			int			*remaining_glyphs);
+-
+-/**
+- * Get the extents of this surface.
+- *
+- * \param surface D2D surface to get the extents for
+- * \param extents Pointer to where to store the extents
+- * \param CAIRO_ERROR_SURFACE_TYPE_MISTMATCH or CAIRO_STATUS_SUCCESS
+- */
+-static cairo_bool_t
+-_cairo_d2d_getextents(void		       *surface,
+-		      cairo_rectangle_int_t    *extents);
+-
+-
+-/**
+- * Stroke a path on this D2D surface.
+- *
+- * \param surface The surface to apply this operation to, must be
+- * a D2D surface
+- * \param op The operator to use
+- * \param source The source pattern to fill this path with
+- * \param path The path to stroke
+- * \param style The style of the stroke
+- * \param ctm A logical to device matrix, since the path might be in
+- * device space the miter angle and such are not, hence we need to
+- * be aware of the transformation to apply correct stroking.
+- * \param ctm_inverse Inverse of ctm, used to transform the path back
+- * to logical space.
+- * \param tolerance Tolerance to stroke with
+- * \param antialias Antialias mode to use
+- * \param clip The clip of this operation
+- * \return Return code, this can be CAIRO_ERROR_SURFACE_TYPE_MISMATCH,
+- * CAIRO_INT_STATUS_UNSUPPORTED or CAIRO_STATUS_SUCCESS
+- */
+-static cairo_int_status_t
+-_cairo_d2d_stroke(void			*surface,
+-		  cairo_operator_t	 op,
+-		  const cairo_pattern_t	*source,
+-		  cairo_path_fixed_t	*path,
+-		  const cairo_stroke_style_t	*style,
+-		  const cairo_matrix_t	*ctm,
+-		  const cairo_matrix_t	*ctm_inverse,
+-		  double		 tolerance,
+-		  cairo_antialias_t	 antialias,
+-		  cairo_clip_t		*clip);
+-
+-static const cairo_surface_backend_t cairo_d2d_surface_backend = {
+-    CAIRO_SURFACE_TYPE_D2D,
+-    _cairo_d2d_create_similar, /* create_similar */
+-    _cairo_d2d_finish, /* finish */
+-    _cairo_d2d_acquire_source_image, /* acquire_source_image */
+-    _cairo_d2d_release_source_image, /* release_source_image */
+-    _cairo_d2d_acquire_dest_image, /* acquire_dest_image */
+-    _cairo_d2d_release_dest_image, /* release_dest_image */
+-    NULL, /* clone_similar */
+-    NULL, /* composite */
+-    NULL, /* fill_rectangles */
+-    NULL, /* composite_trapezoids */
+-    NULL, /* create_span_renderer */
+-    NULL, /* check_span_renderer */
+-    NULL, /* copy_page */
+-    NULL, /* show_page */
+-    _cairo_d2d_getextents, /* get_extents */
+-    NULL, /* old_show_glyphs */
+-    NULL, /* get_font_options */
+-    _cairo_d2d_flush, /* flush */
+-    NULL, /* mark_dirty_rectangle */
+-    NULL, /* scaled_font_fini */
+-    NULL, /* scaled_glyph_fini */
+-    _cairo_d2d_paint, /* paint */
+-    _cairo_d2d_mask, /* mask */
+-    _cairo_d2d_stroke, /* stroke */
+-    _cairo_d2d_fill, /* fill */
+-    _cairo_d2d_show_glyphs, /* show_glyphs */
+-    NULL, /* snapshot */
+-    NULL
+-};
+-
+-/*
+- * Helper functions.
+- */
+-
+-/* Stack-based helper to manage region destruction. */
+-struct cairo_region_auto_ptr
+-{
+-    cairo_region_auto_ptr() : region(NULL)
+-    { }
+-    cairo_region_auto_ptr(cairo_region_t *in_region) : region(in_region)
+-    { }
+-
+-    void set(cairo_region_t *in_region) { region = in_region; }
+-
+-    ~cairo_region_auto_ptr() { if (region) cairo_region_destroy (region); }
+-
+-    cairo_region_t *region;
+-};
+-
+-/* This clears a new D2D surface in case the VRAM was reused from an existing surface
+- * and is therefor not empty, this must be called outside of drawing state! */
+-static void
+-_d2d_clear_surface(cairo_d2d_surface_t *surf)
+-{
+-    surf->rt->BeginDraw();
+-    surf->rt->Clear(D2D1::ColorF(0, 0));
+-    surf->rt->EndDraw();
+-}
+-
+-static cairo_rectangle_int_t
+-_cairo_rect_from_windows_rect(const RECT *rect)
+-{
+-    cairo_rectangle_int_t new_rect;
+-
+-    new_rect.x = rect->left;
+-    new_rect.y = rect->top;
+-    new_rect.width = rect->right - rect->left;
+-    new_rect.height = rect->bottom - rect->top;
+-
+-    return new_rect;
+-}
+-
+-static D2D1_POINT_2F
+-_d2d_point_from_cairo_point(const cairo_point_t *point)
+-{
+-    return D2D1::Point2F(_cairo_fixed_to_float(point->x),
+-			 _cairo_fixed_to_float(point->y));
+-}
+-
+-static D2D1_COLOR_F
+-_cairo_d2d_color_from_cairo_color(const cairo_color_t &color)
+-{
+-    return D2D1::ColorF((FLOAT)color.red, 
+-			(FLOAT)color.green, 
+-			(FLOAT)color.blue,
+-			(FLOAT)color.alpha);
+-}
+-
+-static void
+-_cairo_d2d_round_out_to_int_rect(cairo_rectangle_int_t *rect, double x1, double y1, double x2, double y2)
+-{
+-    rect->x = (int)floor(x1);
+-    rect->y = (int)floor(y1);
+-    rect->width = (int)ceil(x2) - rect->x;
+-    rect->height = (int)ceil(y2) - rect->y;    
+-}
+-
+-static int
+-_cairo_d2d_compute_surface_mem_size(cairo_d2d_surface_t *surface)
+-{
+-    int size = surface->rt->GetPixelSize().width * surface->rt->GetPixelSize().height;
+-    size *= surface->rt->GetPixelFormat().format == DXGI_FORMAT_A8_UNORM ? 1 : 4;
+-    return size;
+-}
+-
+-static D2D1_COLOR_F
+-_cairo_d2d_color_from_cairo_color_stop(const cairo_color_stop_t &color)
+-{
+-    return D2D1::ColorF((FLOAT)color.red, 
+-			(FLOAT)color.green, 
+-			(FLOAT)color.blue,
+-			(FLOAT)color.alpha);
+-}
+-
+-
+-/**
+- * Gets the surface buffer texture for window surfaces whose backbuffer
+- * is not directly usable as a bitmap.
+- *
+- * \param surface D2D surface.
+- * \return Buffer texture
+- */
+-static ID3D10Texture2D*
+-_cairo_d2d_get_buffer_texture(cairo_d2d_surface_t *surface) 
+-{
+-    if (!surface->bufferTexture) {
+-	RefPtr<IDXGISurface> surf;
+-	DXGI_SURFACE_DESC surfDesc;
+-	surface->surface->QueryInterface(&surf);
+-	surf->GetDesc(&surfDesc);
+-	CD3D10_TEXTURE2D_DESC softDesc(surfDesc.Format, surfDesc.Width, surfDesc.Height);
+-	softDesc.MipLevels = 1;
+-	softDesc.Usage = D3D10_USAGE_DEFAULT;
+-	softDesc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+-	surface->device->mD3D10Device->CreateTexture2D(&softDesc, NULL, &surface->bufferTexture);
+-	surface->device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(surface);
+-    }
+-    return surface->bufferTexture;
+-}
+-
+-/**
+- * Ensure that the surface has an up-to-date surface bitmap. Used for
+- * window surfaces which cannot have a surface bitmap directly related
+- * to their backbuffer for some reason.
+- * You cannot create a bitmap around a backbuffer surface for reason (it will 
+- * fail with an E_INVALIDARG). Meaning they need a special texture to store 
+- * their graphical data which is wrapped by a D2D bitmap if a window surface 
+- * is ever used in a surface pattern. All other D2D surfaces use a texture as 
+- * their backing store so can have a bitmap directly.
+- *
+- * \param surface D2D surface.
+- */
+-static void _cairo_d2d_update_surface_bitmap(cairo_d2d_surface_t *d2dsurf)
+-{
+-    if (!d2dsurf->backBuf && d2dsurf->rt->GetPixelFormat().format != DXGI_FORMAT_A8_UNORM) {
+-	return;
+-    }
+-    
+-    if (!d2dsurf->surfaceBitmap) {
+-	d2dsurf->rt->CreateBitmap(d2dsurf->rt->GetPixelSize(),
+-				  D2D1::BitmapProperties(d2dsurf->rt->GetPixelFormat()),
+-				  &d2dsurf->surfaceBitmap);
+-    }
+-
+-    d2dsurf->surfaceBitmap->CopyFromRenderTarget(NULL, d2dsurf->rt, NULL);
+-}
+-
+-/**
+- * Present the backbuffer for a surface create for an HWND. This needs
+- * to be called when the owner of the original window surface wants to
+- * actually present the executed drawing operations to the screen.
+- *
+- * \param surface D2D surface.
+- */
+-void cairo_d2d_present_backbuffer(cairo_surface_t *surface)
+-{
+-    if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
+-	return;
+-    }
+-    cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
+-    _cairo_d2d_flush(d2dsurf);
+-    if (d2dsurf->dxgiChain) {
+-	d2dsurf->dxgiChain->Present(0, 0);
+-	d2dsurf->device->mD3D10Device->Flush();
+-    }
+-}
+-
+-struct d2d_clip_t
+-{
+-    enum clip_type {LAYER, AXIS_ALIGNED_CLIP};
+-    d2d_clip_t * const prev;
+-    const enum clip_type type;
+-    d2d_clip_t(d2d_clip_t *prev, clip_type type) : prev(prev), type(type) { }
+-};
+-
+-static RefPtr<ID2D1PathGeometry>
+-_cairo_d2d_create_path_geometry_for_path(cairo_path_fixed_t *path,
+-					 cairo_fill_rule_t fill_rule,
+-					 D2D1_FIGURE_BEGIN type);
+-
+-
+-static cairo_bool_t
+-box_is_integer (cairo_box_t *box)
+-{
+-    return _cairo_fixed_is_integer(box->p1.x) &&
+-	_cairo_fixed_is_integer(box->p1.y) &&
+-	_cairo_fixed_is_integer(box->p2.x) &&
+-	_cairo_fixed_is_integer(box->p2.y);
+-}
+-
+-static cairo_status_t
+-push_clip (cairo_d2d_surface_t *d2dsurf, cairo_clip_path_t *clip_path)
+-{
+-    cairo_box_t box;
+-    if (_cairo_path_fixed_is_box(&clip_path->path, &box)) {
+-
+-	assert(box.p1.y < box.p2.y);
+-
+-	D2D1_ANTIALIAS_MODE mode;
+-	if (box_is_integer (&box)) {
+-	    mode = D2D1_ANTIALIAS_MODE_ALIASED;
+-	} else {
+-	    mode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
+-	}
+-	d2dsurf->rt->PushAxisAlignedClip (
+-		D2D1::RectF(
+-		    _cairo_fixed_to_float(box.p1.x),
+-		    _cairo_fixed_to_float(box.p1.y),
+-		    _cairo_fixed_to_float(box.p2.x),
+-		    _cairo_fixed_to_float(box.p2.y)),
+-		mode);
+-
+-	d2dsurf->d2d_clip = new d2d_clip_t (d2dsurf->d2d_clip, d2d_clip_t::AXIS_ALIGNED_CLIP);
+-    } else {
+-	HRESULT hr;
+-	RefPtr<ID2D1PathGeometry> geom = _cairo_d2d_create_path_geometry_for_path (&clip_path->path,
+-							clip_path->fill_rule,
+-							D2D1_FIGURE_BEGIN_FILLED);
+-	RefPtr<ID2D1Layer> layer;
+-
+-	hr = d2dsurf->rt->CreateLayer (&layer);
+-
+-	D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
+-	D2D1_LAYER_OPTIONS1 options1 =  D2D1_LAYER_OPTIONS1_NONE;
+-
+-	if (d2dsurf->base.content == CAIRO_CONTENT_COLOR) {
+-	    options = D2D1_LAYER_OPTIONS_INITIALIZE_FOR_CLEARTYPE;
+-	    options1 = D2D1_LAYER_OPTIONS1_IGNORE_ALPHA;
+-	    options1 = D2D1_LAYER_OPTIONS1_INITIALIZE_FROM_BACKGROUND;
+-	}
+-
+-	RefPtr<ID2D1DeviceContext> dc;
+-	hr = d2dsurf->rt->QueryInterface(IID_ID2D1DeviceContext, (void**)&dc);
+-
+-	if (FAILED(hr)) {
+-	    d2dsurf->rt->PushLayer(D2D1::LayerParameters(
+-				       D2D1::InfiniteRect(),
+-				       geom,
+-				       D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
+-				       D2D1::IdentityMatrix(),
+-				       1.0,
+-				       0,
+-				       options),
+-				   layer);
+-	} else {
+-	    dc->PushLayer(D2D1::LayerParameters1(
+-			      D2D1::InfiniteRect(),
+-			      geom,
+-			      D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
+-			      D2D1::IdentityMatrix(),
+-			      1.0,
+-			      0,
+-			      options1),
+-			  layer);
+-	}
+-
+-	d2dsurf->d2d_clip = new d2d_clip_t(d2dsurf->d2d_clip, d2d_clip_t::LAYER);
+-   }
+-    if (!d2dsurf->d2d_clip)
+-	return _cairo_error(CAIRO_STATUS_NO_MEMORY);
+-    return CAIRO_STATUS_SUCCESS;
+-}
+-
+-static void
+-pop_clip (cairo_d2d_surface_t *d2dsurf)
+-{
+-    d2d_clip_t *current_clip = d2dsurf->d2d_clip;
+-
+-    /* pop the clip from the render target */
+-    if (current_clip->type == d2d_clip_t::LAYER) {
+-	d2dsurf->rt->PopLayer();
+-    } else if (current_clip->type == d2d_clip_t::AXIS_ALIGNED_CLIP) {
+-	d2dsurf->rt->PopAxisAlignedClip();
+-    }
+-
+-    /* pop it from our own stack */
+-    d2dsurf->d2d_clip = current_clip->prev;
+-    delete current_clip;
+-}
+-
+-/* intersect clip_paths until we reach head */
+-static cairo_status_t
+-clipper_intersect_clip_path_recursive (cairo_d2d_surface_t *d2dsurf,
+-	cairo_clip_path_t *head,
+-	cairo_clip_path_t *clip_path)
+-{
+-    cairo_status_t status;
+-
+-    if (clip_path->prev != head) {
+-	status =
+-	    clipper_intersect_clip_path_recursive (d2dsurf,
+-		    head,
+-		    clip_path->prev);
+-	if (unlikely (status))
+-	    return status;
+-    }
+-    return push_clip(d2dsurf, clip_path);
+-
+-}
+-
+-/* pop all of the clipping layers and reset the clip */
+-static void
+-reset_clip (cairo_d2d_surface_t *d2dsurf)
+-{
+-    cairo_clip_path_t *current_clip_path = d2dsurf->clip.path;
+-    while (current_clip_path != NULL) {
+-	pop_clip (d2dsurf);
+-	current_clip_path = current_clip_path->prev;
+-    }
+-
+-    _cairo_clip_reset (&d2dsurf->clip);
+-}
+-
+-/* finds the lowest common ancestor of a and b */
+-static cairo_clip_path_t *
+-find_common_ancestor(cairo_clip_path_t *a, cairo_clip_path_t *b)
+-{
+-    int a_depth = 0, b_depth = 0;
+-
+-    cairo_clip_path_t *x;
+-
+-    /* find the depths of the clip_paths */
+-    x = a;
+-    while (x) {
+-	a_depth++;
+-	x = x->prev;
+-    }
+-
+-    x = b;
+-    while (x) {
+-	b_depth++;
+-	x = x->prev;
+-    }
+-
+-    /* rewind the deeper chain to the depth of the shallowest chain */
+-    while (b_depth < a_depth && a) {
+-	a = a->prev;
+-	a_depth--;
+-    }
+-
+-    while (a_depth < b_depth && b) {
+-	b = b->prev;
+-	b_depth--;
+-    }
+-
+-    /* walk back until we find a common ancesstor */
+-
+-    /* b will be null if and only if a is null because the depths
+-     * must match at this point */
+-    while (a) {
+-	if (a == b)
+-	    return a;
+-
+-	a = a->prev;
+-	b = b->prev;
+-    }
+-
+-    /* a will be NULL */
+-    return a;
+-}
+-
+-static cairo_status_t
+-_cairo_d2d_set_clip (cairo_d2d_surface_t *d2dsurf, cairo_clip_t *clip)
+-{
+-    if (clip == NULL) {
+-	reset_clip (d2dsurf);
+-	return CAIRO_STATUS_SUCCESS;
+-    }
+-
+-    if (clip != NULL && clip->path == d2dsurf->clip.path)
+-	return CAIRO_STATUS_SUCCESS;
+-
+-    cairo_clip_path_t *current_clip_path = d2dsurf->clip.path;
+-    cairo_clip_path_t *new_clip_path = clip->path;
+-    cairo_clip_path_t *ancestor = find_common_ancestor (current_clip_path, new_clip_path);
+-
+-    /* adjust the clip to the common ancestor */
+-    while (current_clip_path != ancestor) {
+-	pop_clip (d2dsurf);
+-	current_clip_path = current_clip_path->prev;
+-    }
+-
+-    /* we now have a common parent (current_clip_path) for the clip */
+-
+-    /* replace the old clip */
+-    _cairo_clip_reset (&d2dsurf->clip);
+-    _cairo_clip_init_copy (&d2dsurf->clip, clip);
+-
+-    /* push the new clip paths up to current_clip_path */
+-    if (current_clip_path != clip->path)
+-	return clipper_intersect_clip_path_recursive (d2dsurf, current_clip_path, clip->path);
+-    else
+-	return CAIRO_STATUS_SUCCESS;
+-}
+-
+-static void _cairo_d2d_add_dependent_surface(cairo_d2d_surface_t *surf, cairo_d2d_surface_t *user)
+-{
+-    _cairo_d2d_surface_entry *entry = new _cairo_d2d_surface_entry;
+-    entry->surface = user;
+-    cairo_surface_reference(&user->base);
+-    cairo_list_add(&entry->link, &surf->dependent_surfaces);
+-};
+-
+-static void _cairo_d2d_flush_dependent_surfaces(cairo_d2d_surface_t *surf)
+-{
+-    _cairo_d2d_surface_entry *entry, *next;
+-    cairo_list_foreach_entry_safe(entry, next, _cairo_d2d_surface_entry, &surf->dependent_surfaces, link) {
+-	_cairo_d2d_flush(entry->surface);
+-	cairo_surface_destroy(&entry->surface->base);
+-	delete entry;
+-    }
+-    cairo_list_init(&surf->dependent_surfaces);
+-}
+-
+-/**
+- * Enter the state where the surface is ready for drawing. This will guarantee
+- * the surface is in the correct state, and the correct clipping area is pushed.
+- *
+- * \param surface D2D surface
+- */
+-static void _begin_draw_state(cairo_d2d_surface_t* surface)
+-{
+-    if (!surface->isDrawing) {
+-	_cairo_d2d_flush_dependent_surfaces(surface);
+-	surface->rt->BeginDraw();
+-	surface->isDrawing = true;
+-    }
+-}
+-
+-/**
+- * Get a D2D matrix from a cairo matrix. Note that D2D uses row vectors where cairo
+- * uses column vectors. Hence the transposition.
+- *
+- * \param Cairo matrix
+- * \return D2D matrix
+- */
+-static D2D1::Matrix3x2F
+-_cairo_d2d_matrix_from_matrix(const cairo_matrix_t *matrix)
+-{
+-    return D2D1::Matrix3x2F((FLOAT)matrix->xx,
+-			    (FLOAT)matrix->yx,
+-			    (FLOAT)matrix->xy,
+-			    (FLOAT)matrix->yy,
+-			    (FLOAT)matrix->x0,
+-			    (FLOAT)matrix->y0);
+-}
+-
+-/**
+- * Returns the inverse matrix for a D2D1 matrix. We cannot use the Invert function
+- * on the Matrix3x2F function class since it's statically linked and we'd have to
+- * lookup the symbol in the library. Doing this ourselves is easier.
+- *
+- * \param mat matrix
+- * \return inverse of matrix mat
+- */
+-static D2D1::Matrix3x2F
+-_cairo_d2d_invert_matrix(const D2D1::Matrix3x2F &mat)
+-{
+-    float inv_det =  (1 / mat.Determinant());
+-
+-    return D2D1::Matrix3x2F(mat._22 * inv_det,
+-			    -mat._12 * inv_det,
+-			    -mat._21 * inv_det,
+-			    mat._11 * inv_det,
+-			    (mat._21 * mat._32 - mat._22 * mat._31) * inv_det,
+-			    -(mat._11 * mat._32 - mat._12 * mat._31) * inv_det);
+-}
+-
+-/**
+- * Create a D2D stroke style interface for a cairo stroke style object. Must be
+- * released when the calling function is finished with it.
+- *
+- * \param style Cairo stroke style object
+- * \return D2D StrokeStyle interface
+- */
+-static RefPtr<ID2D1StrokeStyle>
+-_cairo_d2d_create_strokestyle_for_stroke_style(const cairo_stroke_style_t *style)
+-{
+-    D2D1_CAP_STYLE line_cap = D2D1_CAP_STYLE_FLAT;
+-    switch (style->line_cap) {
+-	case CAIRO_LINE_CAP_BUTT:
+-	    line_cap = D2D1_CAP_STYLE_FLAT;
+-	    break;
+-	case CAIRO_LINE_CAP_SQUARE:
+-	    line_cap = D2D1_CAP_STYLE_SQUARE;
+-	    break;
+-	case CAIRO_LINE_CAP_ROUND:
+-	    line_cap = D2D1_CAP_STYLE_ROUND;
+-	    break;
+-    }
+-
+-    D2D1_LINE_JOIN line_join = D2D1_LINE_JOIN_MITER;
+-    switch (style->line_join) {
+-	case CAIRO_LINE_JOIN_MITER:
+-	    line_join = D2D1_LINE_JOIN_MITER_OR_BEVEL;
+-	    break;
+-	case CAIRO_LINE_JOIN_ROUND:
+-	    line_join = D2D1_LINE_JOIN_ROUND;
+-	    break;
+-	case CAIRO_LINE_JOIN_BEVEL:
+-	    line_join = D2D1_LINE_JOIN_BEVEL;
+-	    break;
+-    }
+-
+-    FLOAT *dashes = NULL;
+-    if (style->num_dashes) {
+-	dashes = new FLOAT[style->num_dashes];
+-	for (unsigned int i = 0; i < style->num_dashes; i++) {
+-	    /* D2D seems to specify dash lengths in units of
+-	     * line width instead of the more traditional approach
+-	     * that cairo and many other APIs use where the unit
+-	     * is in pixels or someother constant unit. */
+-	    dashes[i] = (FLOAT) (style->dash[i] / style->line_width);
+-	}
+-    }
+-
+-    D2D1_DASH_STYLE dashStyle = D2D1_DASH_STYLE_SOLID;
+-    if (dashes) {
+-	dashStyle = D2D1_DASH_STYLE_CUSTOM;
+-    }
+-
+-    RefPtr<ID2D1StrokeStyle> strokeStyle;
+-    sD2DFactory->CreateStrokeStyle(D2D1::StrokeStyleProperties(line_cap, 
+-							       line_cap,
+-							       line_cap, 
+-							       line_join, 
+-							       (FLOAT)style->miter_limit,
+-							       dashStyle,
+-							       (FLOAT)style->dash_offset),
+-							       dashes,
+-							       style->num_dashes,
+-							       &strokeStyle);
+-    delete [] dashes;
+-    return strokeStyle;
+-}
+-
+-static int _d2d_compute_bitmap_mem_size(ID2D1Bitmap *bitmap)
+-{
+-    D2D1_SIZE_U size = bitmap->GetPixelSize();
+-    int bytes_per_pixel = bitmap->GetPixelFormat().format == DXGI_FORMAT_A8_UNORM ? 1 : 4;
+-    return size.width * size.height * bytes_per_pixel;
+-}
+-
+-cairo_user_data_key_t bitmap_key_nonextend;
+-cairo_user_data_key_t bitmap_key_extend;
+-cairo_user_data_key_t bitmap_key_snapshot;
+-
+-struct cached_bitmap {
+-    cached_bitmap()
+-    {
+-	sD2DFactory->AddRef();
+-    }
+-
+-    ~cached_bitmap()
+-    {
+-	// Clear bitmap out first because it depends on the factory.
+-	bitmap = NULL;
+-	_cairo_d2d_release_factory();
+-    }
+-
+-    /* Device this cached bitmap was created with, we should really have a per
+-     * device cache, see bug 607408 */
+-    cairo_d2d_device_t *device;
+-    /** The cached bitmap */
+-    RefPtr<ID2D1Bitmap> bitmap;
+-    /** The cached bitmap is dirty and needs its data refreshed */
+-    bool dirty;
+-    /** Order of snapshot detach/release bitmap called not guaranteed, single threaded refcount for now */
+-    int refs;
+-};
+-
+-/** 
+- * This is called when user data on a surface is replaced or the surface is
+- * destroyed.
+- */
+-static void _d2d_release_bitmap(void *bitmap)
+-{
+-    cached_bitmap *existingBitmap = (cached_bitmap*)bitmap;
+-    if (!--existingBitmap->refs) {
+-	cache_usage -= _d2d_compute_bitmap_mem_size(existingBitmap->bitmap);
+-	delete existingBitmap;
+-    }
+-}
+-
+-/**
+- * Via a little trick this is just used to determine when a surface has been
+- * modified.
+- */
+-static void _d2d_snapshot_detached(cairo_surface_t *surface)
+-{
+-    cached_bitmap *existingBitmap = (cached_bitmap*)cairo_surface_get_user_data(surface, &bitmap_key_snapshot);
+-    if (existingBitmap) {
+-	existingBitmap->dirty = true;
+-    }
+-    if (!--existingBitmap->refs) {
+-	cache_usage -= _d2d_compute_bitmap_mem_size(existingBitmap->bitmap);
+-	delete existingBitmap;
+-    }
+-    cairo_surface_destroy(surface);
+-}
+-
+-/**
+- * This function will calculate the part of srcSurf which will possibly be used within
+- * the boundaries of d2dsurf given the current transformation mat. This is used to
+- * determine what the minimal part of a surface is that needs to be uploaded.
+- *
+- * \param d2dsurf D2D surface
+- * \param srcSurf Source surface for operation
+- * \param mat Transformation matrix applied to source
+- */
+-static void
+-_cairo_d2d_calculate_visible_rect(cairo_d2d_surface_t *d2dsurf, cairo_image_surface_t *srcSurf,
+-				  cairo_matrix_t *mat,
+-				  int *x, int *y, unsigned int *width, unsigned int *height)
+-{
+-    /** Leave room for extend_none space, 2 pixels */
+-    UINT32 maxSize = d2dsurf->rt->GetMaximumBitmapSize() - 2;
+-
+-    /* Transform this surface to image surface space */
+-    cairo_matrix_t invMat = *mat;
+-    if (_cairo_matrix_is_invertible(mat)) {
+-	/* If this is not invertible it will be rank zero, and invMat = mat is fine */
+-	cairo_matrix_invert(&invMat);
+-    }
+-
+-    RefPtr<IDXGISurface> surf;
+-    d2dsurf->surface->QueryInterface(&surf);
+-    DXGI_SURFACE_DESC desc;
+-    surf->GetDesc(&desc);
+-
+-    double leftMost = 0;
+-    double rightMost = desc.Width;
+-    double topMost = 0;
+-    double bottomMost = desc.Height;
+-
+-    _cairo_matrix_transform_bounding_box(&invMat, &leftMost, &topMost, &rightMost, &bottomMost, NULL);
+-
+-    leftMost -= 1;
+-    topMost -= 1;
+-    rightMost += 1;
+-    bottomMost += 1;
+-
+-    /* Calculate the offsets into the source image and the width of the part required */
+-    if ((UINT32)srcSurf->width > maxSize) {
+-	*x = (int)MAX(0, floor(leftMost));
+-	/* Ensure that we get atleast 1 column of pixels as source, this will make EXTEND_PAD work */
+-	if (*x < srcSurf->width) {
+-	    *width = (unsigned int)MIN(MAX(1, ceil(rightMost - *x)), srcSurf->width - *x);
+-	} else {
+-	    *x = srcSurf->width - 1;
+-	    *width = 1;
+-	}
+-    } else {
+-	*x = 0;
+-	*width = srcSurf->width;
+-    }
+-
+-    if ((UINT32)srcSurf->height > maxSize) {
+-	*y = (int)MAX(0, floor(topMost));
+-	/* Ensure that we get atleast 1 row of pixels as source, this will make EXTEND_PAD work */
+-	if (*y < srcSurf->height) {
+-	    *height = (unsigned int)MIN(MAX(1, ceil(bottomMost - *y)), srcSurf->height - *y);
+-	} else {
+-	    *y = srcSurf->height - 1;
+-	    *height = 1;
+-	}
+-    } else {
+-	*y = 0;
+-	*height = srcSurf->height;
+-    }
+-}
+-
+-static double
+-_cairo_d2d_point_dist(const cairo_point_double_t &p1, const cairo_point_double_t &p2)
+-{
+-    return hypot(p2.x - p1.x, p2.y - p1.y);
+-}
+-
+-static void
+-_cairo_d2d_normalize_point(cairo_point_double_t *p)
+-{
+-    double length = hypot(p->x, p->y);
+-    p->x /= length;
+-    p->y /= length;
+-}
+-
+-static cairo_point_double_t
+-_cairo_d2d_subtract_point(const cairo_point_double_t &p1, const cairo_point_double_t &p2)
+-{
+-    cairo_point_double_t p = {p1.x - p2.x, p1.y - p2.y};
+-    return p;
+-}
+-
+-static double
+-_cairo_d2d_dot_product(const cairo_point_double_t &p1, const cairo_point_double_t &p2)
+-{
+-    return p1.x * p2.x + p1.y * p2.y;
+-}
+-
+-static RefPtr<ID2D1Brush>
+-_cairo_d2d_create_radial_gradient_brush(cairo_d2d_surface_t *d2dsurf,
+-					cairo_radial_pattern_t *source_pattern)
+-{
+-    cairo_matrix_t inv_mat = source_pattern->base.base.matrix;
+-    if (_cairo_matrix_is_invertible(&inv_mat)) {
+-	/* If this is not invertible it will be rank zero, and invMat = mat is fine */
+-	cairo_matrix_invert(&inv_mat);
+-    }
+-
+-    D2D1_BRUSH_PROPERTIES brushProps =
+-	D2D1::BrushProperties(1.0, _cairo_d2d_matrix_from_matrix(&inv_mat));
+-
+-    if ((source_pattern->c1.x != source_pattern->c2.x ||
+-	source_pattern->c1.y != source_pattern->c2.y) &&
+-	source_pattern->r1 != 0) {
+-	    /**
+-	     * In this particular case there's no way to deal with this!
+-	     * \todo Create an image surface with the gradient and use that.
+-	     */
+-	    return NULL;
+-    }
+-
+-    D2D_POINT_2F center =
+-	_d2d_point_from_cairo_point(&source_pattern->c2);
+-    D2D_POINT_2F origin =
+-	_d2d_point_from_cairo_point(&source_pattern->c1);
+-    origin.x -= center.x;
+-    origin.y -= center.y;
+-
+-    float outer_radius = _cairo_fixed_to_float(source_pattern->r2);
+-    float inner_radius = _cairo_fixed_to_float(source_pattern->r1);
+-    int num_stops = source_pattern->base.n_stops;
+-    D2D1_GRADIENT_STOP *stops;
+-
+-    if (source_pattern->base.base.extend == CAIRO_EXTEND_REPEAT || source_pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
+-	bool reflected = false;
+-	bool reflect = source_pattern->base.base.extend == CAIRO_EXTEND_REFLECT;
+-
+-	RefPtr<IDXGISurface> surf;
+-	d2dsurf->surface->QueryInterface(&surf);
+-	DXGI_SURFACE_DESC desc;
+-	surf->GetDesc(&desc);
+-
+-	// Calculate the largest distance the origin could be from the edge after inverse
+-	// transforming by the pattern transformation.
+-	cairo_point_double_t top_left, top_right, bottom_left, bottom_right, gradient_center;
+-	top_left.x = bottom_left.x = top_left.y = top_right.y = 0;
+-	top_right.x = bottom_right.x = desc.Width;
+-	bottom_right.y = bottom_left.y = desc.Height;
+-
+-	gradient_center.x = _cairo_fixed_to_float(source_pattern->c1.x);
+-	gradient_center.y = _cairo_fixed_to_float(source_pattern->c1.y);
+-
+-	// Transform surface corners into pattern coordinates.
+-	cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y);
+-	cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y);
+-	cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y);
+-	cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &bottom_right.y);
+-
+-	// Find the corner furthest away from the gradient center in pattern space.
+-	double largest = MAX(_cairo_d2d_point_dist(top_left, gradient_center), _cairo_d2d_point_dist(top_right, gradient_center));
+-	largest = MAX(largest, _cairo_d2d_point_dist(bottom_left, gradient_center));
+-	largest = MAX(largest, _cairo_d2d_point_dist(bottom_right, gradient_center));
+-
+-	unsigned int minSize = (unsigned int)ceil(largest);
+-
+-	// Calculate how often we need to repeat on the inside (for filling the inner radius)
+-	// and on the outside (for covering the entire surface) and create the appropriate number
+-	// of stops.
+-	float gradient_length = outer_radius - inner_radius;
+-	int inner_repeat = (int)ceil(inner_radius / gradient_length);
+-	int outer_repeat = (int)MAX(1, ceil((minSize - inner_radius) / gradient_length));
+-	num_stops *= (inner_repeat + outer_repeat);
+-	stops = new D2D1_GRADIENT_STOP[num_stops];
+-
+-	// Change outer_radius to the true outer radius after taking into account the needed
+-	// repeats.
+-	outer_radius = (inner_repeat + outer_repeat) * gradient_length;
+-
+-	float stop_scale = 1.0f / (inner_repeat + outer_repeat);
+-
+-	if (reflect) {
+-	    // We start out reflected (meaning reflected starts as false since it will
+-	    // immediately be inverted) if the inner_repeats are uneven.
+-	    reflected = !(inner_repeat & 0x1);
+-
+-	    for (int i = 0; i < num_stops; i++) {
+-		if (!(i % source_pattern->base.n_stops)) {
+-		    // Reflect here
+-		    reflected = !reflected;
+-		}
+-		// Calculate the repeat count.
+-		int repeat = i / source_pattern->base.n_stops;
+-		// Take the stop that we're using in the pattern.
+-		int stop = i % source_pattern->base.n_stops;
+-		if (reflected) {
+-		    // Take the stop from the opposite side when reflected.
+-		    stop = source_pattern->base.n_stops - stop - 1;
+-		    // When reflected take 1 - offset as the offset.
+-		    stops[i].position = (FLOAT)((repeat + 1.0f - source_pattern->base.stops[stop].offset) * stop_scale);
+-		} else {
+-		    stops[i].position = (FLOAT)((repeat + source_pattern->base.stops[stop].offset) * stop_scale);
+-		}
+-		stops[i].color =
+-		    _cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[stop].color);
+-	    }
+-	} else {
+-	    // Simple case, we don't need to reflect.
+-	    for (int i = 0; i < num_stops; i++) {
+-		// Calculate which repeat this is.
+-		int repeat = i / source_pattern->base.n_stops;
+-		// Calculate which stop this would be in the original pattern
+-		cairo_gradient_stop_t *stop = &source_pattern->base.stops[i % source_pattern->base.n_stops];
+-		stops[i].position = (FLOAT)((repeat + stop->offset) * stop_scale);
+-		stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
+-	    }
+-	}
+-    } else if (source_pattern->base.base.extend == CAIRO_EXTEND_PAD) {
+-	float offset_factor = (outer_radius - inner_radius) / outer_radius;
+-	float global_offset = inner_radius / outer_radius;
+-
+-	stops = new D2D1_GRADIENT_STOP[num_stops];
+-
+-	// If the inner radius is not 0 we need to scale and offset the stops.
+-	for (unsigned int i = 0; i < source_pattern->base.n_stops; i++) {
+-	    cairo_gradient_stop_t *stop = &source_pattern->base.stops[i];
+-	    stops[i].position = (FLOAT)(global_offset + stop->offset * offset_factor);
+-	    stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
+-	}
+-    } else if (source_pattern->base.base.extend == CAIRO_EXTEND_NONE) {
+-	float offset_factor = (outer_radius - inner_radius) / outer_radius;
+-	float global_offset = inner_radius / outer_radius;
+-
+-	num_stops++; // Add a stop on the outer radius.
+-	if (inner_radius != 0) {
+-	    num_stops++; // Add a stop on the inner radius.
+-	}
+-
+-	stops = new D2D1_GRADIENT_STOP[num_stops];
+-
+-	// If the inner radius is not 0 we need to scale and offset the stops and put a stop before the inner_radius
+-	// of a transparent color.
+-	int i = 0;
+-	if (inner_radius != 0) {
+-	    stops[i].position = global_offset;
+-	    stops[i].color = D2D1::ColorF(0, 0);
+-	    i++;
+-	}
+-	for (unsigned int j = 0; j < source_pattern->base.n_stops; j++, i++) {
+-	    cairo_gradient_stop_t *stop = &source_pattern->base.stops[j];
+-	    stops[i].position = (FLOAT)(global_offset + stop->offset * offset_factor);
+-	    stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
+-	}
+-	stops[i].position = 1.0f;
+-	stops[i].color = D2D1::ColorF(0, 0);
+-    } else {
+-	return NULL;
+-    }
+-
+-    RefPtr<ID2D1GradientStopCollection> stopCollection;
+-    d2dsurf->rt->CreateGradientStopCollection(stops, num_stops, &stopCollection);
+-    RefPtr<ID2D1RadialGradientBrush> brush;
+-
+-    d2dsurf->rt->CreateRadialGradientBrush(D2D1::RadialGradientBrushProperties(center,
+-									       origin,
+-									       outer_radius,
+-									       outer_radius),
+-					   brushProps,
+-					   stopCollection,
+-					   &brush);
+-    delete [] stops;
+-    return brush;
+-}
+-
+-static RefPtr<ID2D1Brush>
+-_cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
+-					cairo_path_fixed_t *fill_path,
+-					cairo_linear_pattern_t *source_pattern)
+-{
+-    if (source_pattern->p1.x == source_pattern->p2.x &&
+-	source_pattern->p1.y == source_pattern->p2.y) {
+-	// Cairo behavior in this situation is to draw a solid color the size of the last stop.
+-	RefPtr<ID2D1SolidColorBrush> brush;
+-	d2dsurf->rt->CreateSolidColorBrush(
+-	    _cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[source_pattern->base.n_stops - 1].color),
+-	    &brush);
+-	return brush;
+-    }
+-
+-    cairo_matrix_t inv_mat = source_pattern->base.base.matrix;
+-    /**
+-     * Cairo views this matrix as the transformation of the destination
+-     * when the pattern is imposed. We see this differently, D2D transformation
+-     * moves the pattern over the destination.
+-     */
+-    if (_cairo_matrix_is_invertible(&inv_mat)) {
+-	/* If this is not invertible it will be rank zero, and invMat = mat is fine */
+-	cairo_matrix_invert(&inv_mat);
+-    }
+-    D2D1_BRUSH_PROPERTIES brushProps =
+-	D2D1::BrushProperties(1.0, _cairo_d2d_matrix_from_matrix(&inv_mat));
+-    cairo_point_double_t p1, p2;
+-    p1.x = _cairo_fixed_to_float(source_pattern->p1.x);
+-    p1.y = _cairo_fixed_to_float(source_pattern->p1.y);
+-    p2.x = _cairo_fixed_to_float(source_pattern->p2.x);
+-    p2.y = _cairo_fixed_to_float(source_pattern->p2.y);
+-
+-    D2D1_GRADIENT_STOP *stops;
+-    int num_stops = source_pattern->base.n_stops;
+-    if (source_pattern->base.base.extend == CAIRO_EXTEND_REPEAT || source_pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
+-	// Get this when the points are not transformed yet.
+-	double gradient_length = _cairo_d2d_point_dist(p1, p2);
+-        cairo_point_double_t top_left, top_right, bottom_left, bottom_right;
+-
+-        if (fill_path) {
+-            // Calculate the repeat count needed;
+-            cairo_box_t fill_extents;
+-            _cairo_path_fixed_extents (fill_path, &fill_extents);
+-
+-	    top_left.x = bottom_left.x = _cairo_fixed_to_double (fill_extents.p1.x);
+-	    top_left.y = top_right.y = _cairo_fixed_to_double (fill_extents.p1.y);
+-	    top_right.x = bottom_right.x = _cairo_fixed_to_double (fill_extents.p2.x);
+-	    bottom_right.y = bottom_left.y = _cairo_fixed_to_double (fill_extents.p2.y);
+-        } else {
+-            RefPtr<IDXGISurface> surf;
+-            d2dsurf->surface->QueryInterface(&surf);
+-            DXGI_SURFACE_DESC desc;
+-            surf->GetDesc(&desc);
+-
+-            top_left.x = bottom_left.x = 0;
+-            top_left.y = top_right.y = 0;
+-            top_right.x = bottom_right.x = desc.Width;
+-            bottom_right.y = bottom_left.y = desc.Height;
+-        }
+-
+-	// Transform the corners of our surface to pattern space.
+-	cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y);
+-	cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y);
+-	cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y);
+-	cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &bottom_right.y);
+-
+-	cairo_point_double_t u;
+-	// Unit vector of the gradient direction.
+-	u = _cairo_d2d_subtract_point(p2, p1);
+-	_cairo_d2d_normalize_point(&u);
+-
+-	// (corner - p1) . u = |corner - p1| cos(a) where a is the angle between the two vectors.
+-	// Coincidentally |corner - p1| cos(a) is actually also the distance our gradient needs to cover since
+-	// at this point on the gradient line it will be perpendicular to the line running from the gradient
+-	// line through the corner.
+-
+-	double max_dist, min_dist;
+-	max_dist = MAX(_cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_left, p1)),
+-		       _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_right, p1)));
+-	max_dist = MAX(max_dist, _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(bottom_left, p1)));
+-	max_dist = MAX(max_dist, _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(bottom_right, p1)));
+-	min_dist = MIN(_cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_left, p1)),
+-		       _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(top_right, p1)));
+-	min_dist = MIN(min_dist, _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(bottom_left, p1)));
+-	min_dist = MIN(min_dist, _cairo_d2d_dot_product(u, _cairo_d2d_subtract_point(bottom_right, p1)));
+-
+-	min_dist = MAX(-min_dist, 0);
+-
+-	// Repeats after gradient start.
+- 	// It's possible for max_dist and min_dist to both be zero, in which case
+- 	// we'll set num_stops to 0 and crash D2D. Let's just ensure after_repeat
+- 	// is at least 1.
+- 	int after_repeat = MAX((int)ceil(max_dist / gradient_length), 1);
+-	int before_repeat = (int)ceil(min_dist / gradient_length);
+-	num_stops *= (after_repeat + before_repeat);
+-
+-	p2.x = p1.x + u.x * after_repeat * gradient_length;
+-	p2.y = p1.y + u.y * after_repeat * gradient_length;
+-	p1.x = p1.x - u.x * before_repeat * gradient_length;
+-	p1.y = p1.y - u.y * before_repeat * gradient_length;
+-
+-	float stop_scale = 1.0f / (float)(after_repeat + before_repeat);
+-
+-	stops = new D2D1_GRADIENT_STOP[num_stops];
+-	if (source_pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
+-	    // We start out reflected (meaning reflected starts as false since it will
+-	    // immediately be inverted) if the inner_repeats are uneven.
+-	    bool reflected = !(before_repeat & 0x1);
+-
+-	    for (int i = 0; i < num_stops; i++) {
+-		if (!(i % source_pattern->base.n_stops)) {
+-		    // Reflect here
+-		    reflected = !reflected;
+-		}
+-		// Calculate the repeat count.
+-		int repeat = i / source_pattern->base.n_stops;
+-		// Take the stop that we're using in the pattern.
+-		int stop = i % source_pattern->base.n_stops;
+-		if (reflected) {
+-		    // Take the stop from the opposite side when reflected.
+-		    stop = source_pattern->base.n_stops - stop - 1;
+-		    // When reflected take 1 - offset as the offset.
+-		    stops[i].position = (FLOAT)((repeat + 1.0f - source_pattern->base.stops[stop].offset) * stop_scale);
+-		} else {
+-		    stops[i].position = (FLOAT)((repeat + source_pattern->base.stops[stop].offset) * stop_scale);
+-		}
+-		stops[i].color =
+-		    _cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[stop].color);
+-	    }
+-	} else {
+-	    // Simple case, we don't need to reflect.
+-	    for (int i = 0; i < num_stops; i++) {
+-		// Calculate which repeat this is.
+-		int repeat = i / source_pattern->base.n_stops;
+-		// Calculate which stop this would be in the original pattern
+-		cairo_gradient_stop_t *stop = &source_pattern->base.stops[i % source_pattern->base.n_stops];
+-		stops[i].position = (FLOAT)((repeat + stop->offset) * stop_scale);
+-		stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
+-	    }
+-	}
+-    } else if (source_pattern->base.base.extend == CAIRO_EXTEND_PAD) {
+-	stops = new D2D1_GRADIENT_STOP[source_pattern->base.n_stops];
+-	for (unsigned int i = 0; i < source_pattern->base.n_stops; i++) {
+-	    cairo_gradient_stop_t *stop = &source_pattern->base.stops[i];
+-	    stops[i].position = (FLOAT)stop->offset;
+-	    stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
+-	}
+-    } else if (source_pattern->base.base.extend == CAIRO_EXTEND_NONE) {
+-	num_stops += 2;
+-	stops = new D2D1_GRADIENT_STOP[num_stops];
+-	stops[0].position = 0;
+-	stops[0].color = D2D1::ColorF(0, 0);
+-	for (unsigned int i = 1; i < source_pattern->base.n_stops + 1; i++) {
+-	    cairo_gradient_stop_t *stop = &source_pattern->base.stops[i - 1];
+-	    stops[i].position = (FLOAT)stop->offset;
+-	    stops[i].color = _cairo_d2d_color_from_cairo_color_stop(stop->color);
+-	}
+-	stops[source_pattern->base.n_stops + 1].position = 1.0f;
+-	stops[source_pattern->base.n_stops + 1].color = D2D1::ColorF(0, 0);
+-    }
+-    RefPtr<ID2D1GradientStopCollection> stopCollection;
+-    d2dsurf->rt->CreateGradientStopCollection(stops, num_stops, &stopCollection);
+-    RefPtr<ID2D1LinearGradientBrush> brush;
+-    d2dsurf->rt->CreateLinearGradientBrush(D2D1::LinearGradientBrushProperties(D2D1::Point2F((FLOAT)p1.x, (FLOAT)p1.y),
+-									       D2D1::Point2F((FLOAT)p2.x, (FLOAT)p2.y)),
+-					   brushProps,
+-					   stopCollection,
+-					   &brush);
+-    delete [] stops;
+-    return brush;
+-}
+-
+-/**
+- * This creates an ID2D1Brush that will fill with the correct pattern.
+- * This function passes a -strong- reference to the caller, the brush
+- * needs to be released, even if it is not unique.
+- *
+- * \param d2dsurf Surface to create a brush for
+- * \param pattern The pattern to create a brush for
+- * \param unique We cache the bitmap/color brush for speed. If this
+- * needs a brush that is unique (i.e. when more than one is needed),
+- * this will make the function return a seperate brush.
+- * \return A brush object
+- */
+-static RefPtr<ID2D1Brush>
+-_cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
+-				    cairo_path_fixed_t *fill_path,
+-				    const cairo_pattern_t *pattern,
+-				    bool unique = false)
+-{
+-    HRESULT hr;
+-
+-    if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
+-	cairo_solid_pattern_t *sourcePattern =
+-	    (cairo_solid_pattern_t*)pattern;
+-	D2D1_COLOR_F color = _cairo_d2d_color_from_cairo_color(sourcePattern->color);
+-	if (unique) {
+-	    RefPtr<ID2D1SolidColorBrush> brush;
+-	    d2dsurf->rt->CreateSolidColorBrush(color,
+-					       &brush);
+-	    return brush;
+-	} else {
+-	    if (d2dsurf->solidColorBrush->GetColor().a != color.a ||
+-		d2dsurf->solidColorBrush->GetColor().r != color.r ||
+-		d2dsurf->solidColorBrush->GetColor().g != color.g ||
+-		d2dsurf->solidColorBrush->GetColor().b != color.b) {
+-		d2dsurf->solidColorBrush->SetColor(color);
+-	    }
+-	    return d2dsurf->solidColorBrush;
+-	}
+-
+-    } else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
+-	cairo_linear_pattern_t *source_pattern =
+-	    (cairo_linear_pattern_t*)pattern;
+-	return _cairo_d2d_create_linear_gradient_brush(d2dsurf, fill_path, source_pattern);
+-    } else if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL) {
+-	cairo_radial_pattern_t *source_pattern =
+-	    (cairo_radial_pattern_t*)pattern;
+-	return _cairo_d2d_create_radial_gradient_brush(d2dsurf, source_pattern);
+-    } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
+-	cairo_matrix_t mat = pattern->matrix;
+-	cairo_matrix_invert(&mat);
+-
+-	cairo_surface_pattern_t *surfacePattern =
+-	    (cairo_surface_pattern_t*)pattern;
+-	D2D1_EXTEND_MODE extendMode;
+-
+-	cairo_user_data_key_t *key = &bitmap_key_extend;
+-
+-	if (pattern->extend == CAIRO_EXTEND_NONE) {
+-	    extendMode = D2D1_EXTEND_MODE_CLAMP;
+-	    key = &bitmap_key_nonextend;
+-	    /** 
+-	     * We create a slightly larger bitmap with a transparent border
+-	     * around it for this case. Need to translate for that.
+-	     */
+-	    cairo_matrix_translate(&mat, -1.0, -1.0);
+-	} else if (pattern->extend == CAIRO_EXTEND_REPEAT) {
+-	    extendMode = D2D1_EXTEND_MODE_WRAP;
+-	} else if (pattern->extend == CAIRO_EXTEND_REFLECT) {
+-	    extendMode = D2D1_EXTEND_MODE_MIRROR;
+-	} else {
+-	    extendMode = D2D1_EXTEND_MODE_CLAMP;
+-	}
+-
+-	RefPtr<ID2D1Bitmap> sourceBitmap;
+-	bool partial = false;
+-	int xoffset = 0;
+-	int yoffset = 0;
+-	unsigned int width;
+-	unsigned int height;
+-	unsigned char *data = NULL;
+- 	unsigned int stride = 0;
+-
+-	if (surfacePattern->surface->type == CAIRO_SURFACE_TYPE_D2D) {
+-	    /**
+-	     * \todo We need to somehow get a rectangular transparent
+-	     * border here too!!
+-	     */
+-	    cairo_d2d_surface_t *srcSurf = 
+-		reinterpret_cast<cairo_d2d_surface_t*>(surfacePattern->surface);
+-	    
+-	    if (srcSurf == d2dsurf) {
+-		/* D2D cannot deal with self-copy. We should add an optimized
+-		 * codepath for self-copy in the easy cases that does ping-pong like
+-		 * scroll does. See bug 579215. For now fallback.
+-		 */
+-		return NULL;
+-	    }
+-	    if (srcSurf->device != d2dsurf->device) {
+-		/* This code does not work if the source surface does not use
+-		 * the same device. Some work could be done to do something
+-		 * fairly efficient here, for now, fallback.
+-		 */
+-		return NULL;
+-	    }
+-
+-	    _cairo_d2d_update_surface_bitmap(srcSurf);
+-	    _cairo_d2d_flush(srcSurf);
+-
+-	    // Mark a dependency on the source surface.
+-	    _cairo_d2d_add_dependent_surface(srcSurf, d2dsurf);
+-
+-	    if (pattern->extend == CAIRO_EXTEND_NONE) {
+-		ID2D1Bitmap *srcSurfBitmap = srcSurf->surfaceBitmap;
+-		d2dsurf->rt->CreateBitmap(
+-		    D2D1::SizeU(srcSurfBitmap->GetPixelSize().width + 2,
+-				srcSurfBitmap->GetPixelSize().height + 2),
+-		    D2D1::BitmapProperties(srcSurfBitmap->GetPixelFormat()),
+-		    &sourceBitmap);
+-		D2D1_POINT_2U point = D2D1::Point2U(1, 1);
+-		sourceBitmap->CopyFromBitmap(&point, srcSurfBitmap, NULL);
+-	    } else {
+-		sourceBitmap = srcSurf->surfaceBitmap;
+-	    }
+-
+-	} else if (surfacePattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
+-	    cairo_image_surface_t *srcSurf = 
+-		reinterpret_cast<cairo_image_surface_t*>(surfacePattern->surface);
+-	    D2D1_ALPHA_MODE alpha;
+-	    if (srcSurf->format == CAIRO_FORMAT_ARGB32 ||
+-		srcSurf->format == CAIRO_FORMAT_A8) {
+-		alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
+-	    } else {
+-		alpha = D2D1_ALPHA_MODE_IGNORE;
+-	    }
+-
+-	    data = srcSurf->data;
+-	    stride = srcSurf->stride;
+-
+-	    /* This is used as a temporary surface for resampling surfaces larget than maxSize. */
+-	    pixman_image_t *pix_image = NULL;
+-
+-	    DXGI_FORMAT format;
+-	    unsigned int Bpp;
+-	    if (srcSurf->format == CAIRO_FORMAT_ARGB32) {
+-		format = DXGI_FORMAT_B8G8R8A8_UNORM;
+-		Bpp = 4;
+-	    } else if (srcSurf->format == CAIRO_FORMAT_RGB24) {
+-		format = DXGI_FORMAT_B8G8R8A8_UNORM;
+-		Bpp = 4;
+-	    } else if (srcSurf->format == CAIRO_FORMAT_A8) {
+-		format = DXGI_FORMAT_A8_UNORM;
+-		Bpp = 1;
+-	    } else {
+-		return NULL;
+-	    }
+-
+-	    /** Leave room for extend_none space, 2 pixels */
+-	    UINT32 maxSize = d2dsurf->rt->GetMaximumBitmapSize() - 2;
+-
+-	    if ((UINT32)srcSurf->width > maxSize || (UINT32)srcSurf->height > maxSize) {
+-		if (pattern->extend == CAIRO_EXTEND_REPEAT ||
+-		    pattern->extend == CAIRO_EXTEND_REFLECT) {
+-		    // XXX - we don't have code to deal with these yet.
+-		    return NULL;
+-		}
+-
+-		/* We cannot fit this image directly into a texture, start doing tricks to draw correctly anyway. */
+-		partial = true;
+-
+-		/* First we check which part of the image is inside the viewable area. */
+-  		_cairo_d2d_calculate_visible_rect(d2dsurf, srcSurf, &mat, &xoffset, &yoffset, &width, &height);
+-
+-		cairo_matrix_translate(&mat, xoffset, yoffset);
+-
+-		if (width > maxSize || height > maxSize) {
+-		    /*
+-		     * We cannot upload the required part of the surface directly, we're going to create
+-		     * a version which is downsampled to a smaller size by pixman and then uploaded.
+-		     *
+-		     * We need to size it to at least the diagonal size of this surface, in order to prevent ever
+-		     * upsampling this again when drawing it to the surface. We want the resized surface
+-		     * to be as small as possible to limit pixman required fill rate.
+-		     *
+-		     * Note this isn't necessarily perfect. Imagine having a 5x5 pixel destination and
+-		     * a 10x5 image containing a line of blackpixels, white pixels, black pixels, if you rotate
+-		     * this by 45 degrees and scale it to a size of 5x5 pixels and composite it to the destination,
+-		     * the composition will require all 10 original columns to do the best possible sampling.
+-		     */
+-		    RefPtr<IDXGISurface> surf;
+-		    d2dsurf->surface->QueryInterface(&surf);
+-		    DXGI_SURFACE_DESC desc;
+-		    surf->GetDesc(&desc);
+-
+-		    unsigned int minSize = (unsigned int)ceil(sqrt(pow((float)desc.Width, 2) + pow((float)desc.Height, 2)));
+-		    
+-		    unsigned int newWidth = MIN(minSize, MIN(width, maxSize));
+-		    unsigned int newHeight = MIN(minSize, MIN(height, maxSize));
+-		    double xRatio = (double)width / newWidth;
+-		    double yRatio = (double)height / newHeight;
+-
+-		    if (newWidth > maxSize || newHeight > maxSize) {
+-			/*
+-			 * Okay, the diagonal of our surface is big enough to require a sampling larger
+-			 * than the maximum texture size. This is where we give up.
+-			 */
+-			return NULL;
+-  		    }
+-
+-		    /* Create a temporary surface to hold the downsampled image */
+-		    pix_image = pixman_image_create_bits(srcSurf->pixman_format,
+-							 newWidth,
+-							 newHeight,
+-							 NULL,
+-							 -1);
+-
+-		    /* Set the transformation to downsample and call pixman_image_composite to downsample */
+-		    pixman_transform_t transform;
+-		    pixman_transform_init_scale(&transform, pixman_double_to_fixed(xRatio), pixman_double_to_fixed(yRatio));
+-		    pixman_transform_translate(&transform, NULL, pixman_int_to_fixed(xoffset), pixman_int_to_fixed(yoffset));
+-
+-		    pixman_image_set_transform(srcSurf->pixman_image, &transform);
+-		    pixman_image_composite(PIXMAN_OP_SRC, srcSurf->pixman_image, NULL, pix_image, 0, 0, 0, 0, 0, 0, newWidth, newHeight);
+-
+-		    /* Adjust the pattern transform to the used temporary surface */
+-		    cairo_matrix_scale(&mat, xRatio, yRatio);
+-
+-		    data = (unsigned char*)pixman_image_get_data(pix_image);
+-		    stride = pixman_image_get_stride(pix_image);
+-
+-		    /* Into this image we actually have no offset */
+-		    xoffset = 0;
+-		    yoffset = 0;
+-		    width = newWidth;
+-		    height = newHeight;
+-  		}
+-	    } else {
+-		width = srcSurf->width;
+-		height = srcSurf->height;
+-	    }
+-
+-	    cached_bitmap *cachebitmap = NULL;
+-
+-	    if (!partial) {
+-		cachebitmap = 
+-		    (cached_bitmap*)cairo_surface_get_user_data(
+-		    surfacePattern->surface,
+-		    key);
+-		if (cachebitmap && cachebitmap->device != d2dsurf->device) {
+-		    cachebitmap = NULL;
+-		}
+-	    }
+-
+-	    if (cachebitmap) {
+-		sourceBitmap = cachebitmap->bitmap;
+-		if (cachebitmap->dirty) {
+-		    D2D1_RECT_U rect;
+-		    /* No need to take partial uploading into account - partially uploaded surfaces are never cached. */
+-		    if (pattern->extend == CAIRO_EXTEND_NONE) {
+-			rect = D2D1::RectU(1, 1, srcSurf->width + 1, srcSurf->height + 1);
+-		    } else {
+-			rect = D2D1::RectU(0, 0, srcSurf->width, srcSurf->height);
+-		    }
+-		    sourceBitmap->CopyFromMemory(&rect,
+-						 srcSurf->data,
+-						 srcSurf->stride);
+-		    cairo_surface_t *nullSurf =
+-			cairo_null_surface_create(CAIRO_CONTENT_COLOR_ALPHA);
+-		    cachebitmap->refs++;
+-		    cachebitmap->dirty = false;
+-		    cairo_surface_set_user_data(nullSurf,
+-						&bitmap_key_snapshot,
+-						cachebitmap,
+-						NULL);
+-		    cairo_surface_attach_snapshot(surfacePattern->surface,
+-						   nullSurf,
+-						   _d2d_snapshot_detached);
+-		}
+-	    } else {
+-		if (pattern->extend != CAIRO_EXTEND_NONE) {
+-		    hr = d2dsurf->rt->CreateBitmap(D2D1::SizeU(width, height),
+-						   data + yoffset * stride + xoffset * Bpp,
+-						   stride,
+-						   D2D1::BitmapProperties(D2D1::PixelFormat(format,
+-											    alpha)),
+-						   &sourceBitmap);
+-
+-		    if (FAILED(hr)) {
+-			return NULL;
+-		    }
+-		} else {
+-		    /**
+-		     * Trick here, we create a temporary rectangular
+-		     * surface with 1 pixel margin on each side. This
+-		     * provides a rectangular transparent border, that
+-		     * will ensure CLAMP acts as EXTEND_NONE. Perhaps
+-		     * this could be further optimized by not memsetting
+-		     * the whole array.
+-		     */
+-		    unsigned int tmpWidth = width + 2;
+-		    unsigned int tmpHeight = height + 2;
+-		    unsigned char *tmp = new unsigned char[tmpWidth * tmpHeight * Bpp];
+-		    memset(tmp, 0, tmpWidth * tmpHeight * Bpp);
+-		    for (unsigned int y = 0; y < height; y++) {
+-			memcpy(
+-			    tmp + tmpWidth * Bpp * y + tmpWidth * Bpp + Bpp, 
+-			    data + yoffset * stride + y * stride + xoffset * Bpp, 
+-			    width * Bpp);
+-		    }
+-
+-		    hr = d2dsurf->rt->CreateBitmap(D2D1::SizeU(tmpWidth, tmpHeight),
+-						   tmp,
+-						   tmpWidth * Bpp,
+-						   D2D1::BitmapProperties(D2D1::PixelFormat(format,
+-					 						    D2D1_ALPHA_MODE_PREMULTIPLIED)),
+-						   &sourceBitmap);
+-
+-		    delete [] tmp;
+-		    if (FAILED(hr)) {
+-			return NULL;
+-		    }
+-		}
+-
+-		if (!partial) {
+-		    cached_bitmap *cachebitmap = new cached_bitmap;
+-		    /* We can cache it if it isn't a partial bitmap */
+-		    cachebitmap->dirty = false;
+-		    cachebitmap->bitmap = sourceBitmap;
+-		    cachebitmap->device = d2dsurf->device;
+-		    /*
+-		     * This will start out with two references, one on the snapshot
+-		     * and one more in the user data structure.
+-		     */
+-		    cachebitmap->refs = 2;
+-		    cairo_surface_set_user_data(surfacePattern->surface,
+-						key,
+-						cachebitmap,
+-						_d2d_release_bitmap);
+-		    cairo_surface_t *nullSurf =
+-			cairo_null_surface_create(CAIRO_CONTENT_COLOR_ALPHA);
+-		    cairo_surface_set_user_data(nullSurf,
+-						&bitmap_key_snapshot,
+-						cachebitmap,
+-						NULL);
+-		    cairo_surface_attach_snapshot(surfacePattern->surface,
+-						   nullSurf,
+-						   _d2d_snapshot_detached);
+-		    cache_usage += _d2d_compute_bitmap_mem_size(sourceBitmap);
+-		}
+-		if (pix_image) {
+-		    pixman_image_unref(pix_image);
+-  		}
+-	    }
+-	} else {
+-	    return NULL;
+-	}
+-	D2D1_BITMAP_BRUSH_PROPERTIES bitProps;
+-	
+-	if (surfacePattern->base.filter == CAIRO_FILTER_NEAREST) {
+-	    bitProps = D2D1::BitmapBrushProperties(extendMode, 
+-						   extendMode,
+-						   D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
+-	} else {
+-	    bitProps = D2D1::BitmapBrushProperties(extendMode,
+-						   extendMode,
+-						   D2D1_BITMAP_INTERPOLATION_MODE_LINEAR);
+-	}
+-	if (unique) {
+-	    RefPtr<ID2D1BitmapBrush> bitBrush;
+-	    D2D1_BRUSH_PROPERTIES brushProps =
+-		D2D1::BrushProperties(1.0, _cairo_d2d_matrix_from_matrix(&mat));
+-	    d2dsurf->rt->CreateBitmapBrush(sourceBitmap, 
+-					   &bitProps,
+-					   &brushProps,
+-					   &bitBrush);
+-	    return bitBrush;
+-	} else {
+-	    D2D1_MATRIX_3X2_F matrix = _cairo_d2d_matrix_from_matrix(&mat);
+-
+-	    if (d2dsurf->bitmapBrush) {
+-		d2dsurf->bitmapBrush->SetTransform(matrix);
+-
+-		if (surfacePattern->base.filter == CAIRO_FILTER_NEAREST) {
+-		    d2dsurf->bitmapBrush->SetInterpolationMode(D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
+-		} else {
+-		    d2dsurf->bitmapBrush->SetInterpolationMode(D2D1_BITMAP_INTERPOLATION_MODE_LINEAR);
+-		}
+-
+-		d2dsurf->bitmapBrush->SetBitmap(sourceBitmap);
+-		d2dsurf->bitmapBrush->SetExtendModeX(extendMode);
+-		d2dsurf->bitmapBrush->SetExtendModeY(extendMode);
+-	    } else {
+-		D2D1_BRUSH_PROPERTIES brushProps =
+-		    D2D1::BrushProperties(1.0, _cairo_d2d_matrix_from_matrix(&mat));
+-		d2dsurf->rt->CreateBitmapBrush(sourceBitmap,
+-					       &bitProps,
+-					       &brushProps,
+-					       &d2dsurf->bitmapBrush);
+-	    }
+-	    return d2dsurf->bitmapBrush;
+-	}
+-    } else {
+-	return NULL;
+-    }
+-}
+-
+-
+-/** Path Conversion */
+-
+-/**
+- * Structure to use for the closure, containing all needed data.
+- */
+-struct path_conversion {
+-    /** Geometry sink that we need to write to */
+-    ID2D1GeometrySink *sink;
+-    /** 
+-     * If this figure is active, cairo doesn't always send us a close. But
+-     * we do need to end this figure if it didn't.
+-     */
+-    bool figureActive;
+-    /**
+-     * Current point, D2D has no explicit move so we need to track moved for
+-     * the next begin.
+-     */
+-    cairo_point_t current_point;
+-    /** The type of figure begin for this geometry instance */
+-    D2D1_FIGURE_BEGIN type;
+-};
+-
+-static cairo_status_t
+-_cairo_d2d_path_move_to(void		 *closure,
+-			const cairo_point_t *point)
+-{
+-    path_conversion *pathConvert =
+-	static_cast<path_conversion*>(closure);
+-    if (pathConvert->figureActive) {
+-	pathConvert->sink->EndFigure(D2D1_FIGURE_END_OPEN);
+-	pathConvert->figureActive = false;
+-    }
+-
+-    pathConvert->current_point = *point;
+-    return CAIRO_STATUS_SUCCESS;
+-}
+-
+-static cairo_status_t
+-_cairo_d2d_path_line_to(void		    *closure,
+-			const cairo_point_t *point)
+-{
+-    path_conversion *pathConvert =
+-	static_cast<path_conversion*>(closure);
+-    if (!pathConvert->figureActive) {
+-	pathConvert->sink->BeginFigure(_d2d_point_from_cairo_point(&pathConvert->current_point),
+-				       pathConvert->type);
+-	pathConvert->figureActive = true;
+-    }
+-
+-    D2D1_POINT_2F d2dpoint = _d2d_point_from_cairo_point(point);
+-
+-    pathConvert->sink->AddLine(d2dpoint);
+-    return CAIRO_STATUS_SUCCESS;
+-}
+-
+-static cairo_status_t
+-_cairo_d2d_path_curve_to(void	  *closure,
+-			 const cairo_point_t *p0,
+-			 const cairo_point_t *p1,
+-			 const cairo_point_t *p2)
+-{
+-    path_conversion *pathConvert =
+-	static_cast<path_conversion*>(closure);
+-    if (!pathConvert->figureActive) {
+-	pathConvert->sink->BeginFigure(_d2d_point_from_cairo_point(&pathConvert->current_point),
+-				       D2D1_FIGURE_BEGIN_FILLED);
+-	pathConvert->figureActive = true;
+-    }
+-
+-    pathConvert->sink->AddBezier(D2D1::BezierSegment(_d2d_point_from_cairo_point(p0),
+-						     _d2d_point_from_cairo_point(p1),
+-						     _d2d_point_from_cairo_point(p2)));
+-	
+-    return CAIRO_STATUS_SUCCESS;
+-}
+-
+-static cairo_status_t
+-_cairo_d2d_path_close(void *closure)
+-{
+-    path_conversion *pathConvert =
+-	static_cast<path_conversion*>(closure);
+-
+-    if (!pathConvert->figureActive) {
+-	pathConvert->sink->BeginFigure(_d2d_point_from_cairo_point(&pathConvert->current_point),
+-				       pathConvert->type);
+-	/**
+-	 * In this case we mean a single point. For D2D this means we need to add an infinitely
+-	 * small line here to get that effect.
+-	 */
+-	pathConvert->sink->AddLine(_d2d_point_from_cairo_point(&pathConvert->current_point));
+-    }
+-
+-    pathConvert->sink->EndFigure(D2D1_FIGURE_END_CLOSED);
+-    pathConvert->figureActive = false;
+-    return CAIRO_STATUS_SUCCESS;
+-}
+-
+-/**
+- * Create an ID2D1PathGeometry for a cairo_path_fixed_t
+- *
+- * \param path Path to create a geometry for
+- * \param fill_rule Fill rule to use
+- * \param type Figure begin type to use
+- * \return A D2D geometry
+- */
+-static RefPtr<ID2D1PathGeometry>
+-_cairo_d2d_create_path_geometry_for_path(cairo_path_fixed_t *path, 
+-					 cairo_fill_rule_t fill_rule,
+-					 D2D1_FIGURE_BEGIN type)
+-{
+-    RefPtr<ID2D1PathGeometry> d2dpath;
+-    sD2DFactory->CreatePathGeometry(&d2dpath);
+-    RefPtr<ID2D1GeometrySink> sink;
+-    d2dpath->Open(&sink);
+-    D2D1_FILL_MODE fillMode = D2D1_FILL_MODE_WINDING;
+-    if (fill_rule == CAIRO_FILL_RULE_WINDING) {
+-	fillMode = D2D1_FILL_MODE_WINDING;
+-    } else if (fill_rule == CAIRO_FILL_RULE_EVEN_ODD) {
+-	fillMode = D2D1_FILL_MODE_ALTERNATE;
+-    }
+-    sink->SetFillMode(fillMode);
+-
+-    path_conversion pathConvert;
+-    pathConvert.type = type;
+-    pathConvert.sink = sink;
+-    pathConvert.figureActive = false;
+-    _cairo_path_fixed_interpret(path,
+-				CAIRO_DIRECTION_FORWARD,
+-				_cairo_d2d_path_move_to,
+-				_cairo_d2d_path_line_to,
+-				_cairo_d2d_path_curve_to,
+-				_cairo_d2d_path_close,
+-				&pathConvert);
+-    if (pathConvert.figureActive) {
+-	sink->EndFigure(D2D1_FIGURE_END_OPEN);
+-    }
+-    sink->Close();
+-    return d2dpath;
+-}
+-
+-static cairo_bool_t
+-clip_contains_only_boxes (cairo_clip_t *clip)
+-{
+-    cairo_bool_t is_boxes = TRUE;
+-
+-    if (clip) {
+-	cairo_box_t clip_box;
+-	cairo_clip_path_t *path = clip->path;
+-
+-	while (path) {
+-	    is_boxes &= _cairo_path_fixed_is_box(&path->path, &clip_box);
+-	    path = path->prev;
+-	}
+-    }
+-    return is_boxes;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_clear_box (cairo_d2d_surface_t *d2dsurf,
+-		 cairo_clip_t *clip,
+-		 cairo_box_t *box)
+-{
+-    if (clip_contains_only_boxes (clip)) {
+-	/* clear the box using axis aligned clips */
+-	d2dsurf->rt->PushAxisAlignedClip(D2D1::RectF(_cairo_fixed_to_float(box->p1.x),
+-		    _cairo_fixed_to_float(box->p1.y),
+-		    _cairo_fixed_to_float(box->p2.x),
+-		    _cairo_fixed_to_float(box->p2.y)),
+-		D2D1_ANTIALIAS_MODE_ALIASED);
+-	d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
+-	d2dsurf->rt->PopAxisAlignedClip();
+-
+-	return CAIRO_INT_STATUS_SUCCESS;
+-    }
+-
+-    return CAIRO_INT_STATUS_UNSUPPORTED;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_clear (cairo_d2d_surface_t *d2dsurf,
+-		 cairo_clip_t *clip)
+-{
+-    cairo_region_t *region;
+-    cairo_int_status_t status;
+-
+-    if (!clip) {
+-	/* no clip so clear everything */
+-	_begin_draw_state(d2dsurf);
+-	reset_clip(d2dsurf);
+-	d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
+-
+-	return CAIRO_INT_STATUS_SUCCESS;
+-    }
+-
+-    status = _cairo_clip_get_region (clip, &region);
+-    if (status)
+-	return status;
+-
+-    /* We now have a region, we'll clear it one rectangle at a time */
+-    _begin_draw_state(d2dsurf);
+-
+-    reset_clip(d2dsurf);
+-
+-    if (region) {
+-	int num_rects;
+-	int i;
+-
+-	num_rects = cairo_region_num_rectangles (region);
+-
+-	for (i = 0; i < num_rects; i++) {
+-	    cairo_rectangle_int_t rect;
+-
+-	    cairo_region_get_rectangle (region, i, &rect);
+-
+-	    d2dsurf->rt->PushAxisAlignedClip(
+-		    D2D1::RectF((FLOAT)rect.x,
+-				(FLOAT)rect.y,
+-				(FLOAT)rect.x + rect.width,
+-				(FLOAT)rect.y + rect.height),
+-		    D2D1_ANTIALIAS_MODE_ALIASED);
+-
+-	    d2dsurf->rt->Clear(D2D1::ColorF(0, 0));
+-
+-	    d2dsurf->rt->PopAxisAlignedClip();
+-	}
+-
+-    }
+-
+-    return CAIRO_INT_STATUS_SUCCESS;
+-}
+-
+-static cairo_operator_t _cairo_d2d_simplify_operator(cairo_operator_t op,
+-						     const cairo_pattern_t *source)
+-{
+-    if (op == CAIRO_OPERATOR_SOURCE) {
+-	/** Operator over is easier for D2D! If the source if opaque, change */
+-	if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
+-	    const cairo_surface_pattern_t *surfpattern =
+-		reinterpret_cast<const cairo_surface_pattern_t*>(source);
+-	    if (surfpattern->surface->content == CAIRO_CONTENT_COLOR) {
+-		return CAIRO_OPERATOR_OVER;
+-	    }
+-	} else if (source->type == CAIRO_PATTERN_TYPE_SOLID) {
+-	    const cairo_solid_pattern_t *solidpattern =
+-		reinterpret_cast<const cairo_solid_pattern_t*>(source);
+-	    if (solidpattern->color.alpha == 1.0) {
+-		return CAIRO_OPERATOR_OVER;
+-	    }
+-	}
+-    }
+-    return op;
+-}
+-
+-void
+-_cairo_d2d_surface_init(cairo_d2d_surface_t *newSurf, cairo_d2d_device_t *d2d_device, cairo_format_t format)
+-{
+-    newSurf->format = format;
+-
+-    newSurf->device = d2d_device;
+-    cairo_addref_device(&d2d_device->base);
+-    d2d_device->mVRAMUsage += _cairo_d2d_compute_surface_mem_size(newSurf);
+-}
+-    
+-_cairo_d2d_surface::~_cairo_d2d_surface()
+-{
+-    _cairo_d2d_surface_entry *entry, *next;
+-    cairo_list_foreach_entry_safe(entry, next, _cairo_d2d_surface_entry, &dependent_surfaces, link) {
+-	// We do not need to flush, the contents of our texture has not changed,
+-	// our users have their own reference and can just use it later.
+-	cairo_surface_destroy(&entry->surface->base);
+-	delete entry;
+-    }
+-
+-}
+-
+-// Implementation
+-static cairo_surface_t*
+-_cairo_d2d_create_similar(void			*surface,
+-			  cairo_content_t	 content,
+-			  int			 width,
+-			  int			 height)
+-{
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+-    cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
+-    
+-    new (newSurf) cairo_d2d_surface_t();
+-    _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
+-
+-
+-    D2D1_SIZE_U sizePixels;
+-    D2D1_SIZE_F size;
+-    HRESULT hr;
+-
+-    sizePixels.width = width;
+-    sizePixels.height = height;
+-    FLOAT dpiX;
+-    FLOAT dpiY;
+-
+-    d2dsurf->rt->GetDpi(&dpiX, &dpiY);
+-
+-    D2D1_ALPHA_MODE alpha;
+-
+-    if (content == CAIRO_CONTENT_COLOR) {
+-	alpha = D2D1_ALPHA_MODE_IGNORE;
+-    } else {
+-	alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
+-    }
+-
+-    size.width = sizePixels.width * dpiX;
+-    size.height = sizePixels.height * dpiY;
+-    D2D1_BITMAP_PROPERTIES bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN,
+-									       alpha));
+-
+-    if (sizePixels.width < 1) {
+-	sizePixels.width = 1;
+-    }
+-    if (sizePixels.height < 1) {
+-	sizePixels.height = 1;
+-    }
+-    RefPtr<IDXGISurface> oldDxgiSurface;
+-    d2dsurf->surface->QueryInterface(&oldDxgiSurface);
+-    DXGI_SURFACE_DESC origDesc;
+-
+-    oldDxgiSurface->GetDesc(&origDesc);
+-
+-    CD3D10_TEXTURE2D_DESC desc(origDesc.Format,
+-			       sizePixels.width,
+-			       sizePixels.height);
+-
+-    if (content == CAIRO_CONTENT_ALPHA) {
+-	desc.Format = DXGI_FORMAT_A8_UNORM;
+-    }
+-
+-    desc.MipLevels = 1;
+-    desc.Usage = D3D10_USAGE_DEFAULT;
+-    desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+-    
+-    /* CreateTexture2D does not support D3D10_RESOURCE_MISC_GDI_COMPATIBLE with DXGI_FORMAT_A8_UNORM */
+-    if (desc.Format != DXGI_FORMAT_A8_UNORM)
+-	desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
+-
+-    RefPtr<ID3D10Texture2D> texture;
+-    RefPtr<IDXGISurface> dxgiSurface;
+-
+-    D2D1_RENDER_TARGET_USAGE usage = (desc.MiscFlags & D3D10_RESOURCE_MISC_GDI_COMPATIBLE) ?
+-					  D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE
+-					: D2D1_RENDER_TARGET_USAGE_NONE;
+-
+-    hr = d2dsurf->device->mD3D10Device->CreateTexture2D(&desc, NULL, &texture);
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATESIMILAR;
+-    }
+-
+-    newSurf->surface = texture;
+-
+-    // Create the DXGI surface.
+-    hr = newSurf->surface->QueryInterface(IID_IDXGISurface, (void**)&dxgiSurface);
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATESIMILAR;
+-    }
+-
+-    hr = sD2DFactory->CreateDxgiSurfaceRenderTarget(dxgiSurface,
+-						    D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
+-										 D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN,
+-												   alpha),
+-										 dpiX,
+-										 dpiY,
+-										 usage),
+-						    &newSurf->rt);
+-
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATESIMILAR;
+-    }
+-
+-    if (desc.Format != DXGI_FORMAT_A8_UNORM) {
+-	/* For some reason creation of shared bitmaps for A8 UNORM surfaces
+-	 * doesn't work even though the documentation suggests it does. The
+-	 * function will return an error if we try */
+-	hr = newSurf->rt->CreateSharedBitmap(IID_IDXGISurface,
+-					     dxgiSurface,
+-					     &bitProps,
+-					     &newSurf->surfaceBitmap);
+-	if (FAILED(hr)) {
+-	    goto FAIL_CREATESIMILAR;
+-	}
+-    }
+-
+-    newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
+-
+-    _d2d_clear_surface(newSurf);
+-
+-    _cairo_d2d_surface_init(newSurf, d2dsurf->device, _cairo_format_from_content(content));
+-
+-    return reinterpret_cast<cairo_surface_t*>(newSurf);
+-
+-FAIL_CREATESIMILAR:
+-    /** Ensure we call our surfaces desctructor */
+-    newSurf->~cairo_d2d_surface_t();
+-    free(newSurf);
+-    return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+-}
+-
+-static cairo_status_t
+-_cairo_d2d_finish(void	    *surface)
+-{
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+-
+-    d2dsurf->device->mVRAMUsage -= _cairo_d2d_compute_surface_mem_size(d2dsurf);
+-    if (d2dsurf->bufferTexture) {
+-	d2dsurf->device->mVRAMUsage -= _cairo_d2d_compute_surface_mem_size(d2dsurf);
+-    }
+-
+-    reset_clip(d2dsurf);
+-
+-    // We need to release the device after calling the constructor, since the
+-    // device destruction may release the D3D/D2D libraries.
+-    cairo_device_t *device = &d2dsurf->device->base;
+-    d2dsurf->~cairo_d2d_surface_t();
+-    cairo_release_device(device);
+-    return CAIRO_STATUS_SUCCESS;
+-}
+-
+-/* The input types for src and dst don't match because in our particular use case, copying from a texture,
+- * those types don't match. */
+-static void
+-_copy_data_to_different_stride(unsigned char *dst, int dst_stride, void *src, UINT src_stride, int height)
+-{
+-
+-    unsigned char *src_p = (unsigned char *)src;
+-    int min_stride = MIN(dst_stride, src_stride);
+-    while (height) {
+-        memcpy(dst, src_p, min_stride);
+-        height--;
+-        dst += dst_stride;
+-        src_p += src_stride;
+-    }
+-}
+-
+-static cairo_status_t
+-_cairo_d2d_acquire_source_image(void                    *abstract_surface,
+-				cairo_image_surface_t  **image_out_ret,
+-				void                   **image_extra)
+-{
+-    cairo_surface_t *image_out;
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(abstract_surface);
+-    _cairo_d2d_flush(d2dsurf);
+-
+-    HRESULT hr;
+-    D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize();
+-
+-    RefPtr<ID3D10Texture2D> softTexture;
+-
+-    RefPtr<IDXGISurface> dxgiSurface;
+-    d2dsurf->surface->QueryInterface(&dxgiSurface);
+-    DXGI_SURFACE_DESC desc;
+-
+-    dxgiSurface->GetDesc(&desc);
+-
+-    CD3D10_TEXTURE2D_DESC softDesc(desc.Format, desc.Width, desc.Height);
+-
+-    /**
+-     * We can't actually map our backing store texture, so we create one in CPU memory, and then
+-     * tell D3D to copy the data from our surface there, readback is expensive, we -never-
+-     * -ever- want this to happen.
+-     */
+-    softDesc.MipLevels = 1;
+-    softDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE | D3D10_CPU_ACCESS_READ;
+-    softDesc.Usage = D3D10_USAGE_STAGING;
+-    softDesc.BindFlags = 0;
+-    hr = d2dsurf->device->mD3D10Device->CreateTexture2D(&softDesc, NULL, &softTexture);
+-    if (FAILED(hr)) {
+-	return _cairo_error(CAIRO_STATUS_NO_MEMORY);
+-    }
+-
+-    d2dsurf->device->mD3D10Device->CopyResource(softTexture, d2dsurf->surface);
+-
+-    D3D10_MAPPED_TEXTURE2D data;
+-    hr = softTexture->Map(0, D3D10_MAP_READ_WRITE, 0, &data);
+-    if (FAILED(hr)) {
+-	return _cairo_error(CAIRO_STATUS_NO_DEVICE);
+-    }
+-
+-    if (_cairo_valid_stride_alignment(data.RowPitch)) {
+-	image_out = cairo_image_surface_create_for_data((unsigned char*)data.pData,
+-						  d2dsurf->format,
+-						  size.width,
+-						  size.height,
+-						  data.RowPitch);
+-    } else {
+-	/* Slow path used when the stride doesn't match our requirements.
+-	 * This is possible on at least the Intel driver 8.15.10.2302.
+-	 *
+-	 * Create a new image surface and copy our data into it */
+-	image_out = cairo_image_surface_create(d2dsurf->format,
+-					 size.width,
+-					 size.height);
+-	_copy_data_to_different_stride(cairo_image_surface_get_data(image_out),
+-				       cairo_image_surface_get_stride(image_out),
+-				       data.pData,
+-				       data.RowPitch,
+-				       size.height);
+-
+-    }
+-    /* these are the only surface statuses we expect */
+-    assert(cairo_surface_status(image_out) == CAIRO_STATUS_SUCCESS ||
+-	   cairo_surface_status(image_out) == CAIRO_STATUS_NO_MEMORY);
+-
+-    *image_extra = softTexture.forget().drop();
+-    *image_out_ret = (cairo_image_surface_t*)image_out;
+-
+-    return cairo_surface_status(image_out);
+-}
+-
+-static void
+-_cairo_d2d_release_source_image(void                   *abstract_surface,
+-				cairo_image_surface_t  *image,
+-				void                   *image_extra)
+-{
+-    if (((cairo_surface_t*)abstract_surface)->type != CAIRO_SURFACE_TYPE_D2D) {
+-	return;
+-    }
+-
+-    cairo_surface_destroy(&image->base);
+-    ID3D10Texture2D *softTexture = (ID3D10Texture2D*)image_extra;
+-    
+-    softTexture->Unmap(0);
+-    softTexture->Release();
+-    softTexture = NULL;
+-}
+-
+-static cairo_status_t
+-_cairo_d2d_acquire_dest_image(void                    *abstract_surface,
+-			      cairo_rectangle_int_t   *interest_rect,
+-			      cairo_image_surface_t  **image_out,
+-			      cairo_rectangle_int_t   *image_rect,
+-			      void                   **image_extra)
+-{
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(abstract_surface);
+-    _cairo_d2d_flush(d2dsurf);
+-
+-    HRESULT hr;
+-    D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize();
+-
+-    RefPtr<ID3D10Texture2D> softTexture;
+-
+-
+-    RefPtr<IDXGISurface> dxgiSurface;
+-    d2dsurf->surface->QueryInterface(&dxgiSurface);
+-    DXGI_SURFACE_DESC desc;
+-
+-    dxgiSurface->GetDesc(&desc);
+-
+-    CD3D10_TEXTURE2D_DESC softDesc(desc.Format, desc.Width, desc.Height);
+-
+-    image_rect->width = desc.Width;
+-    image_rect->height = desc.Height;
+-    image_rect->x = image_rect->y = 0;
+-
+-    softDesc.MipLevels = 1;
+-    softDesc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE | D3D10_CPU_ACCESS_READ;
+-    softDesc.Usage = D3D10_USAGE_STAGING;
+-    softDesc.BindFlags = 0;
+-    hr = d2dsurf->device->mD3D10Device->CreateTexture2D(&softDesc, NULL, &softTexture);
+-    if (FAILED(hr)) {
+-	return _cairo_error(CAIRO_STATUS_NO_MEMORY);
+-    }
+-    d2dsurf->device->mD3D10Device->CopyResource(softTexture, d2dsurf->surface);
+-
+-    D3D10_MAPPED_TEXTURE2D data;
+-    hr = softTexture->Map(0, D3D10_MAP_READ_WRITE, 0, &data);
+-    if (FAILED(hr)) {
+-	return _cairo_error(CAIRO_STATUS_NO_DEVICE);
+-    }
+-    *image_out = 
+-	(cairo_image_surface_t*)cairo_image_surface_create_for_data((unsigned char*)data.pData,
+-										  _cairo_format_from_content(d2dsurf->base.content),
+-										  size.width,
+-										  size.height,
+-										  data.RowPitch);
+-    *image_extra = softTexture.forget().drop();
+-
+-    return CAIRO_STATUS_SUCCESS;
+-}
+-
+-static void
+-_cairo_d2d_release_dest_image(void                    *abstract_surface,
+-			      cairo_rectangle_int_t   *interest_rect,
+-			      cairo_image_surface_t   *image,
+-			      cairo_rectangle_int_t   *image_rect,
+-			      void                    *image_extra)
+-{
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(abstract_surface);
+-
+-    ID3D10Texture2D *softTexture = (ID3D10Texture2D*)image_extra;
+-    D2D1_POINT_2U point;
+-    point.x = 0;
+-    point.y = 0;
+-    D2D1_RECT_U rect;
+-    D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize();
+-    rect.left = rect.top = 0;
+-    rect.right = size.width;
+-    rect.bottom = size.height;
+-
+-    cairo_surface_destroy(&image->base);
+-
+-    softTexture->Unmap(0);
+-    d2dsurf->device->mD3D10Device->CopyResource(d2dsurf->surface, softTexture);
+-    softTexture->Release();
+-}
+-
+-
+-static cairo_status_t
+-_cairo_d2d_flush(void                  *surface)
+-{
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+-
+-    if (d2dsurf->isDrawing) {
+-	reset_clip(d2dsurf);
+-	HRESULT hr = d2dsurf->rt->EndDraw();
+-	d2dsurf->isDrawing = false;
+-    }
+-
+-    return CAIRO_STATUS_SUCCESS;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_copy_surface(cairo_d2d_surface_t *dst,
+-			cairo_d2d_surface_t *src,
+-			cairo_point_int_t *translation,
+-			cairo_region_t *region)
+-{
+-    RefPtr<IDXGISurface> dstSurface;
+-    dst->surface->QueryInterface(&dstSurface);
+-    RefPtr<IDXGISurface> srcSurface;
+-    src->surface->QueryInterface(&srcSurface);
+-    DXGI_SURFACE_DESC srcDesc, dstDesc;
+-
+-    srcSurface->GetDesc(&srcDesc);
+-    dstSurface->GetDesc(&dstDesc);
+-
+-    cairo_rectangle_int_t clip_rect;
+-    clip_rect.x = 0;
+-    clip_rect.y = 0;
+-    clip_rect.width = dstDesc.Width;
+-    clip_rect.height = dstDesc.Height;
+-    
+-    cairo_int_status_t rv = CAIRO_INT_STATUS_SUCCESS;
+-
+-    _cairo_d2d_flush(dst);
+-    ID3D10Resource *srcResource = src->surface;
+-    if (src->surface.get() == dst->surface.get()) {
+-	// Self-copy
+-	srcResource = _cairo_d2d_get_buffer_texture(dst);
+-	src->device->mD3D10Device->CopyResource(srcResource, src->surface);
+-    } else {
+-	// Need to flush the source too if it's a different surface.
+-	_cairo_d2d_flush(src);
+-    }
+-
+-    // One copy for each rectangle in the final clipping region.
+-    for (int i = 0; i < cairo_region_num_rectangles(region); i++) {
+-	D3D10_BOX rect;
+-	cairo_rectangle_int_t area_to_copy;
+-
+-	cairo_region_get_rectangle(region, i, &area_to_copy);
+-
+-	cairo_rectangle_int_t transformed_rect = { area_to_copy.x + translation->x,
+-						   area_to_copy.y + translation->y,
+-						   area_to_copy.width, area_to_copy.height };
+-	cairo_rectangle_int_t surface_rect = { 0, 0,
+-					       static_cast<int>(srcDesc.Width),
+-					       static_cast<int>(srcDesc.Height) };
+-
+-
+-	if (!_cairo_rectangle_contains(&surface_rect, &transformed_rect)) {
+-	    /* We cannot do any sort of extend, in the future a little bit of extra code could
+-	     * allow us to support EXTEND_NONE.
+-	     */
+-	    rv = CAIRO_INT_STATUS_UNSUPPORTED;
+-	    break;
+-	}
+-
+-	rect.front = 0;
+-	rect.back = 1;
+-	rect.left = transformed_rect.x;
+-	rect.top = transformed_rect.y;
+-	rect.right = transformed_rect.x + transformed_rect.width;
+-	rect.bottom = transformed_rect.y + transformed_rect.height;
+-
+-	src->device->mD3D10Device->CopySubresourceRegion(dst->surface,
+-							 0,
+-							 area_to_copy.x,
+-							 area_to_copy.y,
+-							 0,
+-							 srcResource,
+-							 0,
+-							 &rect);
+-    }
+-
+-    return rv;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_blend_surface(cairo_d2d_surface_t *dst,
+-			 cairo_d2d_surface_t *src,
+-		 	 const cairo_matrix_t *transform,
+-			 cairo_box_t *box,
+-			 cairo_clip_t *clip,
+-			 cairo_filter_t filter,
+-			 float opacity)
+-{
+-    if (dst == src) {
+-	// We cannot do self-blend.
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-    cairo_int_status_t rv = CAIRO_INT_STATUS_SUCCESS;
+-
+-    _begin_draw_state(dst);
+-    _cairo_d2d_set_clip(dst, clip);
+-    _cairo_d2d_flush(src);
+-    D2D1_SIZE_U sourceSize = src->surfaceBitmap->GetPixelSize();
+-
+-
+-    double x1, x2, y1, y2;
+-    if (box) {
+-	_cairo_box_to_doubles(box, &x1, &y1, &x2, &y2);
+-    } else {
+-	x1 = y1 = 0;
+-	x2 = dst->rt->GetSize().width;
+-	y2 = dst->rt->GetSize().height;
+-    }
+-
+-    if (clip) {
+-	const cairo_rectangle_int_t *clipExtent = _cairo_clip_get_extents(clip);
+-	x1 = MAX(x1, clipExtent->x);
+-	x2 = MIN(x2, clipExtent->x + clipExtent->width);
+-	y1 = MAX(y1, clipExtent->y);
+-	y2 = MIN(y2, clipExtent->y + clipExtent->height);
+-    }
+-
+-    // We should be in drawing state for this.
+-    _begin_draw_state(dst);
+-    _cairo_d2d_set_clip (dst, clip);
+-    D2D1_RECT_F rectSrc;
+-    rectSrc.left = (float)(x1 * transform->xx + transform->x0);
+-    rectSrc.top = (float)(y1 * transform->yy + transform->y0);
+-    rectSrc.right = (float)(x2 * transform->xx + transform->x0);
+-    rectSrc.bottom = (float)(y2 * transform->yy + transform->y0);
+-
+-    if (rectSrc.left < 0 || rectSrc.top < 0 || rectSrc.right < 0 || rectSrc.bottom < 0 ||
+-	rectSrc.right > sourceSize.width || rectSrc.bottom > sourceSize.height ||
+-	rectSrc.left > sourceSize.width || rectSrc.top > sourceSize.height) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    D2D1_RECT_F rectDst;
+-    rectDst.left = (float)x1;
+-    rectDst.top = (float)y1;
+-    rectDst.right = (float)x2;
+-    rectDst.bottom = (float)y2;
+-
+-    // Bug 599658 - if the src rect is inverted in either axis D2D is fine with
+-    // this but it does not actually invert the bitmap. This is an easy way
+-    // of doing that.
+-    D2D1_MATRIX_3X2_F matrix = D2D1::IdentityMatrix();
+-    bool needsTransform = false;
+-    if (rectSrc.left > rectSrc.right) {
+-	rectDst.left = -rectDst.left;
+-	rectDst.right = -rectDst.right;
+-	matrix._11 = -1.0;
+-	needsTransform = true;
+-    }
+-    if (rectSrc.top > rectSrc.bottom) {
+-	rectDst.top = -rectDst.top;
+-	rectDst.bottom = -rectDst.bottom;
+-	matrix._22 = -1.0;
+-	needsTransform = true;
+-    }
+-
+-    _cairo_d2d_add_dependent_surface(src, dst);
+-
+-    D2D1_BITMAP_INTERPOLATION_MODE interpMode =
+-      D2D1_BITMAP_INTERPOLATION_MODE_LINEAR;
+-
+-    if (needsTransform) {
+-	dst->rt->SetTransform(matrix);
+-    }
+-
+-    if (filter == CAIRO_FILTER_NEAREST) {
+-      interpMode = D2D1_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR;
+-    }
+-
+-    dst->rt->DrawBitmap(src->surfaceBitmap,
+-			rectDst,
+-			opacity,
+-			interpMode,
+-			rectSrc);
+-    if (needsTransform) {
+-	dst->rt->SetTransform(D2D1::IdentityMatrix());
+-    }
+-
+-    return rv;
+-}
+-/**
+- * This function will text if we can use GPU mem cpy to execute an operation with
+- * a surface pattern. If box is NULL it will operate on the entire dst surface.
+- */
+-static cairo_int_status_t
+-_cairo_d2d_try_fastblit(cairo_d2d_surface_t *dst,
+-			cairo_surface_t *src,
+-			cairo_box_t *box,
+-			const cairo_matrix_t *matrix,
+-			cairo_clip_t *clip,
+-			cairo_operator_t op,
+-			cairo_filter_t filter,
+-			float opacity = 1.0f)
+-{
+-    if (op == CAIRO_OPERATOR_OVER && src->content == CAIRO_CONTENT_COLOR) {
+-	op = CAIRO_OPERATOR_SOURCE;
+-    }
+-    if (op != CAIRO_OPERATOR_SOURCE && op != CAIRO_OPERATOR_OVER) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    /* For now we do only D2D sources */
+-    if (src->type != CAIRO_SURFACE_TYPE_D2D) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    cairo_d2d_surface_t *d2dsrc = reinterpret_cast<cairo_d2d_surface_t*>(src);
+-    if (op == CAIRO_OPERATOR_OVER && matrix->xy == 0 && matrix->yx == 0) {
+-	return _cairo_d2d_blend_surface(dst, d2dsrc, matrix, box, clip, filter, opacity);
+-    }
+-    
+-    if (op == CAIRO_OPERATOR_OVER || opacity != 1.0f) {
+-	// Past this point we will never get into a situation where we can
+-	// support OVER.
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-    
+-    cairo_point_int_t translation;
+-    if ((box && !box_is_integer(box)) ||
+-	!_cairo_matrix_is_integer_translation(matrix, &translation.x, &translation.y)) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    cairo_rectangle_int_t rect;
+-    if (box) {
+-	_cairo_box_round_to_rectangle(box, &rect);
+-    } else {
+-	rect.x = rect.y = 0;
+-	rect.width = dst->rt->GetPixelSize().width;
+-	rect.height = dst->rt->GetPixelSize().height;
+-    }
+-    
+-    if (d2dsrc->device != dst->device) {
+-	// This doesn't work between different devices.
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    /* Region we need to clip this operation to */
+-    cairo_region_t *clipping_region = NULL;
+-    cairo_region_t *region;
+-    cairo_region_auto_ptr region_ptr;
+-
+-    if (clip) {
+-	_cairo_clip_get_region(clip, &clipping_region);
+-
+-	if (!clipping_region) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-	region = cairo_region_copy(clipping_region);
+-	region_ptr.set(region);
+-
+-	cairo_region_intersect_rectangle(region, &rect);
+-
+-	if (cairo_region_is_empty(region)) {
+-	    // Nothing to do.
+-	    return CAIRO_INT_STATUS_SUCCESS;
+-	}
+-    } else {
+-	region = cairo_region_create_rectangle(&rect);
+-	region_ptr.set(region);
+-
+-	// Areas outside of the surface do not matter.
+-	cairo_rectangle_int_t surface_rect = { 0, 0,
+-					       static_cast<int>(dst->rt->GetPixelSize().width),
+-					       static_cast<int>(dst->rt->GetPixelSize().height) };
+-	cairo_region_intersect_rectangle(region, &surface_rect);
+-    }
+-
+-    cairo_int_status_t rv = _cairo_d2d_copy_surface(dst, d2dsrc, &translation, region);
+-    
+-    return rv;
+-}
+-
+-static RefPtr<ID2D1RenderTarget>
+-_cairo_d2d_get_temp_rt(cairo_d2d_surface_t *surf, cairo_clip_t *clip)
+-{
+-    RefPtr<ID3D10Texture2D> texture = _cairo_d2d_get_buffer_texture(surf);
+-    RefPtr<ID2D1RenderTarget> new_rt;
+-    RefPtr<IDXGISurface> dxgiSurface;
+-    texture->QueryInterface(&dxgiSurface);
+-    HRESULT hr;
+-
+-    _cairo_d2d_flush(surf);
+-
+-    if (!surf) {
+-	return NULL;
+-    }
+-
+-    D2D1_RENDER_TARGET_PROPERTIES props = 
+-	D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
+-				     D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED));
+-    hr = sD2DFactory->CreateDxgiSurfaceRenderTarget(dxgiSurface,
+-						    props,
+-						    &new_rt);
+-
+-    if (FAILED(hr)) {
+-	return NULL;
+-    }
+-
+-    new_rt->BeginDraw();
+-    new_rt->Clear(D2D1::ColorF(0, 0));
+-
+-    // Since this is a fresh surface there's no point in doing clever things to
+-    // keep the clip path around until a certain depth. So we just do a straight-
+-    // forward push of all clip paths in the tree, similar to what the normal
+-    // clip code does, but a little less clever.
+-    if (clip) {
+-	cairo_clip_path_t *path = clip->path;
+-	while (path) {
+-	    cairo_box_t clip_box;
+-	    if (_cairo_path_fixed_is_box(&path->path, &clip_box)) {
+-		// If this does not have a region it could be none-pixel aligned.
+-		D2D1_ANTIALIAS_MODE aaMode = D2D1_ANTIALIAS_MODE_PER_PRIMITIVE;
+-		if (box_is_integer(&clip_box)) {
+-		    aaMode = D2D1_ANTIALIAS_MODE_ALIASED;
+-		}
+-		new_rt->PushAxisAlignedClip(D2D1::RectF(_cairo_fixed_to_float(clip_box.p1.x),
+-							_cairo_fixed_to_float(clip_box.p1.y),
+-							_cairo_fixed_to_float(clip_box.p2.x),
+-							_cairo_fixed_to_float(clip_box.p2.y)),
+-					    aaMode);
+-	    } else {
+-		HRESULT hr;
+-		RefPtr<ID2D1PathGeometry> geom = _cairo_d2d_create_path_geometry_for_path (&path->path,
+-											   path->fill_rule,
+-											   D2D1_FIGURE_BEGIN_FILLED);
+-		RefPtr<ID2D1Layer> layer;
+-
+-		hr = new_rt->CreateLayer (&layer);
+-
+-		D2D1_LAYER_OPTIONS options = D2D1_LAYER_OPTIONS_NONE;
+-
+-		new_rt->PushLayer(D2D1::LayerParameters(
+-					D2D1::InfiniteRect(),
+-					geom,
+-					D2D1_ANTIALIAS_MODE_PER_PRIMITIVE,
+-					D2D1::IdentityMatrix(),
+-					1.0,
+-					0,
+-					options),
+-				  layer);
+-	    }
+-	    path = path->prev;
+-	}
+-    }
+-    return new_rt;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_blend_temp_surface(cairo_d2d_surface_t *surf, cairo_operator_t op, ID2D1RenderTarget *rt, cairo_clip_t *clip, const cairo_rectangle_int_t *bounds = NULL)
+-{
+-    _cairo_d2d_flush_dependent_surfaces(surf);
+-
+-    int numPaths = 0;
+-    if (clip) {
+-	cairo_clip_path_t *path = clip->path;
+-	while (path) {
+-	    numPaths++;
+-	    path = path->prev;
+-	}
+-	
+-	cairo_clip_path_t **paths = new cairo_clip_path_t*[numPaths];
+-
+-	numPaths = 0;
+-	path = clip->path;
+-	while (path) {
+-	    paths[numPaths++] = path;
+-	    path = path->prev;
+-	}	
+-
+-	for (int i = numPaths - 1; i >= 0; i--) {
+-	    if (paths[i]->flags & CAIRO_CLIP_PATH_IS_BOX) {
+-		rt->PopAxisAlignedClip();
+-	    } else {
+-		rt->PopLayer();
+-	    }
+-	}
+-	delete [] paths;
+-    }
+-    rt->EndDraw();
+-    HRESULT hr;
+-
+-    RefPtr<ID3D10Texture2D> srcTexture = _cairo_d2d_get_buffer_texture(surf);
+-    RefPtr<ID3D10Texture2D> dstTexture;
+-
+-    surf->surface->QueryInterface(&dstTexture);
+-    ID3D10Device *device = surf->device->mD3D10Device;
+-
+-    if (!surf->buffer_rt_view) {
+-	hr = device->CreateRenderTargetView(dstTexture, NULL, &surf->buffer_rt_view);
+-	if (FAILED(hr)) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-    }
+-
+-    if (!surf->buffer_sr_view) {
+-	hr = device->CreateShaderResourceView(srcTexture, NULL, &surf->buffer_sr_view);
+-	if (FAILED(hr)) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-    }
+-
+-    cairo_int_status_t status;
+-
+-    status = _cairo_d2d_set_operator(surf->device, op);
+-
+-    if (unlikely(status)) {
+-	return status;
+-    }
+-
+-    D3D10_TEXTURE2D_DESC tDesc;
+-    dstTexture->GetDesc(&tDesc);
+-    D3D10_VIEWPORT vp;
+-    vp.Height = tDesc.Height;
+-    vp.MinDepth = 0;
+-    vp.MaxDepth = 1.0;
+-    vp.TopLeftX = 0;
+-    vp.TopLeftY = 0;
+-    vp.Width = tDesc.Width;
+-    device->RSSetViewports(1, &vp);
+-
+-    ID3D10Effect *effect = surf->device->mSampleEffect;
+-
+-    ID3D10RenderTargetView *rtViewPtr = surf->buffer_rt_view;
+-    device->OMSetRenderTargets(1, &rtViewPtr, 0);
+-    ID3D10EffectVectorVariable *quadDesc = effect->GetVariableByName("QuadDesc")->AsVector();
+-    ID3D10EffectVectorVariable *texCoords = effect->GetVariableByName("TexCoords")->AsVector();
+-
+-    float quadDescVal[] = { -1.0f, 1.0f, 2.0f, -2.0f };
+-    float texCoordsVal[] = { 0.0, 0.0, 1.0f, 1.0f };
+-    if (bounds && _cairo_operator_bounded_by_mask(op)) {
+-	quadDescVal[0] = -1.0f + ((float)bounds->x / (float)tDesc.Width) * 2.0f;
+-	quadDescVal[1] = 1.0f - ((float)bounds->y / (float)tDesc.Height) * 2.0f;
+-	quadDescVal[2] = ((float)bounds->width / (float)tDesc.Width) * 2.0f;
+-	quadDescVal[3] = -((float)bounds->height / (float)tDesc.Height) * 2.0f;
+-	texCoordsVal[0] = (float)bounds->x / (float)tDesc.Width;
+-	texCoordsVal[1] = (float)bounds->y / (float)tDesc.Height;
+-	texCoordsVal[2] = (float)bounds->width / (float)tDesc.Width;
+-	texCoordsVal[3] = (float)bounds->height / (float)tDesc.Height;
+-    }
+-    quadDesc->SetFloatVector(quadDescVal);
+-    texCoords->SetFloatVector(texCoordsVal);
+-
+-    _cairo_d2d_setup_for_blend(surf->device);
+-    ID3D10EffectTechnique *technique = effect->GetTechniqueByName("SampleTexture");
+-    technique->GetPassByIndex(0)->Apply(0);
+-
+-    ID3D10ShaderResourceView *srViewPtr = surf->buffer_sr_view;
+-    device->PSSetShaderResources(0, 1, &srViewPtr);
+-
+-    device->Draw(4, 0);
+-
+-#ifdef DEBUG
+-    // Quiet down some info messages from D3D10 debug layer
+-    srViewPtr = NULL;
+-    device->PSSetShaderResources(0, 1, &srViewPtr);
+-    rtViewPtr = NULL;
+-    device->OMSetRenderTargets(1, &rtViewPtr, 0); 
+-#endif
+-    return CAIRO_INT_STATUS_SUCCESS;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_paint(void			*surface,
+-		 cairo_operator_t	 op,
+-		 const cairo_pattern_t	*source,
+-		 cairo_clip_t		*clip)
+-{
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+-    cairo_int_status_t status;
+-
+-    op = _cairo_d2d_simplify_operator(op, source);
+-
+-    if (op == CAIRO_OPERATOR_SOURCE) {
+-	if (!clip) {
+-	    _cairo_d2d_clear(d2dsurf, NULL);
+-	    op = CAIRO_OPERATOR_OVER;
+-	} else {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-    }
+-
+-    if (op == CAIRO_OPERATOR_CLEAR) {
+-	return _cairo_d2d_clear(d2dsurf, clip);
+-    }
+-
+-    if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
+-	const cairo_surface_pattern_t *surf_pattern = 
+-	    reinterpret_cast<const cairo_surface_pattern_t*>(source);
+-
+-	status = _cairo_d2d_try_fastblit(d2dsurf, surf_pattern->surface,
+-					 NULL, &source->matrix, clip,
+-					 op, source->filter);
+-
+-	if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
+-	    return status;
+-	}
+-    }
+-    RefPtr<ID2D1RenderTarget> target_rt = d2dsurf->rt;
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    if (op != CAIRO_OPERATOR_OVER) {
+-#endif
+-	target_rt = _cairo_d2d_get_temp_rt(d2dsurf, clip);
+-	if (!target_rt) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    } else {
+-	_begin_draw_state(d2dsurf);
+-	status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, clip);
+-
+-	if (unlikely(status))
+-	    return status;
+-    }
+-#endif
+-
+-    target_rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+-
+-    RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL,
+-								   source);
+-    
+-    if (!brush) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    D2D1_SIZE_F size = target_rt->GetSize();
+-    target_rt->FillRectangle(D2D1::RectF((FLOAT)0,
+-					 (FLOAT)0,
+-					 (FLOAT)size.width,
+-					 (FLOAT)size.height),
+-			     brush);
+-
+-    if (target_rt.get() != d2dsurf->rt.get()) {
+-	return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip);
+-    }
+-
+-    return CAIRO_INT_STATUS_SUCCESS;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_mask(void			*surface,
+-		cairo_operator_t	 op,
+-		const cairo_pattern_t	*source,
+-		const cairo_pattern_t	*mask,
+-		cairo_clip_t		*clip)
+-{
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+-    cairo_rectangle_int_t extents;
+-
+-    cairo_clip_t *actual_clip = clip;
+-    cairo_clip_t temporary_clip;
+-
+-    cairo_int_status_t status;
+-
+-    status = (cairo_int_status_t)_cairo_surface_mask_extents (&d2dsurf->base,
+-		    op, source,
+-		    mask,
+-		    clip, &extents);
+-    if (unlikely (status))
+-	    return status;
+-
+-    bool isSolidAlphaMask = false;
+-    float solidAlphaValue = 1.0f;
+-
+-    if (mask->type == CAIRO_PATTERN_TYPE_SOLID) {
+-	cairo_solid_pattern_t *solidPattern =
+-	    (cairo_solid_pattern_t*)mask;
+-	if (_cairo_color_get_content (&solidPattern->color) == CAIRO_CONTENT_ALPHA) {
+-	    isSolidAlphaMask = true;
+-	    solidAlphaValue = solidPattern->color.alpha;
+-	}
+-    }
+-
+-    cairo_box_t box;
+-    _cairo_box_from_rectangle(&box, &extents);
+-
+-    if (clip && isSolidAlphaMask) {
+-	// We do some work here to try and avoid pushing and popping clips for rectangular areas,
+-	// if we do this fill rects will occur without rectangular clips being pushed and popped.
+-	// This is faster for non-axis aligned clips in general and allows more efficient batching
+-	// of the pop-clip calls.
+-	int num_boxes = 1;
+-	cairo_box_t box_stack;
+-	cairo_box_t *boxes;
+-	boxes = &box_stack;
+-
+-	// This function assumes atleast a single box resides at 'boxes' and the
+-	// amount of boxes that reside there are passed in under num_boxes.
+-	status = _cairo_clip_get_boxes(clip, &boxes, &num_boxes);
+-
+-	if (!status && num_boxes == 1) {
+-	    box.p1.x = MAX(box.p1.x, boxes->p1.x);
+-	    box.p2.x = MIN(box.p2.x, boxes->p2.x);
+-	    box.p1.y = MAX(box.p1.y, boxes->p1.y);
+-	    box.p2.y = MIN(box.p2.y, boxes->p2.y);
+-
+-	    if (clip->path != d2dsurf->clip.path) {
+-		// If we have a clip set, but it's not the right one. We want to
+-		// pop as much as we need to, to be sure the area affected by
+-		// the operation is not clipped. To do this we set the clip path
+-		// to the common ancestor of the currently set clip path and the
+-		// clip path for this operation. This will cause
+-		// _cairo_d2d_set_clip to pop to that common ancestor, but not
+-		// needlessly push the additional clips we're trying to avoid.
+-		temporary_clip.path = find_common_ancestor(clip->path, d2dsurf->clip.path);
+-
+-		// We're not going to be using this down the line so it doesn't
+-		// really matter what the value is. If all -was- clipped this
+-		// call shouldn't even have reached the surface backend.
+-		temporary_clip.all_clipped = FALSE;
+-
+-		actual_clip = &temporary_clip;
+-	    }
+-	}
+-
+-	if (boxes != &box_stack) {
+-	    // If the function changed the boxes pointer, we need to free it.
+-	    free(boxes);
+-	}
+-    }
+-
+-    if (isSolidAlphaMask) {
+-	if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
+-	    const cairo_surface_pattern_t *surf_pattern = 
+-		reinterpret_cast<const cairo_surface_pattern_t*>(source);
+-	    cairo_int_status_t rv = _cairo_d2d_try_fastblit(d2dsurf,
+-							    surf_pattern->surface,
+-							    &box,
+-							    &source->matrix,
+-							    clip,
+-							    op,
+-							    source->filter,
+-							    solidAlphaValue);
+-	    if (rv != CAIRO_INT_STATUS_UNSUPPORTED) {
+-		return rv;
+-	    }
+-	}
+-    }
+-
+-    RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, source);
+-    if (!brush) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    RefPtr<ID2D1RenderTarget> target_rt = d2dsurf->rt;
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    if (op != CAIRO_OPERATOR_OVER) {
+-#endif
+-	target_rt = _cairo_d2d_get_temp_rt(d2dsurf, clip);
+-	if (!target_rt) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    } else {
+-	_begin_draw_state(d2dsurf);
+-
+-	status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, actual_clip);
+-	if (unlikely(status))
+-	    return status;
+-    }
+-#endif
+-
+-    D2D1_RECT_F rect = D2D1::RectF(_cairo_fixed_to_float(box.p1.x),
+-				   _cairo_fixed_to_float(box.p1.y),
+-				   _cairo_fixed_to_float(box.p2.x),
+-				   _cairo_fixed_to_float(box.p2.y));
+-
+-    if (isSolidAlphaMask) {
+-	brush->SetOpacity(solidAlphaValue);
+-	target_rt->FillRectangle(rect,
+-				 brush);
+-	brush->SetOpacity(1.0);
+-
+-	if (target_rt.get() != d2dsurf->rt.get()) {
+-	    return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip);
+-	}
+-	return CAIRO_INT_STATUS_SUCCESS;
+-    }
+-
+-    RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, mask, true);
+-    if (!opacityBrush) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    if (!d2dsurf->maskLayer) {
+-	d2dsurf->rt->CreateLayer(&d2dsurf->maskLayer);
+-    }
+-    target_rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(),
+-					       0,
+-					       D2D1_ANTIALIAS_MODE_ALIASED,
+-					       D2D1::IdentityMatrix(),
+-					       1.0,
+-					       opacityBrush),
+-			 d2dsurf->maskLayer);
+-
+-    target_rt->FillRectangle(rect,
+-			     brush);
+-    target_rt->PopLayer();
+-
+-    if (target_rt.get() != d2dsurf->rt.get()) {
+-	return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip);
+-    }
+-    return CAIRO_INT_STATUS_SUCCESS;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_stroke(void			*surface,
+-		  cairo_operator_t	 op,
+-		  const cairo_pattern_t	*source,
+-		  cairo_path_fixed_t	*path,
+-		  const cairo_stroke_style_t	*style,
+-		  const cairo_matrix_t	*ctm,
+-		  const cairo_matrix_t	*ctm_inverse,
+-		  double		 tolerance,
+-		  cairo_antialias_t	 antialias,
+-		  cairo_clip_t		*clip)
+-{
+-    cairo_int_status_t status;
+-
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+-
+-    op = _cairo_d2d_simplify_operator(op, source);
+-
+-    if (op == CAIRO_OPERATOR_SOURCE) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    RefPtr<ID2D1RenderTarget> target_rt = d2dsurf->rt;
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    if (op != CAIRO_OPERATOR_OVER) {
+-#endif
+-	target_rt = _cairo_d2d_get_temp_rt(d2dsurf, clip);
+-	if (!target_rt) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    } else {
+-	_begin_draw_state(d2dsurf);
+-	status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, clip);
+-
+-	if (unlikely(status))
+-	    return status;
+-    }
+-#endif
+-
+-    if (antialias == CAIRO_ANTIALIAS_NONE) {
+-	target_rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+-    } else {
+-	target_rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
+-    }
+-    RefPtr<ID2D1StrokeStyle> strokeStyle = _cairo_d2d_create_strokestyle_for_stroke_style(style);
+-
+-    if (!strokeStyle) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-    RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path, 
+-		    							     CAIRO_FILL_RULE_WINDING, 
+-									     D2D1_FIGURE_BEGIN_FILLED);
+-    
+-    bool transformed = true;
+-
+-    if (_cairo_matrix_is_identity(ctm)) {
+-      transformed = false;
+-    }
+-
+-    RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL,
+-								   source);
+-    if (!brush) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    D2D1::Matrix3x2F mat;
+-    if (transformed) {
+-      // If we are transformed we will draw the geometry multiplied by the
+-      // inverse transformation and apply the transform to our render target.
+-      // This way the transformation will also be applied to the strokestyle.
+-      mat = _cairo_d2d_matrix_from_matrix(ctm);
+-      D2D1::Matrix3x2F inverse_mat = _cairo_d2d_invert_matrix(mat);
+-    
+-      RefPtr<ID2D1TransformedGeometry> trans_geom;
+-      sD2DFactory->CreateTransformedGeometry(d2dpath, &inverse_mat, &trans_geom);
+-
+-      // If we are setting a transform on the render target, we've multiplied
+-      // the geometry by the inverse transform, we should also multiply the
+-      // brush matrix by this inverse transform then to map the brush to the
+-      // correct place.
+-      D2D1_MATRIX_3X2_F brushMatrix;
+-      brush->GetTransform(&brushMatrix);
+-      brushMatrix = brushMatrix * inverse_mat;
+-      brush->SetTransform(brushMatrix);
+-      target_rt->SetTransform(mat);
+-      d2dpath = trans_geom;
+-    } else {
+-      mat = D2D1::Matrix3x2F::Identity();
+-    }
+-
+-    target_rt->DrawGeometry(d2dpath, brush, (FLOAT)style->line_width, strokeStyle);
+-
+-    if (transformed) {
+-      target_rt->SetTransform(D2D1::Matrix3x2F::Identity());
+-    }
+-
+-    if (target_rt.get() != d2dsurf->rt.get()) {
+-	D2D1_RECT_F bounds;
+-	d2dpath->GetWidenedBounds((FLOAT)style->line_width, strokeStyle, mat, &bounds);
+-	cairo_rectangle_int_t bound_rect;
+-	_cairo_d2d_round_out_to_int_rect(&bound_rect, bounds.left, bounds.top, bounds.right, bounds.bottom);
+-	return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip, &bound_rect);
+-    }
+-
+-    return CAIRO_INT_STATUS_SUCCESS;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_fill(void			*surface,
+-		cairo_operator_t	 op,
+-		const cairo_pattern_t	*source,
+-		cairo_path_fixed_t	*path,
+-		cairo_fill_rule_t	 fill_rule,
+-		double			 tolerance,
+-		cairo_antialias_t	 antialias,
+-		cairo_clip_t		*clip)
+-{
+-    cairo_int_status_t status;
+-
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+-    cairo_box_t box;
+-    bool is_box = _cairo_path_fixed_is_box(path, &box);
+-
+-    if (is_box && source->type == CAIRO_PATTERN_TYPE_SURFACE) {
+-	const cairo_surface_pattern_t *surf_pattern = 
+-	    reinterpret_cast<const cairo_surface_pattern_t*>(source);
+-	cairo_int_status_t rv = _cairo_d2d_try_fastblit(d2dsurf, surf_pattern->surface,
+-							&box, &source->matrix, clip, op,
+-							source->filter);
+-
+-	if (rv != CAIRO_INT_STATUS_UNSUPPORTED) {
+-	    return rv;
+-	}
+-    }
+-
+-    op = _cairo_d2d_simplify_operator(op, source);
+-
+-    if (op == CAIRO_OPERATOR_SOURCE) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    if (op == CAIRO_OPERATOR_CLEAR) {
+-	if (_cairo_path_fixed_is_box(path, &box)) {
+-	    _begin_draw_state(d2dsurf);
+-	    status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, clip);
+-
+-	    if (unlikely(status))
+-		return status;
+-
+-	    return _cairo_d2d_clear_box (d2dsurf, clip, &box);
+-	} else {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-    }
+-
+-    RefPtr<ID2D1RenderTarget> target_rt = d2dsurf->rt;
+-    
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    if (op != CAIRO_OPERATOR_OVER) {
+-#endif
+-	target_rt = _cairo_d2d_get_temp_rt(d2dsurf, clip);
+-	if (!target_rt) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    } else {
+-	_begin_draw_state(d2dsurf);
+-	status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, clip);
+-
+-	if (unlikely(status))
+-	    return status;
+-    }
+-#endif
+-
+-    if (antialias == CAIRO_ANTIALIAS_NONE) {
+-	target_rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
+-    } else {
+-	target_rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE);
+-    }
+-
+-    if (is_box) {
+-	float x1 = _cairo_fixed_to_float(box.p1.x);
+-	float y1 = _cairo_fixed_to_float(box.p1.y);    
+-	float x2 = _cairo_fixed_to_float(box.p2.x);    
+-	float y2 = _cairo_fixed_to_float(box.p2.y);
+-	RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
+-	    path, source);
+-	if (!brush) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-
+-	target_rt->FillRectangle(D2D1::RectF(x1,
+-					     y1,
+-					     x2,
+-					     y2),
+-				 brush);
+-    } else {
+-	RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
+-
+-	RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
+-            path, source);
+-	if (!brush) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-	target_rt->FillGeometry(d2dpath, brush);
+-    }
+-
+-    if (target_rt.get() != d2dsurf->rt.get()) {
+-	double x1, y1, x2, y2;
+-        cairo_box_t box;
+-        _cairo_path_fixed_extents (path, &box);
+-        x1 = _cairo_fixed_to_double (box.p1.x);
+-        y1 = _cairo_fixed_to_double (box.p1.y);
+-        x2 = _cairo_fixed_to_double (box.p2.x);
+-        y2 = _cairo_fixed_to_double (box.p2.y);
+-	cairo_rectangle_int_t bounds;
+-	_cairo_d2d_round_out_to_int_rect(&bounds, x1, y1, x2, y2);
+-	return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip, &bounds);
+-    }
+-
+-    return CAIRO_INT_STATUS_SUCCESS;
+-}
+-
+-cairo_int_status_t
+-_cairo_dwrite_manual_show_glyphs_on_d2d_surface(void			    *surface,
+-						cairo_operator_t	     op,
+-						const cairo_solid_pattern_t *source,
+-						cairo_glyph_t		    *glyphs,
+-						int			     num_glyphs,
+-						cairo_dwrite_scaled_font_t  *scaled_font,
+-						cairo_clip_t		    *clip)
+-{
+-    cairo_dwrite_scaled_font_t *dwritesf = reinterpret_cast<cairo_dwrite_scaled_font_t*>(scaled_font);
+-    if (!dwritesf->manual_show_glyphs_allowed) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    cairo_dwrite_font_face_t *dwriteff = reinterpret_cast<cairo_dwrite_font_face_t*>(scaled_font->base.font_face);
+-    cairo_d2d_surface_t *dst = reinterpret_cast<cairo_d2d_surface_t*>(surface);
+-
+-    BOOL transform = FALSE;
+-    HRESULT hr;
+-
+-    cairo_region_t *clip_region = NULL;
+-
+-    // We can only draw axis and pixel aligned rectangular quads, this means we
+-    // can only support clips which form regions, since the intersection with
+-    // our text area will then always be a set of rectangular axis and pixel
+-    // aligned quads.
+-    if (clip) {
+-	_cairo_clip_get_region(clip, &clip_region);
+-	if (!clip_region) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-    }
+-
+-    if (!dst->isDrawing) {
+-	_cairo_d2d_flush_dependent_surfaces(dst);
+-    }
+-
+-    _cairo_d2d_set_clip(dst, NULL);
+-    dst->rt->Flush();
+-
+-    AutoDWriteGlyphRun run;
+-    _cairo_dwrite_glyph_run_from_glyphs(glyphs, num_glyphs, scaled_font, &run, &transform);
+-
+-    RefPtr<IDWriteGlyphRunAnalysis> analysis;
+-    DWRITE_MATRIX dwmat = _cairo_dwrite_matrix_from_matrix(&scaled_font->mat);
+-
+-    RefPtr<IDWriteRenderingParams> params;
+-    dst->rt->GetTextRenderingParams(&params);
+-
+-    DWRITE_RENDERING_MODE renderMode = DWRITE_RENDERING_MODE_DEFAULT;
+-    if (params) {
+-	hr = dwriteff->dwriteface->GetRecommendedRenderingMode(
+-						      (FLOAT)scaled_font->base.font_matrix.yy,
+-						      1.0f,
+-						      DWRITE_MEASURING_MODE_NATURAL,
+-						      params,
+-						      &renderMode);
+-	if (FAILED(hr)) {
+-	    // this probably never happens, but let's play it safe
+-	    renderMode = DWRITE_RENDERING_MODE_DEFAULT;
+-	}
+-    }
+-
+-    // Deal with rendering modes CreateGlyphRunAnalysis doesn't accept.
+-    switch (renderMode) {
+-    case DWRITE_RENDERING_MODE_ALIASED:
+-	// ClearType texture creation will fail in this mode, so bail out
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    case DWRITE_RENDERING_MODE_DEFAULT:
+-	// As per DWRITE_RENDERING_MODE documentation, pick Natural for font
+-	// sizes under 16 ppem
+-	if (scaled_font->base.font_matrix.yy < 16.0f) {
+-	    renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
+-	} else {
+-	    renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
+-	}
+-	break;
+-    case DWRITE_RENDERING_MODE_OUTLINE:
+-	renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
+-	break;
+-    default:
+-	break;
+-    }
+-
+-    DWRITE_MEASURING_MODE measureMode =
+-	renderMode <= DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC ? DWRITE_MEASURING_MODE_GDI_CLASSIC :
+-	renderMode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL ? DWRITE_MEASURING_MODE_GDI_NATURAL :
+-	DWRITE_MEASURING_MODE_NATURAL;
+-
+-    hr = DWriteFactory::Instance()->CreateGlyphRunAnalysis(&run,
+-						      1.0f,
+-						      transform ? &dwmat : 0,
+-						      renderMode,
+-						      measureMode,
+-						      0,
+-						      0,
+-						      &analysis);
+-    if (FAILED(hr)) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    RECT bounds;
+-    hr = analysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1,
+-					 &bounds);
+-    if (FAILED(hr) ||
+-	// with bitmap sizes of asian fonts, GetAlphaTextureBounds returns
+-	// an empty rect, so we need to detect that and fall back
+-	(bounds.top == 0 && bounds.bottom == 0 && num_glyphs > 0))
+-    {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    cairo_rectangle_int_t cairo_bounds =
+-	_cairo_rect_from_windows_rect(&bounds);
+-
+-    cairo_region_t *region;
+-    if (clip) {
+-	region = cairo_region_copy(clip_region);
+-
+-	cairo_region_intersect_rectangle(region, &cairo_bounds);
+-    } else {
+-	region = cairo_region_create_rectangle(&cairo_bounds);
+-    }
+-
+-    cairo_region_auto_ptr region_ptr(region);
+-
+-    if (cairo_region_is_empty(region)) {
+-	// Nothing to do.
+-	return CAIRO_INT_STATUS_SUCCESS;
+-    }
+- 
+-    int bufferSize = cairo_bounds.width * cairo_bounds.height * 3;
+-
+-    if (!bufferSize) {
+-	// width == 0 || height == 0
+-	return CAIRO_INT_STATUS_SUCCESS;
+-    }
+-
+-    // We add one byte so we can safely read an entire 32-bit int when copying
+-    // the last 3 bytes of the alpha texture.
+-    BYTE *texture = new BYTE[bufferSize + 1];
+-    hr = analysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1,
+-					&bounds, texture, bufferSize);
+-    if (FAILED(hr)) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    RefPtr<ID3D10ShaderResourceView> srView;
+-    ID3D10Device1 *device = dst->device->mD3D10Device;
+-
+-    int textureWidth, textureHeight;
+-
+-    if (cairo_bounds.width < TEXT_TEXTURE_WIDTH &&
+-	cairo_bounds.height < TEXT_TEXTURE_HEIGHT)
+-    {
+-	// Use our cached TextTexture when it is big enough.
+-	RefPtr<ID3D10Texture2D> tmpTexture;
+-	CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
+-				   cairo_bounds.width, cairo_bounds.height,
+-				   1, 1, 0);
+-
+-	desc.Usage = D3D10_USAGE_STAGING;
+-	desc.CPUAccessFlags = D3D10_CPU_ACCESS_WRITE;
+-				   
+-	hr = device->CreateTexture2D(&desc, NULL, &tmpTexture);
+-
+-	D3D10_MAPPED_TEXTURE2D texMap;
+-	hr = tmpTexture->Map(0, D3D10_MAP_WRITE, 0, &texMap);
+-
+-	if (FAILED(hr)) {
+-	    delete [] texture;
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-
+-	BYTE *alignedTextureData = (BYTE*)texMap.pData;
+-	for (int y = 0; y < cairo_bounds.height; y++) {
+-	    for (int x = 0; x < cairo_bounds.width; x++) {
+-		// Copy 3 Bpp source to 4 Bpp texture.
+-		//
+-		// Since we don't care what ends up in the alpha pixel of the
+-		// destination, therefor we can simply copy a normal 32 bit
+-		// integer each time, filling the alpha pixel of the destination
+-		// with the first subpixel of the next pixel from the source.
+-		*((int*)(alignedTextureData + (y * texMap.RowPitch) + x * 4)) =
+-		    *((int*)(texture + (y * cairo_bounds.width + x) * 3));
+-	    }
+-	}
+-
+-	tmpTexture->Unmap(0);
+-
+-	delete [] texture;
+-
+-	D3D10_BOX box;
+-	box.front = box.top = box.left = 0;
+-	box.back = 1;
+-	box.right = cairo_bounds.width;
+-	box.bottom = cairo_bounds.height;
+-
+-	device->CopySubresourceRegion(dst->device->mTextTexture, 0, 0, 0, 0, tmpTexture, 0, &box);
+-
+-	srView = dst->device->mTextTextureView;
+-
+-	textureWidth = TEXT_TEXTURE_WIDTH;
+-	textureHeight = TEXT_TEXTURE_HEIGHT;
+-    } else {
+-	int alignedBufferSize = cairo_bounds.width * cairo_bounds.height * 4;
+-
+-	// Create a one-off immutable texture from system memory.
+-	BYTE *alignedTextureData = new BYTE[alignedBufferSize];
+-	for (int y = 0; y < cairo_bounds.height; y++) {
+-	    for (int x = 0; x < cairo_bounds.width; x++) {
+-		// Copy 3 Bpp source to 4 Bpp destination memory used for
+-		// texture creation. D3D10 has no 3 Bpp texture format we can
+-		// use.
+-		//
+-		// Since we don't care what ends up in the alpha pixel of the
+-		// destination, therefor we can simply copy a normal 32 bit
+-		// integer each time, filling the alpha pixel of the destination
+-		// with the first subpixel of the next pixel from the source.
+-		*((int*)(alignedTextureData + (y * cairo_bounds.width + x) * 4)) =
+-		    *((int*)(texture + (y * cairo_bounds.width + x) * 3));
+-	    }
+-	}
+-
+-	D3D10_SUBRESOURCE_DATA data;
+-  
+-	CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM,
+-				   cairo_bounds.width, cairo_bounds.height,
+-				   1, 1);
+-	desc.Usage = D3D10_USAGE_IMMUTABLE;
+-
+-	data.SysMemPitch = cairo_bounds.width * 4;
+-	data.pSysMem = alignedTextureData;
+-
+-	RefPtr<ID3D10Texture2D> tex;
+-	hr = device->CreateTexture2D(&desc, &data, &tex);
+-	
+-	delete [] alignedTextureData;
+-	delete [] texture;
+-
+-	if (FAILED(hr)) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-
+-	hr = device->CreateShaderResourceView(tex, NULL, &srView);
+-
+-	if (FAILED(hr)) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-
+-	textureWidth = cairo_bounds.width;
+-	textureHeight = cairo_bounds.height;
+-    }
+-
+-    // Prepare destination surface for rendering.
+-    RefPtr<ID3D10Texture2D> dstTexture;
+-
+-    dst->surface->QueryInterface(&dstTexture);
+-
+-    if (!dst->buffer_rt_view) {
+-	hr = device->CreateRenderTargetView(dstTexture, NULL, &dst->buffer_rt_view);
+-	if (FAILED(hr)) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-    }
+-
+-    D3D10_TEXTURE2D_DESC tDesc;
+-    dstTexture->GetDesc(&tDesc);
+-    D3D10_VIEWPORT vp;
+-    vp.Height = tDesc.Height;
+-    vp.MinDepth = 0;
+-    vp.MaxDepth = 1.0;
+-    vp.TopLeftX = 0;
+-    vp.TopLeftY = 0;
+-    vp.Width = tDesc.Width;
+-    device->RSSetViewports(1, &vp);
+-
+-    ID3D10Effect *effect = dst->device->mSampleEffect;
+-
+-    ID3D10RenderTargetView *rtViewPtr = dst->buffer_rt_view;
+-
+-    device->OMSetRenderTargets(1, &rtViewPtr, 0);
+-
+-    ID3D10EffectTechnique *technique = effect->GetTechniqueByName("SampleTextTexture");
+-
+-    ID3D10EffectVectorVariable *quadDesc = effect->GetVariableByName("QuadDesc")->AsVector();
+-    ID3D10EffectVectorVariable *texCoords = effect->GetVariableByName("TexCoords")->AsVector();
+-    ID3D10EffectVectorVariable *textColor = effect->GetVariableByName("TextColor")->AsVector();
+-
+-    float colorVal[] = { float(source->color.red   * source->color.alpha),
+-			 float(source->color.green * source->color.alpha),
+-			 float(source->color.blue  * source->color.alpha),
+-			 float(source->color.alpha) };
+-    textColor->SetFloatVector(colorVal);
+-
+-    float quadDescVal[4];
+-    float texCoordsVal[4];
+-
+-    // Draw a quad for each rectangle in the intersection of the clip and the
+-    // text area.
+-    for (int i = 0; i < cairo_region_num_rectangles(region); i++) {
+-	cairo_rectangle_int_t quad;
+-	cairo_region_get_rectangle(region, i, &quad);
+-
+-	quadDescVal[0] = -1.0f + ((float)quad.x / (float)tDesc.Width) * 2.0f;
+-	quadDescVal[1] = 1.0f - ((float)quad.y / (float)tDesc.Height) * 2.0f;
+-	quadDescVal[2] = ((float)quad.width / (float)tDesc.Width) * 2.0f;
+-	quadDescVal[3] = -((float)quad.height / (float)tDesc.Height) * 2.0f;
+-	
+-	texCoordsVal[0] = (float)(quad.x - cairo_bounds.x) / textureWidth;
+-	texCoordsVal[1] = (float)(quad.y - cairo_bounds.y) / textureHeight;
+-	texCoordsVal[2] = (float)quad.width / textureWidth;
+-	texCoordsVal[3] = (float)quad.height / textureHeight;
+-
+-	quadDesc->SetFloatVector(quadDescVal);
+-	texCoords->SetFloatVector(texCoordsVal);
+-
+-	_cairo_d2d_setup_for_blend(dst->device);
+-	technique->GetPassByIndex(0)->Apply(0);
+-
+-	ID3D10ShaderResourceView *srViewPtr = srView;
+-	device->PSSetShaderResources(0, 1, &srViewPtr);
+-
+-	device->Draw(4, 0);
+-    }
+-
+-    return CAIRO_INT_STATUS_SUCCESS;
+-}
+-
+-static cairo_int_status_t
+-_cairo_dwrite_show_glyphs_on_d2d_surface(void			*surface,
+-					 cairo_operator_t	 op,
+-					 const cairo_pattern_t	*source,
+-					 cairo_glyph_t		*glyphs,
+-					 int			 num_glyphs,
+-					 cairo_scaled_font_t	*scaled_font,
+-					 cairo_clip_t		*clip)
+-{
+-    cairo_int_status_t status;
+-
+-    // TODO: Check font & surface for types.
+-    cairo_dwrite_scaled_font_t *dwritesf = reinterpret_cast<cairo_dwrite_scaled_font_t*>(scaled_font);
+-    cairo_dwrite_font_face_t *dwriteff = reinterpret_cast<cairo_dwrite_font_face_t*>(scaled_font->font_face);
+-    cairo_d2d_surface_t *dst = reinterpret_cast<cairo_d2d_surface_t*>(surface);
+-
+-    /* We can only handle dwrite fonts */
+-    //XXX: this is checked by at least one caller
+-    if (cairo_scaled_font_get_type (scaled_font) != CAIRO_FONT_TYPE_DWRITE)
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-
+-    op = _cairo_d2d_simplify_operator(op, source);
+-
+-    /* We cannot handle operator SOURCE or CLEAR */
+-    if (op == CAIRO_OPERATOR_SOURCE || op == CAIRO_OPERATOR_CLEAR) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    if (op == CAIRO_OPERATOR_OVER && source->type == CAIRO_PATTERN_TYPE_SOLID &&
+-	dst->base.content != CAIRO_CONTENT_COLOR &&
+-	dst->base.permit_subpixel_antialiasing &&
+-	dwritesf->antialias_mode == CAIRO_ANTIALIAS_SUBPIXEL)
+-    {
+-	// The D2D/DWrite drawing API's will not allow drawing subpixel AA to
+-	// an RGBA surface. We do however want to do this if we know all text
+-	// on a surface will be over opaque pixels, when this is the case
+-	// we set the permit_subpixel_antialiasing flag on a surface. We then
+-	// proceed to manually composite the glyphs to the surface.
+-
+-	const cairo_solid_pattern_t *solid_src =
+-	    reinterpret_cast<const cairo_solid_pattern_t*>(source);
+-	status = _cairo_dwrite_manual_show_glyphs_on_d2d_surface(surface,
+-								 op,
+-								 solid_src,
+-								 glyphs,
+-								 num_glyphs,
+-								 dwritesf,
+-								 clip);
+-
+-	if (status != CAIRO_INT_STATUS_UNSUPPORTED) {
+-	    return status;
+-	}
+-    }
+-
+-    RefPtr<ID2D1RenderTarget> target_rt = dst->rt;
+-    cairo_rectangle_int_t fontArea;
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    if (op != CAIRO_OPERATOR_OVER) {
+-#endif
+-	target_rt = _cairo_d2d_get_temp_rt(dst, clip);
+-
+-	if (!target_rt) {
+-	    return CAIRO_INT_STATUS_UNSUPPORTED;
+-	}
+-#ifndef ALWAYS_MANUAL_COMPOSITE
+-    } else {
+-	_begin_draw_state(dst);
+-	status = (cairo_int_status_t)_cairo_d2d_set_clip (dst, clip);
+-
+-	if (unlikely(status))
+-	    return status;
+-    }
+-#endif
+-
+-    D2D1_TEXT_ANTIALIAS_MODE cleartype_quality = D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE;
+-
+-    // If we're rendering to a temporary surface we cannot do sub-pixel AA.
+-    if (dst->base.content != CAIRO_CONTENT_COLOR || dst->rt.get() != target_rt.get()) {
+-	cleartype_quality = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
+-    }
+-
+-    RefPtr<IDWriteRenderingParams> params;
+-    target_rt->GetTextRenderingParams(&params);
+-
+-    DWRITE_RENDERING_MODE renderMode = DWRITE_RENDERING_MODE_DEFAULT;
+-    if (params) {
+-	HRESULT hr = dwriteff->dwriteface->GetRecommendedRenderingMode(
+-						      (FLOAT)dwritesf->base.font_matrix.yy,
+-						      1.0f,
+-						      DWRITE_MEASURING_MODE_NATURAL,
+-						      params,
+-						      &renderMode);
+-	if (FAILED(hr)) {
+-	    // this probably never happens, but let's play it safe
+-	    renderMode = DWRITE_RENDERING_MODE_DEFAULT;
+-	}
+-    }
+-
+-    // Deal with rendering modes CreateGlyphRunAnalysis doesn't accept
+-    switch (renderMode) {
+-    case DWRITE_RENDERING_MODE_DEFAULT:
+-	// As per DWRITE_RENDERING_MODE documentation, pick Natural for font
+-	// sizes under 16 ppem
+-  	if (dwritesf->base.font_matrix.yy < 16.0f) {
+-	    renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL;
+-	} else {
+-	    renderMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
+-	}
+-	break;
+-    case DWRITE_RENDERING_MODE_OUTLINE:
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    default:
+-	break;
+-    }
+-
+-    switch (dwritesf->antialias_mode) {
+-    case CAIRO_ANTIALIAS_NONE:
+-	cleartype_quality = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
+-	break;
+-    case CAIRO_ANTIALIAS_GRAY:
+-	cleartype_quality = D2D1_TEXT_ANTIALIAS_MODE_GRAYSCALE;
+-	break;
+-    case CAIRO_ANTIALIAS_SUBPIXEL:
+-	break;
+-    }
+-
+-    if (renderMode == DWRITE_RENDERING_MODE_ALIASED) {
+-	cleartype_quality = D2D1_TEXT_ANTIALIAS_MODE_ALIASED;
+-    }
+-
+-    target_rt->SetTextAntialiasMode(cleartype_quality);
+-
+-    DWRITE_MEASURING_MODE measureMode =
+-	renderMode <= DWRITE_RENDERING_MODE_CLEARTYPE_GDI_CLASSIC ? DWRITE_MEASURING_MODE_GDI_CLASSIC :
+-	renderMode == DWRITE_RENDERING_MODE_CLEARTYPE_GDI_NATURAL ? DWRITE_MEASURING_MODE_GDI_NATURAL :
+-	DWRITE_MEASURING_MODE_NATURAL;
+-
+-    cairo_bool_t transform = FALSE;
+-
+-    AutoDWriteGlyphRun run;
+-    _cairo_dwrite_glyph_run_from_glyphs(glyphs, num_glyphs, dwritesf, &run, &transform);
+-
+-    D2D1::Matrix3x2F mat = _cairo_d2d_matrix_from_matrix(&dwritesf->mat);
+-	
+-    if (transform) {
+-	target_rt->SetTransform(mat);
+-    }
+-
+-    if (dst->rt.get() != target_rt.get()) {
+-	RefPtr<IDWriteGlyphRunAnalysis> analysis;
+-	DWRITE_MATRIX dwmat = _cairo_dwrite_matrix_from_matrix(&dwritesf->mat);
+-	DWriteFactory::Instance()->CreateGlyphRunAnalysis(&run,
+-							  1.0f,
+-							  transform ? &dwmat : 0,
+-							  renderMode,
+-							  measureMode,
+-							  0,
+-							  0,
+-							  &analysis);
+-
+-	RECT bounds;
+-	analysis->GetAlphaTextureBounds(scaled_font->options.antialias == CAIRO_ANTIALIAS_NONE ?
+-					DWRITE_TEXTURE_ALIASED_1x1 : DWRITE_TEXTURE_CLEARTYPE_3x1,
+-					&bounds);
+-	fontArea.x = bounds.left;
+-	fontArea.y = bounds.top;
+-	fontArea.width = bounds.right - bounds.left;
+-	fontArea.height = bounds.bottom - bounds.top;
+-    }
+-
+-    RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(dst, NULL,
+-								   source);
+-
+-    if (!brush) {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-    
+-    if (transform) {
+-	D2D1::Matrix3x2F mat_inverse = _cairo_d2d_matrix_from_matrix(&dwritesf->mat_inverse);
+-	D2D1::Matrix3x2F mat_brush;
+-
+-	// The brush matrix needs to be multiplied with the inverted matrix
+-	// as well, to move the brush into the space of the glyphs. Before
+-	// the render target transformation.
+-	brush->GetTransform(&mat_brush);
+-	mat_brush = mat_brush * mat_inverse;
+-	brush->SetTransform(&mat_brush);
+-    }
+-    
+-    target_rt->DrawGlyphRun(D2D1::Point2F(0, 0), &run, brush, measureMode);
+-    
+-    if (transform) {
+-	target_rt->SetTransform(D2D1::Matrix3x2F::Identity());
+-    }
+-
+-    if (target_rt.get() != dst->rt.get()) {
+-	return _cairo_d2d_blend_temp_surface(dst, op, target_rt, clip, &fontArea);
+-    }
+-
+-    return CAIRO_INT_STATUS_SUCCESS;
+-}
+-
+-static cairo_int_status_t
+-_cairo_d2d_show_glyphs (void			*surface,
+-			cairo_operator_t	 op,
+-			const cairo_pattern_t	*source,
+-			cairo_glyph_t		*glyphs,
+-			int			 num_glyphs,
+-			cairo_scaled_font_t	*scaled_font,
+-			cairo_clip_t            *clip,
+-			int			*remaining_glyphs)
+-{
+-    if (((cairo_surface_t*)surface)->type != CAIRO_SURFACE_TYPE_D2D ||
+-        scaled_font->backend->type != CAIRO_FONT_TYPE_DWRITE)
+-    {
+-	return CAIRO_INT_STATUS_UNSUPPORTED;
+-    }
+-
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+-    cairo_d2d_surface_t::TextRenderingState textRenderingState =
+-        reinterpret_cast<cairo_dwrite_scaled_font_t*>(scaled_font)->rendering_mode;
+-    if (d2dsurf->textRenderingState != textRenderingState) {
+-	RefPtr<IDWriteRenderingParams> params =
+-	    DWriteFactory::RenderingParams(textRenderingState);
+-	d2dsurf->rt->SetTextRenderingParams(params);
+-	d2dsurf->textRenderingState = textRenderingState;
+-    }
+-    cairo_int_status_t status = (cairo_int_status_t)
+-        _cairo_dwrite_show_glyphs_on_d2d_surface(surface, op, source, glyphs, num_glyphs, scaled_font, clip);
+-
+-    return status;
+-}
+-
+-
+-static cairo_bool_t
+-_cairo_d2d_getextents(void		       *surface,
+-		      cairo_rectangle_int_t    *extents)
+-{
+-    cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface);
+-    extents->x = 0;
+-    extents->y = 0;
+-    D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize(); 
+-    extents->width = size.width;
+-    extents->height = size.height;
+-    return TRUE;
+-}
+-
+-
+-/** Helper functions. */
+-
+-
+-
+-cairo_surface_t*
+-cairo_d2d_surface_create_for_hwnd(cairo_device_t *cairo_device,
+-				  HWND wnd,
+-				  cairo_content_t content)
+-{
+-    cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(cairo_device);
+-    cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
+-    new (newSurf) cairo_d2d_surface_t();
+-
+-    _cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
+-
+-    RECT rc;
+-    HRESULT hr;
+-
+-    newSurf->isDrawing = false;
+-    ::GetClientRect(wnd, &rc);
+-
+-    FLOAT dpiX;
+-    FLOAT dpiY;
+-    D2D1_SIZE_U sizePixels;
+-    D2D1_SIZE_F size;
+-
+-    dpiX = 96;
+-    dpiY = 96;
+-
+-
+-    sizePixels.width = rc.right - rc.left;
+-    sizePixels.height = rc.bottom - rc.top;
+-
+-    if (!sizePixels.width) {
+-	sizePixels.width = 1;
+-    }
+-    if (!sizePixels.height) {
+-	sizePixels.height = 1;
+-    }
+-    ID3D10Device1 *device = d2d_device->mD3D10Device;
+-    RefPtr<IDXGIDevice> dxgiDevice;
+-    RefPtr<IDXGIAdapter> dxgiAdapter;
+-    RefPtr<IDXGIFactory> dxgiFactory;
+-    D2D1_RENDER_TARGET_PROPERTIES props;    
+-    D2D1_BITMAP_PROPERTIES bitProps;
+-
+-    device->QueryInterface(&dxgiDevice);
+-    dxgiDevice->GetAdapter(&dxgiAdapter);
+-    dxgiAdapter->GetParent(IID_PPV_ARGS(&dxgiFactory));
+-
+-    DXGI_SWAP_CHAIN_DESC swapDesc;
+-    ::ZeroMemory(&swapDesc, sizeof(swapDesc));
+-
+-    swapDesc.BufferDesc.Width = sizePixels.width;
+-    swapDesc.BufferDesc.Height = sizePixels.height;
+-    swapDesc.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
+-    swapDesc.BufferDesc.RefreshRate.Numerator = 60;
+-    swapDesc.BufferDesc.RefreshRate.Denominator = 1;
+-    swapDesc.SampleDesc.Count = 1;
+-    swapDesc.SampleDesc.Quality = 0;
+-    swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
+-    swapDesc.BufferCount = 1;
+-    swapDesc.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;
+-    swapDesc.OutputWindow = wnd;
+-    swapDesc.Windowed = TRUE;
+-
+-    /**
+-     * Create a swap chain, this swap chain will contain the backbuffer for
+-     * the window we draw to. The front buffer is the full screen front
+-     * buffer.
+-     */
+-    hr = dxgiFactory->CreateSwapChain(dxgiDevice, &swapDesc, &newSurf->dxgiChain);
+-
+-    /**
+-     * We do not want DXGI to intercept alt-enter events and make the window go
+-     * fullscreen! This shouldn't be in the cairo backend but controlled through
+-     * the device. See comments on mozilla bug 553603.
+-     */
+-    dxgiFactory->MakeWindowAssociation(wnd, DXGI_MWA_NO_WINDOW_CHANGES);
+-
+-    if (FAILED(hr)) {
+-	goto FAIL_HWND;
+-    }
+-    /** Get the backbuffer surface from the swap chain */
+-    hr = newSurf->dxgiChain->GetBuffer(0,
+-				       IID_PPV_ARGS(&newSurf->surface));
+-
+-    if (FAILED(hr)) {
+-	goto FAIL_HWND;
+-    }
+-
+-    newSurf->surface->QueryInterface(&newSurf->backBuf);
+-
+-    size.width = sizePixels.width * dpiX;
+-    size.height = sizePixels.height * dpiY;
+-
+-    props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
+-					 D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED),
+-					 dpiX,
+-					 dpiY,
+-					 D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE);
+-    hr = sD2DFactory->CreateDxgiSurfaceRenderTarget(newSurf->backBuf,
+-								   props,
+-								   &newSurf->rt);
+-    if (FAILED(hr)) {
+-	goto FAIL_HWND;
+-    }
+-
+-    bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, 
+-				      D2D1_ALPHA_MODE_PREMULTIPLIED));
+-    
+-    newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
+-
+-    _d2d_clear_surface(newSurf);
+-
+-    _cairo_d2d_surface_init(newSurf, d2d_device, _cairo_format_from_content(content));
+-
+-    return reinterpret_cast<cairo_surface_t*>(newSurf);
+-
+-FAIL_HWND:
+-    newSurf->~cairo_d2d_surface_t();
+-    free(newSurf);
+-    return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+-}
+-
+-
+-
+-cairo_surface_t *
+-cairo_d2d_surface_create(cairo_device_t *device,
+-			 cairo_format_t format,
+-			 int width,
+-			 int height)
+-{
+-    if (width == 0 || height == 0) {
+-	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_INVALID_SIZE));
+-    }
+-
+-    cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
+-    cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
+-    new (newSurf) cairo_d2d_surface_t();
+-
+-    DXGI_FORMAT dxgiformat = DXGI_FORMAT_B8G8R8A8_UNORM;
+-    D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
+-    if (format == CAIRO_FORMAT_ARGB32) {
+-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_COLOR_ALPHA);
+-    } else if (format == CAIRO_FORMAT_RGB24) {
+-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_COLOR);
+-	alpha = D2D1_ALPHA_MODE_IGNORE;
+-    } else {
+-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_ALPHA);
+-	dxgiformat = DXGI_FORMAT_A8_UNORM;
+-    }
+-
+-
+-    newSurf->format = format;
+-
+-    D2D1_SIZE_U sizePixels;
+-    HRESULT hr;
+-
+-    sizePixels.width = width;
+-    sizePixels.height = height;
+-
+-    CD3D10_TEXTURE2D_DESC desc(
+-	dxgiformat,
+-	sizePixels.width,
+-	sizePixels.height
+-	);
+-    desc.MipLevels = 1;
+-    desc.Usage = D3D10_USAGE_DEFAULT;
+-    desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
+-
+-    /* CreateTexture2D does not support D3D10_RESOURCE_MISC_GDI_COMPATIBLE with DXGI_FORMAT_A8_UNORM */
+-    if (desc.Format != DXGI_FORMAT_A8_UNORM)
+-	desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
+-
+-    RefPtr<ID3D10Texture2D> texture;
+-    RefPtr<IDXGISurface> dxgiSurface;
+-    D2D1_BITMAP_PROPERTIES bitProps;
+-    D2D1_RENDER_TARGET_PROPERTIES props;
+-
+-    hr = d2d_device->mD3D10Device->CreateTexture2D(&desc, NULL, &texture);
+-
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATE;
+-    }
+-
+-    newSurf->surface = texture;
+-
+-    /** Create the DXGI surface. */
+-    hr = newSurf->surface->QueryInterface(IID_IDXGISurface, (void**)&dxgiSurface);
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATE;
+-    }
+-
+-    props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
+-					 D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, alpha));
+-
+-    if (desc.MiscFlags & D3D10_RESOURCE_MISC_GDI_COMPATIBLE)
+-	props.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
+-
+-    hr = sD2DFactory->CreateDxgiSurfaceRenderTarget(dxgiSurface,
+-								   props,
+-								   &newSurf->rt);
+-
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATE;
+-    }
+-
+-    bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, 
+-				      alpha));
+-
+-    if (dxgiformat != DXGI_FORMAT_A8_UNORM) {
+-	/* For some reason creation of shared bitmaps for A8 UNORM surfaces
+-	 * doesn't work even though the documentation suggests it does. The
+-	 * function will return an error if we try */
+-	hr = newSurf->rt->CreateSharedBitmap(IID_IDXGISurface,
+-					     dxgiSurface,
+-					     &bitProps,
+-					     &newSurf->surfaceBitmap);
+-
+-	if (FAILED(hr)) {
+-	    goto FAIL_CREATE;
+-	}
+-    }
+-
+-    newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
+-
+-    _d2d_clear_surface(newSurf);
+-
+-    _cairo_d2d_surface_init(newSurf, d2d_device, format);
+-
+-    return reinterpret_cast<cairo_surface_t*>(newSurf);
+-
+-FAIL_CREATE:
+-    newSurf->~cairo_d2d_surface_t();
+-    free(newSurf);
+-    return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+-}
+-
+-cairo_surface_t *
+-cairo_d2d_surface_create_for_handle(cairo_device_t *device, HANDLE handle, cairo_content_t content)
+-{
+-    if (!device) {
+-	return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_DEVICE));
+-    }
+-
+-    cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
+-    cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
+-    new (newSurf) cairo_d2d_surface_t();
+-
+-    cairo_status_t status = CAIRO_STATUS_NO_MEMORY;
+-    HRESULT hr;
+-    RefPtr<ID3D10Texture2D> texture;
+-    RefPtr<IDXGISurface> dxgiSurface;
+-    D2D1_BITMAP_PROPERTIES bitProps;
+-    D2D1_RENDER_TARGET_PROPERTIES props;
+-    DXGI_FORMAT format;
+-    DXGI_SURFACE_DESC desc;
+-    D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
+-
+-    hr = d2d_device->mD3D10Device->OpenSharedResource(handle,
+-						      __uuidof(ID3D10Resource),
+-						      (void**)&newSurf->surface);
+-
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATEHANDLE;
+-    }
+-
+-    hr = newSurf->surface->QueryInterface(&dxgiSurface);
+-
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATEHANDLE;
+-    }
+-
+-    dxgiSurface->GetDesc(&desc);
+-    format = desc.Format;
+-    
+-    if (format == DXGI_FORMAT_B8G8R8A8_UNORM) {
+-	if (content == CAIRO_CONTENT_ALPHA) {
+-	    status = CAIRO_STATUS_INVALID_CONTENT;
+-	    goto FAIL_CREATEHANDLE;
+-	}
+-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
+-	if (content == CAIRO_CONTENT_COLOR) {
+-	    alpha = D2D1_ALPHA_MODE_IGNORE;
+-	}
+-    } else if (format == DXGI_FORMAT_A8_UNORM) {
+-	if (content != CAIRO_CONTENT_ALPHA) {
+-	    status = CAIRO_STATUS_INVALID_CONTENT;
+-	    goto FAIL_CREATEHANDLE;
+-	}
+-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_ALPHA);
+-    } else {
+-	status = CAIRO_STATUS_INVALID_FORMAT;
+-	// We don't know how to support this format!
+-	goto FAIL_CREATEHANDLE;
+-    }
+-
+-    props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
+-					 D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, alpha));
+-
+-    hr = sD2DFactory->CreateDxgiSurfaceRenderTarget(dxgiSurface,
+-						    props,
+-						    &newSurf->rt);
+-
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATEHANDLE;
+-    }
+-
+-    bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, 
+-				      alpha));
+-
+-    if (format != DXGI_FORMAT_A8_UNORM) {
+-	/* For some reason creation of shared bitmaps for A8 UNORM surfaces
+-	 * doesn't work even though the documentation suggests it does. The
+-	 * function will return an error if we try */
+-	hr = newSurf->rt->CreateSharedBitmap(IID_IDXGISurface,
+-					     dxgiSurface,
+-					     &bitProps,
+-					     &newSurf->surfaceBitmap);
+-
+-	if (FAILED(hr)) {
+-	    goto FAIL_CREATEHANDLE;
+-	}
+-    }
+-
+-    newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
+-
+-    _cairo_d2d_surface_init(newSurf, d2d_device, _cairo_format_from_content(content));
+-
+-    return &newSurf->base;
+-   
+-FAIL_CREATEHANDLE:
+-    newSurf->~cairo_d2d_surface_t();
+-    free(newSurf);
+-    return _cairo_surface_create_in_error(_cairo_error(status));
+-}
+-
+-cairo_surface_t *
+-cairo_d2d_surface_create_for_texture(cairo_device_t *device,
+-				     ID3D10Texture2D *texture,
+-				     cairo_content_t content)
+-{
+-    cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
+-    cairo_d2d_surface_t *newSurf = static_cast<cairo_d2d_surface_t*>(malloc(sizeof(cairo_d2d_surface_t)));
+-    new (newSurf) cairo_d2d_surface_t();
+-
+-    D2D1_ALPHA_MODE alpha = D2D1_ALPHA_MODE_PREMULTIPLIED;
+-    if (content == CAIRO_CONTENT_COLOR) {
+-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, CAIRO_CONTENT_COLOR);
+-	alpha = D2D1_ALPHA_MODE_IGNORE;
+-    } else {
+-	_cairo_surface_init(&newSurf->base, &cairo_d2d_surface_backend, NULL, content);
+-    }
+-
+-    D2D1_SIZE_U sizePixels;
+-    HRESULT hr;
+-
+-    D3D10_TEXTURE2D_DESC desc;
+-    RefPtr<IDXGISurface> dxgiSurface;
+-    D2D1_BITMAP_PROPERTIES bitProps;
+-    D2D1_RENDER_TARGET_PROPERTIES props;
+-
+-    texture->GetDesc(&desc);
+-
+-    sizePixels.width = desc.Width;
+-    sizePixels.height = desc.Height;
+-
+-    newSurf->surface = texture;
+-
+-    /** Create the DXGI surface. */
+-    hr = newSurf->surface->QueryInterface(IID_IDXGISurface, (void**)&dxgiSurface);
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATE;
+-    }
+-
+-    props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
+-					 D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, alpha));
+-
+-    if (desc.MiscFlags & D3D10_RESOURCE_MISC_GDI_COMPATIBLE)
+-	props.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
+-
+-    hr = sD2DFactory->CreateDxgiSurfaceRenderTarget(dxgiSurface,
+-						    props,
+-						    &newSurf->rt);
+-
+-    if (FAILED(hr)) {
+-	goto FAIL_CREATE;
+-    }
+-
+-    bitProps = D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, 
+-				      alpha));
+-
+-    if (content != CAIRO_CONTENT_ALPHA) {
+-	/* For some reason creation of shared bitmaps for A8 UNORM surfaces
+-	 * doesn't work even though the documentation suggests it does. The
+-	 * function will return an error if we try */
+-	hr = newSurf->rt->CreateSharedBitmap(IID_IDXGISurface,
+-					     dxgiSurface,
+-					     &bitProps,
+-					     &newSurf->surfaceBitmap);
+-
+-	if (FAILED(hr)) {
+-	    goto FAIL_CREATE;
+-	}
+-    }
+-
+-    newSurf->rt->CreateSolidColorBrush(D2D1::ColorF(0, 1.0), &newSurf->solidColorBrush);
+-
+-    _cairo_d2d_surface_init(newSurf, d2d_device, _cairo_format_from_content(content));
+-
+-    return reinterpret_cast<cairo_surface_t*>(newSurf);
+-
+-FAIL_CREATE:
+-    newSurf->~cairo_d2d_surface_t();
+-    free(newSurf);
+-    return _cairo_surface_create_in_error(_cairo_error(CAIRO_STATUS_NO_MEMORY));
+-}
+-
+-ID3D10Texture2D*
+-cairo_d2d_surface_get_texture(cairo_surface_t *surface)
+-{
+-    if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
+-        return NULL;
+-    }
+-
+-    cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
+-
+-    RefPtr<ID3D10Texture2D> texture;
+-    d2dsurf->surface->QueryInterface(&texture);
+-
+-    return texture;
+-}
+-
+-void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip)
+-{
+-    if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
+-	return;
+-    }
+-    cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
+-
+-    /** For now, we invalidate our storing texture with this operation. */
+-    D2D1_POINT_2U point;
+-    D3D10_BOX rect;
+-    rect.front = 0;
+-    rect.back = 1;
+-
+-    RefPtr<IDXGISurface> dxgiSurface;
+-    d2dsurf->surface->QueryInterface(&dxgiSurface);
+-    DXGI_SURFACE_DESC desc;
+-
+-    dxgiSurface->GetDesc(&desc);
+-
+-    /**
+-     * It's important we constrain the size of the clip region to the area of
+-     * the surface. If we don't we might get a box that goes outside the
+-     * surface, and CopySubresourceRegion will become very angry with us.
+-     * It will cause a device failure and subsequent drawing will break.
+-     */
+-    clip->x = MAX(clip->x, 0);
+-    clip->y = MAX(clip->y, 0);
+-    clip->width = MIN(clip->width, desc.Width - clip->x);
+-    clip->height = MIN(clip->height, desc.Height - clip->y);
+-
+-    if (x < 0) {
+-	point.x = (UINT32)clip->x;
+-	rect.left = (UINT)(clip->x - x);
+-	rect.right = (UINT)(clip->x + clip->width);
+-    } else {
+-	point.x = (UINT32)(clip->x + x);
+-	rect.left = (UINT)clip->x;
+-	rect.right = (UINT32)(clip->x + clip->width - x);
+-    }
+-    if (y < 0) {
+-	point.y = (UINT32)clip->y;
+-	rect.top = (UINT)(clip->y - y);
+-	rect.bottom = (UINT)(clip->y + clip->height);
+-    } else {
+-	point.y = (UINT32)(clip->y + y);
+-	rect.top = (UINT)clip->y;
+-	rect.bottom = (UINT)(clip->y + clip->height - y);
+-    }
+-    ID3D10Texture2D *texture = _cairo_d2d_get_buffer_texture(d2dsurf);
+-
+-    d2dsurf->device->mD3D10Device->CopyResource(texture, d2dsurf->surface);
+-    d2dsurf->device->mD3D10Device->CopySubresourceRegion(d2dsurf->surface,
+-						  0,
+-						  point.x,
+-						  point.y,
+-						  0,
+-						  texture,
+-						  0,
+-						  &rect);
+-
+-}
+-
+-HDC
+-cairo_d2d_get_dc(cairo_surface_t *surface, cairo_bool_t retain_contents)
+-{
+-    if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
+-	return NULL;
+-    }
+-    cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
+-
+-    /* We'll pop the clip here manually so that we'll stay in drawing state if we
+-     * already are, we need to ensure d2dsurf->isDrawing manually then though 
+-     */
+-
+-    /* Clips aren't allowed as per MSDN docs */
+-    reset_clip(d2dsurf);
+-
+-    if (!d2dsurf->isDrawing) {
+-      /* GetDC must be called between BeginDraw/EndDraw */
+-      d2dsurf->rt->BeginDraw();
+-      d2dsurf->isDrawing = true;
+-    }
+-
+-    RefPtr<ID2D1GdiInteropRenderTarget> interopRT;
+-
+-    /* This QueryInterface call will always succeed even if the
+-     * the render target doesn't support the ID2D1GdiInteropRenderTarget
+-     * interface */
+-    d2dsurf->rt->QueryInterface(&interopRT);
+-
+-    HDC dc;
+-    HRESULT rv;
+-
+-    rv = interopRT->GetDC(retain_contents ? D2D1_DC_INITIALIZE_MODE_COPY :
+-	D2D1_DC_INITIALIZE_MODE_CLEAR, &dc);
+-
+-    if (FAILED(rv)) {
+-	return NULL;
+-    }
+-
+-    return dc;
+-}
+-
+-void
+-cairo_d2d_release_dc(cairo_surface_t *surface, const cairo_rectangle_int_t *updated_rect)
+-{
+-    if (surface->type != CAIRO_SURFACE_TYPE_D2D) {
+-	return;
+-    }
+-    cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
+-
+-    RefPtr<ID2D1GdiInteropRenderTarget> interopRT;
+-
+-    d2dsurf->rt->QueryInterface(&interopRT);
+-
+-    if (!updated_rect) {
+-	interopRT->ReleaseDC(NULL);
+-	return;
+-    }
+-    
+-    RECT r;
+-    r.left = updated_rect->x;
+-    r.top = updated_rect->y;
+-    r.right = r.left + updated_rect->width;
+-    r.bottom = r.top + updated_rect->height;
+-
+-    interopRT->ReleaseDC(&r);
+-}
+-
+-int
+-cairo_d2d_get_image_surface_cache_usage()
+-{
+-  return _cairo_atomic_int_get(&cache_usage);
+-}
+-
+-int
+-cairo_d2d_get_surface_vram_usage(cairo_device_t *device)
+-{
+-    cairo_d2d_device_t *d2d_device = reinterpret_cast<cairo_d2d_device_t*>(device);
+-    return d2d_device->mVRAMUsage;
+-}
+-
+-int
+-cairo_d2d_surface_get_width(cairo_surface_t *surface)
+-{
+-    if (surface->backend != &cairo_d2d_surface_backend) {
+-	    _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+-	    return 0;
+-    }
+-
+-    cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
+-    D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize();
+-    return size.width;
+-}
+-
+-int
+-cairo_d2d_surface_get_height(cairo_surface_t *surface)
+-{
+-    if (surface->backend != &cairo_d2d_surface_backend) {
+-	    _cairo_error_throw (CAIRO_STATUS_SURFACE_TYPE_MISMATCH);
+-	    return 0;
+-    }
+-
+-    cairo_d2d_surface_t *d2dsurf = reinterpret_cast<cairo_d2d_surface_t*>(surface);
+-    D2D1_SIZE_U size = d2dsurf->rt->GetPixelSize();
+-    return size.height;
+-}
+diff --git a/gfx/cairo/cairo/src/cairo-dwrite-font.cpp b/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
+--- a/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
++++ b/gfx/cairo/cairo/src/cairo-dwrite-font.cpp
+@@ -34,18 +34,18 @@
+  *	Bas Schouten <bschouten@mozilla.com>
+  */
+ 
+ #include "cairoint.h"
+ 
+ #include "cairo-win32-private.h"
+ #include "cairo-surface-private.h"
+ #include "cairo-clip-private.h"
+-
+-#include "cairo-d2d-private.h"
++#include "cairo-win32-refptr.h"
++
+ #include "cairo-dwrite-private.h"
+ #include "cairo-truetype-subset-private.h"
+ #include <float.h>
+ 
+ typedef HRESULT (WINAPI*D2D1CreateFactoryFunc)(
+     D2D1_FACTORY_TYPE factoryType,
+     REFIID iid,
+     CONST D2D1_FACTORY_OPTIONS *pFactoryOptions,
+@@ -505,17 +505,17 @@ static cairo_status_t
+ 	dwriteFont->antialias_mode = default_quality;
+     } else {
+ 	dwriteFont->antialias_mode = options->antialias;
+     }
+ 
+     dwriteFont->manual_show_glyphs_allowed = TRUE;
+     dwriteFont->rendering_mode =
+         default_quality == CAIRO_ANTIALIAS_SUBPIXEL ?
+-            cairo_d2d_surface_t::TEXT_RENDERING_NORMAL : cairo_d2d_surface_t::TEXT_RENDERING_NO_CLEARTYPE;
++            cairo_dwrite_scaled_font_t::TEXT_RENDERING_NORMAL : cairo_dwrite_scaled_font_t::TEXT_RENDERING_NO_CLEARTYPE;
+ 
+     return _cairo_scaled_font_set_metrics (*font, &extents);
+ }
+ 
+ /* Implementation cairo_dwrite_scaled_font_backend_t */
+ void
+ _cairo_dwrite_scaled_font_fini(void *scaled_font)
+ {
+@@ -1096,28 +1096,28 @@ cairo_dwrite_scaled_font_allow_manual_sh
+     cairo_dwrite_scaled_font_t *font = reinterpret_cast<cairo_dwrite_scaled_font_t*>(dwrite_scaled_font);
+     font->manual_show_glyphs_allowed = allowed;
+ }
+ 
+ void
+ cairo_dwrite_scaled_font_set_force_GDI_classic(cairo_scaled_font_t *dwrite_scaled_font, cairo_bool_t force)
+ {
+     cairo_dwrite_scaled_font_t *font = reinterpret_cast<cairo_dwrite_scaled_font_t*>(dwrite_scaled_font);
+-    if (force && font->rendering_mode == cairo_d2d_surface_t::TEXT_RENDERING_NORMAL) {
+-        font->rendering_mode = cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC;
+-    } else if (!force && font->rendering_mode == cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC) {
+-        font->rendering_mode = cairo_d2d_surface_t::TEXT_RENDERING_NORMAL;
++    if (force && font->rendering_mode == cairo_dwrite_scaled_font_t::TEXT_RENDERING_NORMAL) {
++        font->rendering_mode = cairo_dwrite_scaled_font_t::TEXT_RENDERING_GDI_CLASSIC;
++    } else if (!force && font->rendering_mode == cairo_dwrite_scaled_font_t::TEXT_RENDERING_GDI_CLASSIC) {
++        font->rendering_mode = cairo_dwrite_scaled_font_t::TEXT_RENDERING_NORMAL;
+     }
+ }
+ 
+ cairo_bool_t
+ cairo_dwrite_scaled_font_get_force_GDI_classic(cairo_scaled_font_t *dwrite_scaled_font)
+ {
+     cairo_dwrite_scaled_font_t *font = reinterpret_cast<cairo_dwrite_scaled_font_t*>(dwrite_scaled_font);
+-    return font->rendering_mode == cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC;
++    return font->rendering_mode == cairo_dwrite_scaled_font_t::TEXT_RENDERING_GDI_CLASSIC;
+ }
+ 
+ void
+ cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level,
+ 				  int geometry, int mode)
+ {
+     DWriteFactory::SetRenderingParams(gamma, contrast, level, geometry, mode);
+ }
+@@ -1136,36 +1136,36 @@ cairo_int_status_t
+ 				       cairo_dwrite_scaled_font_t *scaled_font,
+ 				       const RECT &area)
+ {
+     IDWriteGdiInterop *gdiInterop;
+     DWriteFactory::Instance()->GetGdiInterop(&gdiInterop);
+     IDWriteBitmapRenderTarget *rt;
+     HRESULT rv;
+ 
+-    cairo_d2d_surface_t::TextRenderingState renderingState =
++    cairo_dwrite_scaled_font_t::TextRenderingState renderingState =
+       scaled_font->rendering_mode;
+ 
+     rv = gdiInterop->CreateBitmapRenderTarget(surface->dc,
+ 					      area.right - area.left,
+ 					      area.bottom - area.top,
+ 					      &rt);
+ 
+     if (FAILED(rv)) {
+ 	if (rv == E_OUTOFMEMORY) {
+ 	    return (cairo_int_status_t)CAIRO_STATUS_NO_MEMORY;
+ 	} else {
+ 	    return CAIRO_INT_STATUS_UNSUPPORTED;
+ 	}
+     }
+ 
+-    if ((renderingState == cairo_d2d_surface_t::TEXT_RENDERING_NORMAL ||
+-         renderingState == cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC) &&
++    if ((renderingState == cairo_dwrite_scaled_font_t::TEXT_RENDERING_NORMAL ||
++         renderingState == cairo_dwrite_scaled_font_t::TEXT_RENDERING_GDI_CLASSIC) &&
+         !surface->base.permit_subpixel_antialiasing) {
+-      renderingState = cairo_d2d_surface_t::TEXT_RENDERING_NO_CLEARTYPE;
++      renderingState = cairo_dwrite_scaled_font_t::TEXT_RENDERING_NO_CLEARTYPE;
+       IDWriteBitmapRenderTarget1* rt1;
+       rv = rt->QueryInterface(&rt1);
+       
+       if (SUCCEEDED(rv) && rt1) {
+         rt1->SetTextAntialiasMode(DWRITE_TEXT_ANTIALIAS_MODE_GRAYSCALE);
+         rt1->Release();
+       }
+     }
+@@ -1187,18 +1187,18 @@ cairo_int_status_t
+     BitBlt(rt->GetMemoryDC(),
+ 	   0, 0,
+ 	   area.right - area.left, area.bottom - area.top,
+ 	   surface->dc,
+ 	   area.left, area.top, 
+ 	   SRCCOPY | NOMIRRORBITMAP);
+     DWRITE_MEASURING_MODE measureMode; 
+     switch (renderingState) {
+-    case cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC:
+-    case cairo_d2d_surface_t::TEXT_RENDERING_NO_CLEARTYPE:
++    case cairo_dwrite_scaled_font_t::TEXT_RENDERING_GDI_CLASSIC:
++    case cairo_dwrite_scaled_font_t::TEXT_RENDERING_NO_CLEARTYPE:
+         measureMode = DWRITE_MEASURING_MODE_GDI_CLASSIC;
+         break;
+     default:
+         measureMode = DWRITE_MEASURING_MODE_NATURAL;
+         break;
+     }
+     HRESULT hr = rt->DrawGlyphRun(0, 0, measureMode, run, params, color);
+     BitBlt(surface->dc,
+diff --git a/gfx/cairo/cairo/src/cairo-dwrite-private.h b/gfx/cairo/cairo/src/cairo-dwrite-private.h
+--- a/gfx/cairo/cairo/src/cairo-dwrite-private.h
++++ b/gfx/cairo/cairo/src/cairo-dwrite-private.h
+@@ -46,17 +46,23 @@ typedef HRESULT (WINAPI*DWriteCreateFact
+ /* cairo_scaled_font_t implementation */
+ struct _cairo_dwrite_scaled_font {
+     cairo_scaled_font_t base;
+     cairo_matrix_t mat;
+     cairo_matrix_t mat_inverse;
+     cairo_antialias_t antialias_mode;
+     DWRITE_MEASURING_MODE measuring_mode;
+     cairo_bool_t manual_show_glyphs_allowed;
+-    cairo_d2d_surface_t::TextRenderingState rendering_mode;
++    enum TextRenderingState {
++        TEXT_RENDERING_UNINITIALIZED,
++        TEXT_RENDERING_NO_CLEARTYPE,
++        TEXT_RENDERING_NORMAL,
++        TEXT_RENDERING_GDI_CLASSIC
++    };
++    TextRenderingState rendering_mode;
+ };
+ typedef struct _cairo_dwrite_scaled_font cairo_dwrite_scaled_font_t;
+ 
+ class DWriteFactory
+ {
+ public:
+     static IDWriteFactory *Instance()
+     {
+@@ -97,28 +103,28 @@ public:
+ 	    return NULL;
+ 	}
+ 
+ 	IDWriteFontFamily *family;
+ 	SystemCollection()->GetFontFamily(idx, &family);
+ 	return family;
+     }
+ 
+-    static IDWriteRenderingParams *RenderingParams(cairo_d2d_surface_t::TextRenderingState mode)
++    static IDWriteRenderingParams *RenderingParams(cairo_dwrite_scaled_font_t::TextRenderingState mode)
+     {
+ 	if (!mDefaultRenderingParams ||
+             !mForceGDIClassicRenderingParams ||
+             !mCustomClearTypeRenderingParams)
+         {
+ 	    CreateRenderingParams();
+ 	}
+ 	IDWriteRenderingParams *params;
+-        if (mode == cairo_d2d_surface_t::TEXT_RENDERING_NO_CLEARTYPE) {
++        if (mode == cairo_dwrite_scaled_font_t::TEXT_RENDERING_NO_CLEARTYPE) {
+             params = mDefaultRenderingParams;
+-        } else if (mode == cairo_d2d_surface_t::TEXT_RENDERING_GDI_CLASSIC && mRenderingMode < 0) {
++        } else if (mode == cairo_dwrite_scaled_font_t::TEXT_RENDERING_GDI_CLASSIC && mRenderingMode < 0) {
+             params = mForceGDIClassicRenderingParams;
+         } else {
+             params = mCustomClearTypeRenderingParams;
+         }
+ 	if (params) {
+ 	    params->AddRef();
+ 	}
+ 	return params;
+diff --git a/gfx/cairo/cairo/src/cairo-features.h.in b/gfx/cairo/cairo/src/cairo-features.h.in
+--- a/gfx/cairo/cairo/src/cairo-features.h.in
++++ b/gfx/cairo/cairo/src/cairo-features.h.in
+@@ -78,18 +78,16 @@
+ @QT_SURFACE_FEATURE@
+ 
+ @FT_FONT_FEATURE@
+ 
+ @WIN32_FONT_FEATURE@
+ 
+ @WIN32_DWRITE_FONT_FEATURE@
+ 
+-@WIN32_D2D_SURFACE_FEATURE@
+-
+ @QUARTZ_FONT_FEATURE@
+ 
+ @TEE_SURFACE_FEATURE@
+ 
+ @PNG_FUNCTIONS_FEATURE@
+ 
+ @FC_FONT_FEATURE@
+ #endif
+diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h
+--- a/gfx/cairo/cairo/src/cairo-win32.h
++++ b/gfx/cairo/cairo/src/cairo-win32.h
+@@ -146,194 +146,15 @@ int
+ cairo_dwrite_get_cleartype_rendering_mode();
+ 
+ #endif /* CAIRO_HAS_DWRITE_FONT */
+ 
+ struct IDirect3DSurface9;
+ cairo_public cairo_surface_t *
+ cairo_win32_surface_create_with_d3dsurface9 (struct IDirect3DSurface9 *surface);
+ 
+-
+-#if CAIRO_HAS_D2D_SURFACE
+-
+-struct _cairo_device
+-{
+-    int type;
+-    int refcount;
+-};
+-
+-/**
+- * Create a D2D device
+- *
+- * \return New D2D device, NULL if creation failed.
+- */
+-cairo_device_t *
+-cairo_d2d_create_device();
+-
+-cairo_device_t *
+-cairo_d2d_create_device_from_d3d10device(struct ID3D10Device1 *device);
+-
+-/**
+- * Releases a D2D device.
+- *
+- * \return References left to the device
+- */
+-int
+-cairo_release_device(cairo_device_t *device);
+-
+-/**
+- * Addrefs a D2D device.
+- *
+- * \return References to the device
+- */
+-int
+-cairo_addref_device(cairo_device_t *device);
+-
+-/**
+- * Flushes a D3D device. In most cases the surface backend will do this
+- * internally, but when using a surfaces created from a shared handle this
+- * should be executed manually when a different device is going to be accessing
+- * the same surface data. This will also block until the device is finished
+- * processing all work.
+- */
+-void
+-cairo_d2d_finish_device(cairo_device_t *device);
+-
+-/**
+- * Gets the D3D10 device used by a certain cairo_device_t.
+- */
+-struct ID3D10Device1*
+-cairo_d2d_device_get_device(cairo_device_t *device);
+-
+-/**
+- * Create a D2D surface for an HWND
+- *
+- * \param device Device used to create the surface
+- * \param wnd Handle for the window
+- * \param content Content of the window, should be COLOR_ALPHA for transparent windows
+- * \return New cairo surface
+- */
+-cairo_public cairo_surface_t *
+-cairo_d2d_surface_create_for_hwnd(cairo_device_t *device, HWND wnd, cairo_content_t content);
+-
+-/**
+- * Create a D2D surface of a certain size.
+- *
+- * \param device Device used to create the surface
+- * \param format Cairo format of the surface
+- * \param width Width of the surface
+- * \param height Height of the surface
+- * \return New cairo surface
+- */
+-cairo_public cairo_surface_t *
+-cairo_d2d_surface_create(cairo_device_t *device,
+-			 cairo_format_t format,
+-                         int width,
+-                         int height);
+-
+-/**
+- * Create a D3D surface from a Texture SharedHandle, this is obtained from a
+- * CreateTexture call on a D3D9 device. This has to be an A8R8G8B8 format
+- * or an A8 format, the treatment of the alpha channel can be indicated using
+- * the content parameter.
+- *
+- * \param device Device used to create the surface
+- * \param handle Shared handle to the texture we want to wrap
+- * \param content Content of the texture, COLOR_ALPHA for ARGB
+- * \return New cairo surface
+- */
+-cairo_public cairo_surface_t *
+-cairo_d2d_surface_create_for_handle(cairo_device_t *device, HANDLE handle, cairo_content_t content);
+-
+-/**
+- * Create a D3D surface from an ID3D10Texture2D texture, this is obtained from a
+- * CreateTexture2D call on a D3D10 device. This has to be an A8R8G8B8 format
+- * or an A8 format, the treatment of the alpha channel can be indicated using
+- * the content parameter.
+- *
+- * \param device Device used to create the surface
+- * \param texture Texture that we want to wrap
+- * \param content Content of the texture
+- * \return New cairo surface
+- */
+-cairo_public cairo_surface_t *
+-cairo_d2d_surface_create_for_texture(cairo_device_t *device,
+-				     struct ID3D10Texture2D *texture,
+-				     cairo_content_t content);
+-
+-/**
+- * Get the ID3D10Texture2D used for a surface.
+- */
+-cairo_public struct ID3D10Texture2D *cairo_d2d_surface_get_texture(cairo_surface_t *surf);
+-
+-/**
+- * Present the backbuffer for a surface create for an HWND. This needs
+- * to be called when the owner of the original window surface wants to
+- * actually present the executed drawing operations to the screen.
+- *
+- * \param surface D2D surface.
+- */
+-void cairo_d2d_present_backbuffer(cairo_surface_t *surface);
+-
+-/**
+- * Scroll the surface, this only moves the surface graphics, it does not
+- * actually scroll child windows or anything like that. Nor does it invalidate
+- * that area of the window.
+- *
+- * \param surface The d2d surface this operation should apply to.
+- * \param x The x delta for the movement
+- * \param y The y delta for the movement
+- * \param clip The clip rectangle, the is the 'part' of the surface that needs
+- * scrolling.
+- */
+-void cairo_d2d_scroll(cairo_surface_t *surface, int x, int y, cairo_rectangle_t *clip);
+-
+-/**
+- * Get a DC for the current render target. When selecting the retention option this
+- * call can be relatively slow, since it may require reading back contents from the
+- * hardware surface.
+- *
+- * \note This must be matched by a call to ReleaseDC!
+- *
+- * \param retain_contents If true the current contents of the RT is copied to the DC,
+- * otherwise the DC is initialized to transparent black.
+- */
+-HDC cairo_d2d_get_dc(cairo_surface_t *surface, cairo_bool_t retain_contents);
+-
+-/**
+- * Release the DC acquired through GetDC(). Optionally an update region may be specified
+- *
+- * \param updated_rect The area of the DC that was updated, if null the entire dc will
+- * be updated.
+- */
+-void cairo_d2d_release_dc(cairo_surface_t *surcace, const cairo_rectangle_int_t *updated_rect);
+-
+-/**
+- * Get an estimate of the amount of (video) RAM which is currently in use by the D2D
+- * internal image surface cache.
+- */
+-int cairo_d2d_get_image_surface_cache_usage();
+-
+-/**
+- * Get an estimate of the amount of VRAM which is currently used by the d2d
+- * surfaces for a device. This does -not- include the internal image surface
+- * cache.
+- */
+-int cairo_d2d_get_surface_vram_usage(cairo_device_t *device);
+-
+-/**
+- * Get the width of the surface.
+- */
+-int cairo_d2d_surface_get_width(cairo_surface_t *surface);
+-
+-/**
+- * Get the height of the surface.
+- */
+-int cairo_d2d_surface_get_height(cairo_surface_t *surface);
+-#endif
+-
+ CAIRO_END_DECLS
+ 
+ #else  /* CAIRO_HAS_WIN32_SURFACE */
+ # error Cairo was not compiled with support for the win32 backend
+ #endif /* CAIRO_HAS_WIN32_SURFACE */
+ 
+ #endif /* _CAIRO_WIN32_H_ */
+diff --git a/gfx/cairo/cairo/src/moz.build b/gfx/cairo/cairo/src/moz.build
+--- a/gfx/cairo/cairo/src/moz.build
++++ b/gfx/cairo/cairo/src/moz.build
+@@ -35,20 +35,16 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] not in (
+ 
+ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
+     EXPORTS.cairo += [
+         'cairo-win32.h',
+     ]
+     SOURCES += [
+         'cairo-dwrite-font.cpp',
+     ]
+-    if CONFIG['MOZ_ENABLE_D2D_SURFACE']:
+-        SOURCES += [
+-            'cairo-d2d-surface.cpp',
+-        ]
+     SOURCES += [
+         'cairo-win32-font.c',
+         'cairo-win32-surface.c',
+     ]
+     DEFINES['DISABLE_SOME_FLOATING_POINT'] = True
+     DEFINES['CAIRO_WIN32_STATIC_BUILD'] = True
+     if CONFIG['NS_PRINTING']:
+         SOURCES += [
+diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h
+--- a/gfx/thebes/gfxWindowsPlatform.h
++++ b/gfx/thebes/gfxWindowsPlatform.h
+@@ -3,17 +3,17 @@
+  * License, v. 2.0. If a copy of the MPL was not distributed with this
+  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+ 
+ #ifndef GFX_WINDOWS_PLATFORM_H
+ #define GFX_WINDOWS_PLATFORM_H
+ 
+ 
+ /**
+- * XXX to get CAIRO_HAS_D2D_SURFACE, CAIRO_HAS_DWRITE_FONT
++ * XXX to get CAIRO_HAS_DWRITE_FONT
+  * and cairo_win32_scaled_font_select_font
+  */
+ #include "cairo-win32.h"
+ 
+ #include "gfxCrashReporterUtils.h"
+ #include "gfxFontUtils.h"
+ #include "gfxWindowsSurface.h"
+ #include "gfxFont.h"
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -2576,52 +2576,44 @@ fi
+ 
+ case "$MOZ_WIDGET_TOOLKIT" in
+   cocoa)
+     QUARTZ_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_SURFACE 1"
+     QUARTZ_IMAGE_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_IMAGE_SURFACE 1"
+     QUARTZ_FONT_FEATURE="#define CAIRO_HAS_QUARTZ_FONT 1"
+     ;;
+   windows)
+-    WIN32_D2D_SURFACE_FEATURE="#define CAIRO_HAS_D2D_SURFACE 1"
+     WIN32_DWRITE_FONT_FEATURE="#define CAIRO_HAS_DWRITE_FONT 1"
+     WIN32_FONT_FEATURE="#define CAIRO_HAS_WIN32_FONT 1"
+     WIN32_SURFACE_FEATURE="#define CAIRO_HAS_WIN32_SURFACE 1"
+-    MOZ_ENABLE_D2D_SURFACE=1
+ 
+     if test "$COMPILE_ENVIRONMENT"; then
+-
+-      dnl D3D10 Layers depend on D2D Surfaces.
+-      if test -n "$WIN32_D2D_SURFACE_FEATURE"; then
+-        MOZ_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
+-      fi
++      MOZ_CHECK_HEADER(d3d10.h, MOZ_ENABLE_D3D10_LAYER=1)
+     fi
+     ;;
+ esac
+ if test "$USE_FC_FREETYPE"; then
+     FC_FONT_FEATURE="#define CAIRO_HAS_FC_FONT 1"
+ fi
+ AC_SUBST(MOZ_ENABLE_CAIRO_FT)
+-AC_SUBST(MOZ_ENABLE_D2D_SURFACE)
+ AC_SUBST(MOZ_ENABLE_D3D10_LAYER)
+ 
+ AC_SUBST(PS_SURFACE_FEATURE)
+ AC_SUBST(SVG_SURFACE_FEATURE)
+ AC_SUBST(XLIB_SURFACE_FEATURE)
+ AC_SUBST(XLIB_XRENDER_SURFACE_FEATURE)
+ AC_SUBST(QUARTZ_SURFACE_FEATURE)
+ AC_SUBST(QUARTZ_IMAGE_SURFACE_FEATURE)
+ AC_SUBST(WIN32_SURFACE_FEATURE)
+ AC_SUBST(OS2_SURFACE_FEATURE)
+ AC_SUBST(DIRECTFB_SURFACE_FEATURE)
+ AC_SUBST(FT_FONT_FEATURE)
+ AC_SUBST(FC_FONT_FEATURE)
+ AC_SUBST(WIN32_FONT_FEATURE)
+ AC_SUBST(WIN32_DWRITE_FONT_FEATURE)
+-AC_SUBST(WIN32_D2D_SURFACE_FEATURE)
+ AC_SUBST(QUARTZ_FONT_FEATURE)
+ AC_SUBST(PNG_FUNCTIONS_FEATURE)
+ AC_SUBST(QT_SURFACE_FEATURE)
+ AC_SUBST(TEE_SURFACE_FEATURE)
+ 
+ if test "$MOZ_X11"; then
+     MOZ_CAIRO_OSLIBS="$MOZ_CAIRO_OSLIBS $XLDFLAGS -lXrender"
+ fi

+ 32 - 1
mozilla-release/patches/1519281-66a1.patch

@@ -2,7 +2,7 @@
 # User Mike Hommey <mh+mozilla@glandium.org>
 # User Mike Hommey <mh+mozilla@glandium.org>
 # Date 1547182927 0
 # Date 1547182927 0
 # Node ID 65511e8d7a7e0df5df7c4b7c96ffc3cbd2590db3
 # Node ID 65511e8d7a7e0df5df7c4b7c96ffc3cbd2590db3
-# Parent  398eb9327e15c508f428c175138a7fc8ea9cd511
+# Parent  9236c91fc9fa4a6522553fe8334978ef0e34178d
 Bug 1519281 - Remove leftovers from bug 1490765. r=nalexander
 Bug 1519281 - Remove leftovers from bug 1490765. r=nalexander
 
 
 Differential Revision: https://phabricator.services.mozilla.com/D16269
 Differential Revision: https://phabricator.services.mozilla.com/D16269
@@ -58,3 +58,34 @@ deleted file mode 100644
 -
 -
 -dnl AC_OUTPUT_SUBDIRS(subdirectory)
 -dnl AC_OUTPUT_SUBDIRS(subdirectory)
 -AC_DEFUN([AC_OUTPUT_SUBDIRS], [do_output_subdirs "$1"])
 -AC_DEFUN([AC_OUTPUT_SUBDIRS], [do_output_subdirs "$1"])
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -3589,27 +3589,16 @@ if test -z "$direct_nspr_config"; then
+     HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
+     HOST_CXXFLAGS="$_SUBDIR_HOST_CXXFLAGS"
+     HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
+ fi
+ 
+ unset MAKEFILES
+ unset CONFIG_FILES
+ 
+-# Run all configure scripts specified by a subconfigure
+-if test -n "$_subconfigure_subdir"; then
+-  _save_srcdir="$srcdir"
+-  srcdir="$srcdir/.."
+-  _save_ac_configure_args="$ac_configure_args"
+-  ac_configure_args="$_subconfigure_config_args"
+-  AC_OUTPUT_SUBDIRS_NOW("$_subconfigure_subdir",$cache_file)
+-  ac_configure_args="$_save_ac_configure_args"
+-  srcdir="$_save_srcdir"
+-fi
+-
+ if test "$COMPILE_ENVIRONMENT" -a "$MOZ_WIDGET_TOOLKIT"; then
+ 
+ 
+ dnl ========================================================
+ dnl = Setup a nice relatively clean build environment for
+ dnl = sub-configures.
+ dnl ========================================================
+ CC="$_SUBDIR_CC"

+ 49 - 0
mozilla-release/patches/1519310-1-66a1.patch

@@ -0,0 +1,49 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1547212317 0
+# Node ID 6eff10f846d7d49fe53ddfadd7e730ff738679bb
+# Parent  a1f35c2a98e20437e7c1b523709caf4a5386b7f5
+Bug 1519310 - Remove direct_nspr_config-related code from old-configure. r=dmajor
+
+This was useful when old-configure was calling nspr configure, but now
+is noop.
+
+Differential Revision: https://phabricator.services.mozilla.com/D16285
+
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -3569,33 +3569,16 @@ HAVE_SYS_MOUNT_H
+ AC_DEFINE(NO_NSPR_10_SUPPORT)
+ 
+ # Don't build NSS libpkix
+ NSS_DISABLE_LIBPKIX=1
+ AC_SUBST(NSS_DISABLE_LIBPKIX)
+ 
+ MOZ_CREATE_CONFIG_STATUS()
+ 
+-if test -z "$direct_nspr_config"; then
+-    dnl ========================================================
+-    dnl = Setup a nice relatively clean build environment for
+-    dnl = sub-configures.
+-    dnl ========================================================
+-    CC="$_SUBDIR_CC"
+-    CXX="$_SUBDIR_CXX"
+-    CFLAGS="$_SUBDIR_CFLAGS"
+-    CPPFLAGS="$_SUBDIR_CPPFLAGS"
+-    CXXFLAGS="$_SUBDIR_CXXFLAGS"
+-    LDFLAGS="$_SUBDIR_LDFLAGS"
+-    HOST_CC="$_SUBDIR_HOST_CC"
+-    HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
+-    HOST_CXXFLAGS="$_SUBDIR_HOST_CXXFLAGS"
+-    HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
+-fi
+-
+ unset MAKEFILES
+ unset CONFIG_FILES
+ 
+ if test "$COMPILE_ENVIRONMENT" -a "$MOZ_WIDGET_TOOLKIT"; then
+ 
+ 
+ dnl ========================================================
+ dnl = Setup a nice relatively clean build environment for

+ 40 - 0
mozilla-release/patches/1519310-2-66a1.patch

@@ -0,0 +1,40 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1547212394 0
+# Node ID 8bb28e41610207c5c3a1dce892a1bb387b1dda94
+# Parent  b4579c8008b82e80fae0c2e901349c4fa52e4022
+Bug 1519310 - Remove NSS_DISABLE_LIBPKIX. r=dmajor
+
+It was used to disable libpkix in NSS when NSS was built with its
+Makefiles, but it's now built with gyp, and this knob does nothing.
+The equivalent is the gyp variable disable_libpkix, which is set in
+security/moz.build.
+
+Depends on D16285
+
+Differential Revision: https://phabricator.services.mozilla.com/D16286
+
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -3563,20 +3563,16 @@ HAVE_SYS_STATVFS_H
+ HAVE_SYS_STATFS_H
+ HAVE_SYS_VFS_H
+ HAVE_SYS_MOUNT_H
+ "
+ 
+ # Avoid using obsolete NSPR features
+ AC_DEFINE(NO_NSPR_10_SUPPORT)
+ 
+-# Don't build NSS libpkix
+-NSS_DISABLE_LIBPKIX=1
+-AC_SUBST(NSS_DISABLE_LIBPKIX)
+-
+ MOZ_CREATE_CONFIG_STATUS()
+ 
+ unset MAKEFILES
+ unset CONFIG_FILES
+ 
+ if test "$COMPILE_ENVIRONMENT" -a "$MOZ_WIDGET_TOOLKIT"; then
+ 
+ 

+ 2 - 37
mozilla-release/patches/1519603-4-66a1.patch

@@ -2,7 +2,7 @@
 # User Mike Hommey <mh+mozilla@glandium.org>
 # User Mike Hommey <mh+mozilla@glandium.org>
 # Date 1547491026 0
 # Date 1547491026 0
 # Node ID 129e9f6b6295da4ed2a2e7bfb73f1c75200ad9ef
 # Node ID 129e9f6b6295da4ed2a2e7bfb73f1c75200ad9ef
-# Parent  f78e309ed12af44cd8ccb1b0572b88e1b1f26033
+# Parent  e34e6d6235022909feaafb36f140540fa80929f7
 Bug 1519603 - Manually inline AC_OUTPUT_SUBDIRS and MOZ_RUN_ALL_SUBCONFIGURES. r=nalexander
 Bug 1519603 - Manually inline AC_OUTPUT_SUBDIRS and MOZ_RUN_ALL_SUBCONFIGURES. r=nalexander
 
 
 Because we only ever run one subconfigure, the machinery to execute
 Because we only ever run one subconfigure, the machinery to execute
@@ -201,42 +201,7 @@ diff --git a/js/src/aclocal.m4 b/js/src/aclocal.m4
 diff --git a/old-configure.in b/old-configure.in
 diff --git a/old-configure.in b/old-configure.in
 --- a/old-configure.in
 --- a/old-configure.in
 +++ b/old-configure.in
 +++ b/old-configure.in
-@@ -3813,25 +3813,25 @@ if test -z "$direct_nspr_config"; then
-     HOST_CXXFLAGS="$_SUBDIR_HOST_CXXFLAGS"
-     HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
- fi
- 
- unset MAKEFILES
- unset CONFIG_FILES
- 
- # Run all configure scripts specified by a subconfigure
--if test -n "$_subconfigure_subdir"; then
--  _save_srcdir="$srcdir"
--  srcdir="$srcdir/.."
--  _save_ac_configure_args="$ac_configure_args"
--  ac_configure_args="$_subconfigure_config_args"
--  AC_OUTPUT_SUBDIRS_NOW("$_subconfigure_subdir",$cache_file)
--  ac_configure_args="$_save_ac_configure_args"
--  srcdir="$_save_srcdir"
--fi
-+#if test -n "$_subconfigure_subdir"; then
-+#  _save_srcdir="$srcdir"
-+#  srcdir="$srcdir/.."
-+#  _save_ac_configure_args="$ac_configure_args"
-+#  ac_configure_args="$_subconfigure_config_args"
-+#  AC_OUTPUT_SUBDIRS_NOW("$_subconfigure_subdir",$cache_file)
-+#  ac_configure_args="$_save_ac_configure_args"
-+#  srcdir="$_save_srcdir"
-+#fi
- 
- if test "$COMPILE_ENVIRONMENT" -a "$MOZ_WIDGET_TOOLKIT"; then
- 
- 
- dnl ========================================================
- dnl = Setup a nice relatively clean build environment for
- dnl = sub-configures.
- dnl ========================================================
-@@ -3897,21 +3897,37 @@ export HOST_CPPFLAGS
+@@ -3642,21 +3642,37 @@ export HOST_CPPFLAGS
  export HOST_CXXFLAGS
  export HOST_CXXFLAGS
  export HOST_LDFLAGS
  export HOST_LDFLAGS
  
  

+ 47 - 0
mozilla-release/patches/1520149-66a1.patch

@@ -0,0 +1,47 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1547731117 0
+# Node ID c28522aaf3918c5f556c65432f8bf14a65bff65a
+# Parent  f9587af599290964d950aec4fd84b7305cc825f5
+Bug 1520149 - Also disable the machine outliner on Android when LTO is enabled. r=dmajor
+
+Differential Revision: https://phabricator.services.mozilla.com/D16790
+
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -610,21 +610,29 @@ case "$target" in
+     if test -z "$CLANG_CC"; then
+         MOZ_OPTIMIZE_FLAGS="-freorder-blocks -fno-reorder-functions -Os"
+     else
+         # From https://github.com/android-ndk/ndk/issues/133#issuecomment-308549264
+         # -Oz is smaller than -Os on clang.
+         MOZ_OPTIMIZE_FLAGS="-Oz"
+         # Disable the outliner, which causes performance regressions, and is
+         # enabled on some platforms at -Oz.
+-        DISABLE_OUTLINER="-mno-outline"
+-        _SAVE_CFLAGS=$CFLAGS
+-        CFLAGS="$CFLAGS $DISABLE_OUTLINER"
+-        AC_TRY_COMPILE(,,[MOZ_OPTIMIZE_FLAGS="$MOZ_OPTIMIZE_FLAGS $DISABLE_OUTLINER"])
+-        CFLAGS="$_SAVE_CFLAGS"
++        if test -z "$MOZ_LTO"; then
++            DISABLE_OUTLINER="-mno-outline"
++            _SAVE_CFLAGS=$CFLAGS
++            CFLAGS="$CFLAGS $DISABLE_OUTLINER"
++            AC_TRY_COMPILE(,,[MOZ_OPTIMIZE_FLAGS="$MOZ_OPTIMIZE_FLAGS $DISABLE_OUTLINER"])
++            CFLAGS="$_SAVE_CFLAGS"
++        else
++            DISABLE_OUTLINER="-Wl,-plugin-opt=-enable-machine-outliner=never"
++            _SAVE_LDFLAGS=$LDFLAGS
++            LDFLAGS="$LDFLAGS $MOZ_LTO_LDFLAGS $DISABLE_OUTLINER"
++            AC_TRY_LINK(,,[MOZ_OPTIMIZE_LDFLAGS="$MOZ_OPTIMIZE_LDFLAGS $DISABLE_OUTLINER"])
++            LDFLAGS="$_SAVE_LDFLAGS"
++        fi
+     fi
+     ;;
+ 
+ *-*linux*)
+     if test "$GNU_CC" -o "$GNU_CXX"; then
+         MOZ_PGO_OPTIMIZE_FLAGS="-O3"
+         if test -n "$MOZ_DEBUG"; then
+             MOZ_OPTIMIZE_FLAGS="-Os"

+ 7 - 35
mozilla-release/patches/1520340-5-66a1.patch

@@ -2,7 +2,7 @@
 # User Mike Hommey <mh+mozilla@glandium.org>
 # User Mike Hommey <mh+mozilla@glandium.org>
 # Date 1547680340 0
 # Date 1547680340 0
 # Node ID 5e51e7031e8f239efd765328071a21b877e1d814
 # Node ID 5e51e7031e8f239efd765328071a21b877e1d814
-# Parent  85a913eb3655c5bb7865497a43711e68eef22eae
+# Parent  907a24a30c73be0770183db159d9b5f3bbaa075b
 Bug 1520340 - Move subconfigure invocation from old-configure to python configure. r=froydnj
 Bug 1520340 - Move subconfigure invocation from old-configure to python configure. r=froydnj
 
 
 This happens to remove the last use of perl from configure.
 This happens to remove the last use of perl from configure.
@@ -243,7 +243,7 @@ new file mode 100644
 diff --git a/moz.configure b/moz.configure
 diff --git a/moz.configure b/moz.configure
 --- a/moz.configure
 --- a/moz.configure
 +++ b/moz.configure
 +++ b/moz.configure
-@@ -605,19 +605,25 @@ def nsis_flags(host):
+@@ -584,19 +584,25 @@ def nsis_flags(host):
      if host.kernel != 'WINNT':
      if host.kernel != 'WINNT':
          return '-nocd'
          return '-nocd'
      return ''
      return ''
@@ -272,46 +272,18 @@ diff --git a/moz.configure b/moz.configure
 diff --git a/old-configure.in b/old-configure.in
 diff --git a/old-configure.in b/old-configure.in
 --- a/old-configure.in
 --- a/old-configure.in
 +++ b/old-configure.in
 +++ b/old-configure.in
-@@ -3792,134 +3792,9 @@ HAVE_SYS_MOUNT_H
- AC_DEFINE(NO_NSPR_10_SUPPORT)
+@@ -3565,106 +3565,9 @@ HAVE_SYS_VFS_H
+ HAVE_SYS_MOUNT_H
+ "
  
  
- # Don't build NSS libpkix
- NSS_DISABLE_LIBPKIX=1
- AC_SUBST(NSS_DISABLE_LIBPKIX)
+ # Avoid using obsolete NSPR features
+ AC_DEFINE(NO_NSPR_10_SUPPORT)
  
  
  MOZ_CREATE_CONFIG_STATUS()
  MOZ_CREATE_CONFIG_STATUS()
  
  
--if test -z "$direct_nspr_config"; then
--    dnl ========================================================
--    dnl = Setup a nice relatively clean build environment for
--    dnl = sub-configures.
--    dnl ========================================================
--    CC="$_SUBDIR_CC"
--    CXX="$_SUBDIR_CXX"
--    CFLAGS="$_SUBDIR_CFLAGS"
--    CPPFLAGS="$_SUBDIR_CPPFLAGS"
--    CXXFLAGS="$_SUBDIR_CXXFLAGS"
--    LDFLAGS="$_SUBDIR_LDFLAGS"
--    HOST_CC="$_SUBDIR_HOST_CC"
--    HOST_CFLAGS="$_SUBDIR_HOST_CFLAGS"
--    HOST_CXXFLAGS="$_SUBDIR_HOST_CXXFLAGS"
--    HOST_LDFLAGS="$_SUBDIR_HOST_LDFLAGS"
--fi
--
 -unset MAKEFILES
 -unset MAKEFILES
 -unset CONFIG_FILES
 -unset CONFIG_FILES
 -
 -
--# Run all configure scripts specified by a subconfigure
--#if test -n "$_subconfigure_subdir"; then
--#  _save_srcdir="$srcdir"
--#  srcdir="$srcdir/.."
--#  _save_ac_configure_args="$ac_configure_args"
--#  ac_configure_args="$_subconfigure_config_args"
--#  AC_OUTPUT_SUBDIRS_NOW("$_subconfigure_subdir",$cache_file)
--#  ac_configure_args="$_save_ac_configure_args"
--#  srcdir="$_save_srcdir"
--#fi
--
 -if test "$COMPILE_ENVIRONMENT" -a "$MOZ_WIDGET_TOOLKIT"; then
 -if test "$COMPILE_ENVIRONMENT" -a "$MOZ_WIDGET_TOOLKIT"; then
 -
 -
 -
 -

+ 78 - 0
mozilla-release/patches/1520730-66a1.patch

@@ -0,0 +1,78 @@
+# HG changeset patch
+# User Mike Hommey <mh+mozilla@glandium.org>
+# Date 1547733281 0
+# Node ID d08b5d16f36f9918c396adb05a105d07697e4e78
+# Parent  202b50eb7f10fdcdcce2f87edd981748e216c078
+Bug 1520730 - Normalize the config log path before writing it in old-configure. r=froydnj
+
+Add a dummy change to old-configure.in so that old-configure is
+force-refreshed.
+
+Differential Revision: https://phabricator.services.mozilla.com/D16797
+
+diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configure
+--- a/build/moz.configure/old.configure
++++ b/build/moz.configure/old.configure
+@@ -135,17 +135,17 @@ def prepare_configure(old_configure, moz
+             die('Generated old-configure is empty! Check that your autoconf 2.13 program works!')
+ 
+         # Make old-configure append to config.log, where we put our own log.
+         # This could be done with a m4 macro, but it's way easier this way
+         if config_log:
+             path = config_log.baseFilename
+         else:
+             path = '/dev/null'
+-        script = script.replace('>./config.log', '>>%s' % path)
++        script = script.replace('>./config.log', '>>%s' % quote(normsep(path)))
+ 
+         with open(old_configure, 'wb') as fh:
+             fh.write(script)
+ 
+     cmd = [shell, old_configure]
+     with encoded_open('old-configure.vars', 'w') as out:
+         log.debug('Injecting the following to old-configure:')
+ 
+diff --git a/js/src/old-configure.in b/js/src/old-configure.in
+--- a/js/src/old-configure.in
++++ b/js/src/old-configure.in
+@@ -8,17 +8,17 @@ dnl Process this file with autoconf to p
+ dnl ========================================================
+ AC_PREREQ(2.13)
+ AC_INIT(js/src/jsapi.h)
+ AC_CONFIG_AUX_DIR(${srcdir}/build/autoconf)
+ AC_CANONICAL_SYSTEM
+ 
+ dnl ========================================================
+ dnl =
+-dnl = Don't change the following two lines.  Doing so breaks:
++dnl = Don't change the following lines.  Doing so breaks:
+ dnl =
+ dnl = CFLAGS="-foo" ./configure
+ dnl =
+ dnl ========================================================
+ CFLAGS="${CFLAGS=}"
+ CPPFLAGS="${CPPFLAGS=}"
+ CXXFLAGS="${CXXFLAGS=}"
+ LDFLAGS="${LDFLAGS=}"
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -8,17 +8,17 @@ dnl Process this file with autoconf to p
+ dnl ========================================================
+ AC_PREREQ(2.13)
+ AC_INIT(config/config.mk)
+ AC_CONFIG_AUX_DIR(${srcdir}/build/autoconf)
+ AC_CANONICAL_SYSTEM
+ 
+ dnl ========================================================
+ dnl =
+-dnl = Don't change the following two lines.  Doing so breaks:
++dnl = Don't change the following lines.  Doing so breaks:
+ dnl =
+ dnl = CFLAGS="-foo" ./configure
+ dnl =
+ dnl ========================================================
+ CFLAGS="${CFLAGS=}"
+ CPPFLAGS="${CPPFLAGS=}"
+ CXXFLAGS="${CXXFLAGS=}"
+ LDFLAGS="${LDFLAGS=}"

+ 53 - 0
mozilla-release/patches/1521133-66a1.patch

@@ -0,0 +1,53 @@
+# HG changeset patch
+# User Tom Ritter <tom@mozilla.com>
+# Date 1547839212 18000
+# Node ID 3296484c0237d1649160e337777979afff76f80b
+# Parent  3fc1e8cf6b7736e35da47473a9d4c7aca83fd0d6
+Bug 1521133 - Disable string tail merging on Windows ASan builds. r=dmajor
+
+diff --git a/js/src/old-configure.in b/js/src/old-configure.in
+--- a/js/src/old-configure.in
++++ b/js/src/old-configure.in
+@@ -603,16 +603,19 @@ case "$target" in
+           changequote([,])
+         fi
+         dnl VS2013+ supports -Gw for better linker optimizations.
+         dnl http://blogs.msdn.com/b/vcblog/archive/2013/09/11/introducing-gw-compiler-switch.aspx
+         dnl Disabled on ASan because it causes false-positive ODR violations.
+         if test -z "$MOZ_ASAN"; then
+             CFLAGS="$CFLAGS -Gw"
+             CXXFLAGS="$CXXFLAGS -Gw"
++        else
++            # String tail merging doesn't play nice with ASan's ODR checker.
++            LDFLAGS="$LDFLAGS -opt:nolldtailmerge"
+         fi
+         # khuey says we can safely ignore MSVC warning C4251
+         # MSVC warning C4244 (implicit type conversion may lose data) warns
+         # and requires workarounds for perfectly valid code.  Also, GCC/clang
+         # don't warn about it by default. So for consistency/sanity, we turn
+         # it off on MSVC, too.
+         # MSVC warning C4267 warns for narrowing type conversions from size_t
+         # to 32-bit integer types on 64-bit platforms.  Since this is virtually
+diff --git a/old-configure.in b/old-configure.in
+--- a/old-configure.in
++++ b/old-configure.in
+@@ -731,16 +731,19 @@ case "$target" in
+             SSSE3_FLAGS="-mssse3"
+         fi
+         dnl VS2013+ supports -Gw for better linker optimizations.
+         dnl http://blogs.msdn.com/b/vcblog/archive/2013/09/11/introducing-gw-compiler-switch.aspx
+         dnl Disabled on ASan because it causes false-positive ODR violations.
+         if test -z "$MOZ_ASAN"; then
+             CFLAGS="$CFLAGS -Gw"
+             CXXFLAGS="$CXXFLAGS -Gw"
++        else
++            # String tail merging doesn't play nice with ASan's ODR checker.
++            LDFLAGS="$LDFLAGS -opt:nolldtailmerge"
+         fi
+         # khuey says we can safely ignore MSVC warning C4251
+         # MSVC warning C4244 (implicit type conversion may lose data) warns
+         # and requires workarounds for perfectly valid code.  Also, GCC/clang
+         # don't warn about it by default. So for consistency/sanity, we turn
+         # it off on MSVC, too.
+         # MSVC warning C4267 warns for narrowing type conversions from size_t
+         # to 32-bit integer types on 64-bit platforms.  Since this is virtually

+ 5 - 5
mozilla-release/patches/1521284-66a1.patch

@@ -2,7 +2,7 @@
 # User Mike Hommey <mh+mozilla@glandium.org>
 # User Mike Hommey <mh+mozilla@glandium.org>
 # Date 1548091931 0
 # Date 1548091931 0
 # Node ID 39d0c50a2209e0f0c982b1d121765c9dc950e161
 # Node ID 39d0c50a2209e0f0c982b1d121765c9dc950e161
-# Parent  4699c84ae712a4ad4dbeee8afdca414fbcfc86ef
+# Parent  a94b1d10d485a6b8a1cf1262410f1ab6e7424101
 Bug 1521284 - Don't hardcode config.log path in old-configure. r=nalexander
 Bug 1521284 - Don't hardcode config.log path in old-configure. r=nalexander
 
 
 Because old-configure is only refreshed when, essentially,
 Because old-configure is only refreshed when, essentially,
@@ -75,7 +75,7 @@ diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configu
 -            path = config_log.baseFilename
 -            path = config_log.baseFilename
 -        else:
 -        else:
 -            path = '/dev/null'
 -            path = '/dev/null'
--        script = script.replace('>./config.log', '>>%s' % path)
+-        script = script.replace('>./config.log', '>>%s' % quote(normsep(path)))
 +        script = script.replace('>./config.log', '>>${CONFIG_LOG=./config.log}')
 +        script = script.replace('>./config.log', '>>${CONFIG_LOG=./config.log}')
  
  
          with open(old_configure, 'wb') as fh:
          with open(old_configure, 'wb') as fh:
@@ -85,7 +85,7 @@ diff --git a/build/moz.configure/old.configure b/build/moz.configure/old.configu
      with encoded_open('old-configure.vars', 'w') as out:
      with encoded_open('old-configure.vars', 'w') as out:
          log.debug('Injecting the following to old-configure:')
          log.debug('Injecting the following to old-configure:')
  
  
-@@ -306,49 +293,53 @@ def prepare_configure_options(extra_old_
+@@ -301,49 +288,53 @@ def prepare_configure_options(extra_old_
                  options.append(arg)
                  options.append(arg)
              else:
              else:
                  k, v = arg.split('=', 1)
                  k, v = arg.split('=', 1)
@@ -158,7 +158,7 @@ diff --git a/js/src/old-configure.in b/js/src/old-configure.in
  
  
  dnl ========================================================
  dnl ========================================================
  dnl =
  dnl =
--dnl = Don't change the following two lines.  Doing so breaks:
+-dnl = Don't change the following lines.  Doing so breaks:
 +dnl = Don't change the following lines. Doing so breaks:
 +dnl = Don't change the following lines. Doing so breaks:
  dnl =
  dnl =
  dnl = CFLAGS="-foo" ./configure
  dnl = CFLAGS="-foo" ./configure
@@ -180,7 +180,7 @@ diff --git a/old-configure.in b/old-configure.in
  
  
  dnl ========================================================
  dnl ========================================================
  dnl =
  dnl =
--dnl = Don't change the following two lines.  Doing so breaks:
+-dnl = Don't change the following lines.  Doing so breaks:
 +dnl = Don't change the following lines. Doing so breaks:
 +dnl = Don't change the following lines. Doing so breaks:
  dnl =
  dnl =
  dnl = CFLAGS="-foo" ./configure
  dnl = CFLAGS="-foo" ./configure

+ 17 - 1
mozilla-release/patches/series

@@ -4705,6 +4705,7 @@ NOBUG-20180824-buildsetting-63a1.patch
 1478843-64a1.patch
 1478843-64a1.patch
 1494216-64a1.patch
 1494216-64a1.patch
 1493345-64a1.patch
 1493345-64a1.patch
+1494958-64a1.patch
 1496136-64a1.patch
 1496136-64a1.patch
 1487321-64a1.patch
 1487321-64a1.patch
 1496084-64a1.patch
 1496084-64a1.patch
@@ -5014,6 +5015,9 @@ NOBUG-20190118-zlib-66a1.patch
 1515528-4-66a1.patch
 1515528-4-66a1.patch
 1515528-5-66a1.patch
 1515528-5-66a1.patch
 1520108-66a1.patch
 1520108-66a1.patch
+1519281-66a1.patch
+1519310-1-66a1.patch
+1519310-2-66a1.patch
 1519603-1-66a1.patch
 1519603-1-66a1.patch
 1519603-2-66a1.patch
 1519603-2-66a1.patch
 1519603-3-66a1.patch
 1519603-3-66a1.patch
@@ -5039,6 +5043,7 @@ NOBUG-20190118-zlib-66a1.patch
 1520394-3-66a1.patch
 1520394-3-66a1.patch
 1520394-4-66a1.patch
 1520394-4-66a1.patch
 1520394-5-66a1.patch
 1520394-5-66a1.patch
+1520730-66a1.patch
 1521284-66a1.patch
 1521284-66a1.patch
 1513134-1no2-66a1.patch
 1513134-1no2-66a1.patch
 1513134-3-66a1.patch
 1513134-3-66a1.patch
@@ -5054,7 +5059,6 @@ NOBUG-20190118-zlib-66a1.patch
 1520681-66a1.patch
 1520681-66a1.patch
 1518630-66a1.patch
 1518630-66a1.patch
 1514209-66a1.patch
 1514209-66a1.patch
-1519281-66a1.patch
 1520516-66a1.patch
 1520516-66a1.patch
 1521478-66a1.patch
 1521478-66a1.patch
 1522507-66a1.patch
 1522507-66a1.patch
@@ -7212,4 +7216,16 @@ TOP-1909714-NSS3904-11514.patch
 1476333-2-63a1.patch
 1476333-2-63a1.patch
 1478128-63a1.patch
 1478128-63a1.patch
 1480004-63a1.patch
 1480004-63a1.patch
+1481864-63a1.patch
 1484759-63a1.patch
 1484759-63a1.patch
+1483780-1-64a1.patch
+1483780-2-64a1.patch
+1508547-1-65a1.patch
+1508547-2-65a1.patch
+1359905-65a1.patch
+1517077-66a1.patch
+1520149-66a1.patch
+1521133-66a1.patch
+1516228-1-66a1.patch
+1516228-2no3or4-66a1.patch
+1516228-5-66a1.patch