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