1diff --git a/gfx/cairo/cairo/src/cairo-rename.h b/gfx/cairo/cairo/src/cairo-rename.h
2--- a/gfx/cairo/cairo/src/cairo-rename.h
3+++ b/gfx/cairo/cairo/src/cairo-rename.h
4@@ -335,16 +335,17 @@
5 #define cairo_win32_font_face_create_for_logfontw_hfont _moz_cairo_win32_font_face_create_for_logfontw_hfont
6 #define cairo_win32_printing_surface_create _moz_cairo_win32_printing_surface_create
7 #define cairo_win32_scaled_font_done_font _moz_cairo_win32_scaled_font_done_font
8 #define cairo_win32_scaled_font_get_device_to_logical _moz_cairo_win32_scaled_font_get_device_to_logical
9 #define cairo_win32_scaled_font_get_logical_to_device _moz_cairo_win32_scaled_font_get_logical_to_device
10 #define cairo_win32_scaled_font_get_metrics_factor _moz_cairo_win32_scaled_font_get_metrics_factor
11 #define cairo_win32_scaled_font_select_font _moz_cairo_win32_scaled_font_select_font
12 #define cairo_win32_surface_create _moz_cairo_win32_surface_create
13+#define cairo_win32_surface_create_with_d3dsurface9 _moz_cairo_win32_surface_create_with_d3dsurface9
14 #define cairo_win32_surface_create_with_ddb _moz_cairo_win32_surface_create_with_ddb
15 #define cairo_win32_surface_create_with_dib _moz_cairo_win32_surface_create_with_dib
16 #define cairo_win32_surface_get_dc _moz_cairo_win32_surface_get_dc
17 #define cairo_win32_surface_get_image _moz_cairo_win32_surface_get_image
18 #define cairo_xcb_surface_create _moz_cairo_xcb_surface_create
19 #define cairo_xcb_surface_create_for_bitmap _moz_cairo_xcb_surface_create_for_bitmap
20 #define cairo_xcb_surface_create_with_xrender_format _moz_cairo_xcb_surface_create_with_xrender_format
21 #define cairo_xcb_surface_set_size _moz_cairo_xcb_surface_set_size
22diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
23--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
24+++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c
25@@ -1852,16 +1852,17 @@ cairo_win32_printing_surface_create (HDC
26     }
27
28     _cairo_surface_clipper_init (&surface->clipper,
29 				 _cairo_win32_printing_surface_clipper_intersect_clip_path);
30
31     surface->image = NULL;
32     surface->format = CAIRO_FORMAT_RGB24;
33     surface->content = CAIRO_CONTENT_COLOR_ALPHA;
34+    surface->d3d9surface = NULL;
35
36     surface->dc = hdc;
37     surface->bitmap = NULL;
38     surface->is_dib = FALSE;
39     surface->saved_dc_bitmap = NULL;
40     surface->brush = NULL;
41     surface->old_brush = NULL;
42     surface->font_subsets = _cairo_scaled_font_subsets_create_scaled ();
43diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h
44--- a/gfx/cairo/cairo/src/cairo-win32-private.h
45+++ b/gfx/cairo/cairo/src/cairo-win32-private.h
46@@ -54,16 +54,18 @@ CAIRO_BEGIN_DECLS
47
48 typedef struct _cairo_win32_surface {
49     cairo_surface_t base;
50
51     cairo_format_t format;
52
53     HDC dc;
54
55+    struct IDirect3DSurface9 *d3d9surface;
56+
57     /* We create off-screen surfaces as DIBs or DDBs, based on what we created
58      * originally*/
59     HBITMAP bitmap;
60     cairo_bool_t is_dib;
61
62     /* Used to save the initial 1x1 monochrome bitmap for the DC to
63      * select back into the DC before deleting the DC and our
64      * bitmap. For Windows XP, this doesn't seem to be necessary
65diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c
66--- a/gfx/cairo/cairo/src/cairo-win32-surface.c
67+++ b/gfx/cairo/cairo/src/cairo-win32-surface.c
68@@ -54,16 +54,17 @@
69 #include "cairo-win32-private.h"
70 #include "cairo-scaled-font-subsets-private.h"
71 #include "cairo-surface-fallback-private.h"
72 #include "cairo-surface-clipper-private.h"
73 #include "cairo-gstate-private.h"
74 #include "cairo-private.h"
75 #include <wchar.h>
76 #include <windows.h>
77+#include <d3d9.h>
78
79 #if defined(__MINGW32__) && !defined(ETO_PDY)
80 # define ETO_PDY 0x2000
81 #endif
82
83 #undef DEBUG_COMPOSITE
84
85 /* for older SDKs */
86@@ -384,16 +385,17 @@ static cairo_surface_t *
87
88     surface->image = cairo_image_surface_create_for_data (bits, format,
89 							  width, height, rowstride);
90     status = surface->image->status;
91     if (status)
92 	goto FAIL;
93
94     surface->format = format;
95+    surface->d3d9surface = NULL;
96
97     surface->clip_rect.x = 0;
98     surface->clip_rect.y = 0;
99     surface->clip_rect.width = width;
100     surface->clip_rect.height = height;
101
102     surface->initial_clip_rgn = NULL;
103     surface->had_simple_clip = FALSE;
104@@ -481,26 +483,73 @@ cairo_status_t
105     if (surface->bitmap) {
106 	SelectObject (surface->dc, surface->saved_dc_bitmap);
107 	DeleteObject (surface->bitmap);
108 	DeleteDC (surface->dc);
109     } else {
110 	_cairo_win32_restore_initial_clip (surface);
111     }
112
113+    if (surface->d3d9surface) {
114+        IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc);
115+        IDirect3DSurface9_Release (surface->d3d9surface);
116+    }
117+
118     if (surface->initial_clip_rgn)
119 	DeleteObject (surface->initial_clip_rgn);
120
121     if (surface->font_subsets != NULL)
122 	_cairo_scaled_font_subsets_destroy (surface->font_subsets);
123
124     return CAIRO_STATUS_SUCCESS;
125 }
126
127 static cairo_status_t
128+_cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t  *surface,
129+				   int                     x,
130+				   int                     y,
131+				   int                     width,
132+				   int                     height,
133+				   cairo_image_surface_t **local_out)
134+{
135+    cairo_image_surface_t *local;
136+    cairo_int_status_t status;
137+
138+    RECT rectin = { x, y, x+width, y+height };
139+    D3DLOCKED_RECT rectout;
140+    HRESULT hr;
141+    hr = IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc);
142+    hr = IDirect3DSurface9_LockRect (surface->d3d9surface,
143+	                             &rectout, &rectin, 0);
144+    surface->dc = 0; // Don't use the DC when this is locked!
145+    if (hr) {
146+        IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
147+        return CAIRO_INT_STATUS_UNSUPPORTED;
148+    }
149+    local = cairo_image_surface_create_for_data (rectout.pBits,
150+	                                         surface->format,
151+						 width, height,
152+						 rectout.Pitch);
153+    if (local == NULL) {
154+	IDirect3DSurface9_UnlockRect (surface->d3d9surface);
155+	IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
156+        return CAIRO_INT_STATUS_UNSUPPORTED;
157+    }
158+    if (local->base.status) {
159+	IDirect3DSurface9_UnlockRect (surface->d3d9surface);
160+	IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
161+        return local->base.status;
162+    }
163+
164+    *local_out = local;
165+
166+    return CAIRO_STATUS_SUCCESS;
167+}
168+
169+static cairo_status_t
170 _cairo_win32_surface_get_subimage (cairo_win32_surface_t  *surface,
171 				   int                     x,
172 				   int                     y,
173 				   int                     width,
174 				   int                     height,
175 				   cairo_win32_surface_t **local_out)
176 {
177     cairo_win32_surface_t *local;
178@@ -599,17 +648,16 @@ static void
179 }
180
181 static cairo_status_t
182 _cairo_win32_surface_acquire_source_image (void                    *abstract_surface,
183 					   cairo_image_surface_t  **image_out,
184 					   void                   **image_extra)
185 {
186     cairo_win32_surface_t *surface = abstract_surface;
187-    cairo_win32_surface_t *local;
188     cairo_status_t status;
189
190     if (!surface->image && !surface->is_dib && surface->bitmap &&
191 	(surface->flags & CAIRO_WIN32_SURFACE_CAN_CONVERT_TO_DIB) != 0)
192     {
193 	/* This is a DDB, and we're being asked to use it as a source for
194 	 * something that we couldn't support natively.  So turn it into
195 	 * a DIB, so that we have an equivalent image surface, as long
196@@ -619,69 +667,109 @@ static cairo_status_t
197     }
198
199     if (surface->image) {
200 	*image_out = (cairo_image_surface_t *)surface->image;
201 	*image_extra = NULL;
202 	return CAIRO_STATUS_SUCCESS;
203     }
204
205-    status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0,
206-						surface->extents.width,
207-						surface->extents.height, &local);
208-    if (status)
209-	return status;
210-
211-    *image_out = (cairo_image_surface_t *)local->image;
212-    *image_extra = local;
213+    if (surface->d3d9surface) {
214+	cairo_image_surface_t *local;
215+	status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface, 0, 0,
216+						      surface->extents.width,
217+						      surface->extents.height, &local);
218+	if (status)
219+	    return status;
220+
221+	*image_out = local;
222+	*image_extra = surface;
223+    } else {
224+	cairo_win32_surface_t *local;
225+	status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0,
226+						    surface->extents.width,
227+						    surface->extents.height, &local);
228+	if (status)
229+	    return status;
230+
231+	*image_out = (cairo_image_surface_t *)local->image;
232+	*image_extra = local;
233+    }
234+    // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points
235+    // to the original surface to get back the d3d9surface and properly unlock.
236+
237     return CAIRO_STATUS_SUCCESS;
238 }
239
240 static void
241 _cairo_win32_surface_release_source_image (void                   *abstract_surface,
242 					   cairo_image_surface_t  *image,
243 					   void                   *image_extra)
244 {
245+    cairo_win32_surface_t *surface = abstract_surface;
246     cairo_win32_surface_t *local = image_extra;
247
248-    if (local)
249+    if (local && local->d3d9surface) {
250+	IDirect3DSurface9_UnlockRect (local->d3d9surface);
251+	IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc);
252+	cairo_surface_destroy ((cairo_surface_t *)image);
253+    } else {
254 	cairo_surface_destroy ((cairo_surface_t *)local);
255+    }
256 }
257
258 static cairo_status_t
259 _cairo_win32_surface_acquire_dest_image (void                    *abstract_surface,
260 					 cairo_rectangle_int_t   *interest_rect,
261 					 cairo_image_surface_t  **image_out,
262 					 cairo_rectangle_int_t   *image_rect,
263 					 void                   **image_extra)
264 {
265     cairo_win32_surface_t *surface = abstract_surface;
266-    cairo_win32_surface_t *local = NULL;
267     cairo_status_t status;
268
269     if (surface->image) {
270 	GdiFlush();
271
272 	*image_out = (cairo_image_surface_t *) surface->image;
273 	*image_extra = NULL;
274 	*image_rect = surface->extents;
275 	return CAIRO_STATUS_SUCCESS;
276     }
277
278-    status = _cairo_win32_surface_get_subimage (abstract_surface,
279+    if (surface->d3d9surface) {
280+	cairo_image_surface_t *local = NULL;
281+	status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface,
282 						interest_rect->x,
283 						interest_rect->y,
284 						interest_rect->width,
285-						interest_rect->height,
286-						&local);
287-    if (status)
288-	return status;
289-
290-    *image_out = (cairo_image_surface_t *) local->image;
291-    *image_extra = local;
292+						interest_rect->height, &local);
293+
294+	if (status)
295+	    return status;
296+
297+	*image_out = local;
298+	*image_extra = surface;
299+    } else {
300+	cairo_win32_surface_t *local = NULL;
301+	status = _cairo_win32_surface_get_subimage (abstract_surface,
302+						interest_rect->x,
303+						interest_rect->y,
304+						interest_rect->width,
305+						interest_rect->height, &local);
306+
307+	if (status)
308+	    return status;
309+
310+	*image_out = (cairo_image_surface_t *) local->image;
311+	*image_extra = local;
312+    }
313+    // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points
314+    // to the original surface to get back the d3d9surface and properly unlock.
315+
316     *image_rect = *interest_rect;
317     return CAIRO_STATUS_SUCCESS;
318 }
319
320 static void
321 _cairo_win32_surface_release_dest_image (void                    *abstract_surface,
322 					 cairo_rectangle_int_t   *interest_rect,
323 					 cairo_image_surface_t   *image,
324@@ -689,29 +777,37 @@ static void
325 					 void                    *image_extra)
326 {
327     cairo_win32_surface_t *surface = abstract_surface;
328     cairo_win32_surface_t *local = image_extra;
329
330     if (!local)
331 	return;
332
333-    /* clear any clip that's currently set on the surface
334-       so that we can blit uninhibited. */
335-    _cairo_win32_surface_set_clip_region (surface, NULL);
336-
337-    if (!BitBlt (surface->dc,
338-		 image_rect->x, image_rect->y,
339-		 image_rect->width, image_rect->height,
340-		 local->dc,
341-		 0, 0,
342-		 SRCCOPY))
343-	_cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image");
344-
345-    cairo_surface_destroy ((cairo_surface_t *)local);
346+    if (local->d3d9surface) {
347+	IDirect3DSurface9_UnlockRect (local->d3d9surface);
348+	IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc);
349+	cairo_surface_destroy ((cairo_surface_t *)image);
350+    } else {
351+
352+	/* clear any clip that's currently set on the surface
353+	   so that we can blit uninhibited. */
354+	_cairo_win32_surface_set_clip_region (surface, NULL);
355+
356+	if (!BitBlt (surface->dc,
357+		     image_rect->x, image_rect->y,
358+		     image_rect->width, image_rect->height,
359+		     local->dc,
360+		     0, 0,
361+		     SRCCOPY))
362+	    _cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image");
363+
364+	cairo_surface_destroy ((cairo_surface_t *)local);
365+    }
366+
367 }
368
369 cairo_status_t
370 _cairo_win32_surface_set_clip_region (void           *abstract_surface,
371 				      cairo_region_t *region)
372 {
373     cairo_win32_surface_t *surface = abstract_surface;
374     cairo_status_t status = CAIRO_STATUS_SUCCESS;
375@@ -1849,16 +1945,17 @@ cairo_win32_surface_create_internal (HDC
376 	free (surface);
377 	return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
378     }
379
380     surface->clip_region = NULL;
381     surface->image = NULL;
382     surface->format = format;
383
384+    surface->d3d9surface = NULL;
385     surface->dc = hdc;
386     surface->bitmap = NULL;
387     surface->is_dib = FALSE;
388     surface->saved_dc_bitmap = NULL;
389     surface->brush = NULL;
390     surface->old_brush = NULL;
391     surface->font_subsets = NULL;
392
393@@ -2009,16 +2106,29 @@ cairo_win32_surface_create_with_ddb (HDC
394
395 FINISH:
396     if (screen_dc)
397 	ReleaseDC (NULL, screen_dc);
398
399     return (cairo_surface_t*) new_surf;
400 }
401
402+cairo_public cairo_surface_t *
403+cairo_win32_surface_create_with_d3dsurface9 (IDirect3DSurface9 *surface)
404+{
405+    HDC dc;
406+    cairo_win32_surface_t *win_surface;
407+
408+    IDirect3DSurface9_AddRef (surface);
409+    IDirect3DSurface9_GetDC (surface, &dc);
410+    win_surface = cairo_win32_surface_create_internal(dc, CAIRO_FORMAT_RGB24);
411+    win_surface->d3d9surface = surface;
412+    return (cairo_surface_t*) win_surface;
413+
414+}
415 /**
416  * _cairo_surface_is_win32:
417  * @surface: a #cairo_surface_t
418  *
419  * Checks if a surface is a win32 surface.  This will
420  * return False if this is a win32 printing surface; use
421  * _cairo_surface_is_win32_printing() to check for that.
422  *
423diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h
424--- a/gfx/cairo/cairo/src/cairo-win32.h
425+++ b/gfx/cairo/cairo/src/cairo-win32.h
426@@ -59,17 +59,16 @@ cairo_win32_surface_create_with_ddb (HDC hdc,
427                                      cairo_format_t format,
428                                      int width,
429                                      int height);
430
431 cairo_public cairo_surface_t *
432 cairo_win32_surface_create_with_dib (cairo_format_t format,
433                                      int width,
434                                      int height);
435-
436 cairo_public HDC
437 cairo_win32_surface_get_dc (cairo_surface_t *surface);
438
439 cairo_public HDC
440 cairo_win32_get_dc_with_clip (cairo_t *cr);
441
442 cairo_public cairo_surface_t *
443 cairo_win32_surface_get_image (cairo_surface_t *surface);
444@@ -143,16 +142,21 @@ cairo_dwrite_scaled_font_get_force_GDI_classic(cairo_scaled_font_t *dwrite_scale
445 void
446 cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode);
447
448 int
449 cairo_dwrite_get_cleartype_rendering_mode();
450
451 #endif /* CAIRO_HAS_DWRITE_FONT */
452
453+struct IDirect3DSurface9;
454+cairo_public cairo_surface_t *
455+cairo_win32_surface_create_with_d3dsurface9 (struct IDirect3DSurface9 *surface);
456+
457+
458 #if CAIRO_HAS_D2D_SURFACE
459
460 struct _cairo_device
461 {
462     int type;
463     int refcount;
464 };
465
466