1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/win32-d3dsurface9.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,465 @@ 1.4 +diff --git a/gfx/cairo/cairo/src/cairo-rename.h b/gfx/cairo/cairo/src/cairo-rename.h 1.5 +--- a/gfx/cairo/cairo/src/cairo-rename.h 1.6 ++++ b/gfx/cairo/cairo/src/cairo-rename.h 1.7 +@@ -335,16 +335,17 @@ 1.8 + #define cairo_win32_font_face_create_for_logfontw_hfont _moz_cairo_win32_font_face_create_for_logfontw_hfont 1.9 + #define cairo_win32_printing_surface_create _moz_cairo_win32_printing_surface_create 1.10 + #define cairo_win32_scaled_font_done_font _moz_cairo_win32_scaled_font_done_font 1.11 + #define cairo_win32_scaled_font_get_device_to_logical _moz_cairo_win32_scaled_font_get_device_to_logical 1.12 + #define cairo_win32_scaled_font_get_logical_to_device _moz_cairo_win32_scaled_font_get_logical_to_device 1.13 + #define cairo_win32_scaled_font_get_metrics_factor _moz_cairo_win32_scaled_font_get_metrics_factor 1.14 + #define cairo_win32_scaled_font_select_font _moz_cairo_win32_scaled_font_select_font 1.15 + #define cairo_win32_surface_create _moz_cairo_win32_surface_create 1.16 ++#define cairo_win32_surface_create_with_d3dsurface9 _moz_cairo_win32_surface_create_with_d3dsurface9 1.17 + #define cairo_win32_surface_create_with_ddb _moz_cairo_win32_surface_create_with_ddb 1.18 + #define cairo_win32_surface_create_with_dib _moz_cairo_win32_surface_create_with_dib 1.19 + #define cairo_win32_surface_get_dc _moz_cairo_win32_surface_get_dc 1.20 + #define cairo_win32_surface_get_image _moz_cairo_win32_surface_get_image 1.21 + #define cairo_xcb_surface_create _moz_cairo_xcb_surface_create 1.22 + #define cairo_xcb_surface_create_for_bitmap _moz_cairo_xcb_surface_create_for_bitmap 1.23 + #define cairo_xcb_surface_create_with_xrender_format _moz_cairo_xcb_surface_create_with_xrender_format 1.24 + #define cairo_xcb_surface_set_size _moz_cairo_xcb_surface_set_size 1.25 +diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c 1.26 +--- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c 1.27 ++++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c 1.28 +@@ -1852,16 +1852,17 @@ cairo_win32_printing_surface_create (HDC 1.29 + } 1.30 + 1.31 + _cairo_surface_clipper_init (&surface->clipper, 1.32 + _cairo_win32_printing_surface_clipper_intersect_clip_path); 1.33 + 1.34 + surface->image = NULL; 1.35 + surface->format = CAIRO_FORMAT_RGB24; 1.36 + surface->content = CAIRO_CONTENT_COLOR_ALPHA; 1.37 ++ surface->d3d9surface = NULL; 1.38 + 1.39 + surface->dc = hdc; 1.40 + surface->bitmap = NULL; 1.41 + surface->is_dib = FALSE; 1.42 + surface->saved_dc_bitmap = NULL; 1.43 + surface->brush = NULL; 1.44 + surface->old_brush = NULL; 1.45 + surface->font_subsets = _cairo_scaled_font_subsets_create_scaled (); 1.46 +diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h 1.47 +--- a/gfx/cairo/cairo/src/cairo-win32-private.h 1.48 ++++ b/gfx/cairo/cairo/src/cairo-win32-private.h 1.49 +@@ -54,16 +54,18 @@ CAIRO_BEGIN_DECLS 1.50 + 1.51 + typedef struct _cairo_win32_surface { 1.52 + cairo_surface_t base; 1.53 + 1.54 + cairo_format_t format; 1.55 + 1.56 + HDC dc; 1.57 + 1.58 ++ struct IDirect3DSurface9 *d3d9surface; 1.59 ++ 1.60 + /* We create off-screen surfaces as DIBs or DDBs, based on what we created 1.61 + * originally*/ 1.62 + HBITMAP bitmap; 1.63 + cairo_bool_t is_dib; 1.64 + 1.65 + /* Used to save the initial 1x1 monochrome bitmap for the DC to 1.66 + * select back into the DC before deleting the DC and our 1.67 + * bitmap. For Windows XP, this doesn't seem to be necessary 1.68 +diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c 1.69 +--- a/gfx/cairo/cairo/src/cairo-win32-surface.c 1.70 ++++ b/gfx/cairo/cairo/src/cairo-win32-surface.c 1.71 +@@ -54,16 +54,17 @@ 1.72 + #include "cairo-win32-private.h" 1.73 + #include "cairo-scaled-font-subsets-private.h" 1.74 + #include "cairo-surface-fallback-private.h" 1.75 + #include "cairo-surface-clipper-private.h" 1.76 + #include "cairo-gstate-private.h" 1.77 + #include "cairo-private.h" 1.78 + #include <wchar.h> 1.79 + #include <windows.h> 1.80 ++#include <d3d9.h> 1.81 + 1.82 + #if defined(__MINGW32__) && !defined(ETO_PDY) 1.83 + # define ETO_PDY 0x2000 1.84 + #endif 1.85 + 1.86 + #undef DEBUG_COMPOSITE 1.87 + 1.88 + /* for older SDKs */ 1.89 +@@ -384,16 +385,17 @@ static cairo_surface_t * 1.90 + 1.91 + surface->image = cairo_image_surface_create_for_data (bits, format, 1.92 + width, height, rowstride); 1.93 + status = surface->image->status; 1.94 + if (status) 1.95 + goto FAIL; 1.96 + 1.97 + surface->format = format; 1.98 ++ surface->d3d9surface = NULL; 1.99 + 1.100 + surface->clip_rect.x = 0; 1.101 + surface->clip_rect.y = 0; 1.102 + surface->clip_rect.width = width; 1.103 + surface->clip_rect.height = height; 1.104 + 1.105 + surface->initial_clip_rgn = NULL; 1.106 + surface->had_simple_clip = FALSE; 1.107 +@@ -481,26 +483,73 @@ cairo_status_t 1.108 + if (surface->bitmap) { 1.109 + SelectObject (surface->dc, surface->saved_dc_bitmap); 1.110 + DeleteObject (surface->bitmap); 1.111 + DeleteDC (surface->dc); 1.112 + } else { 1.113 + _cairo_win32_restore_initial_clip (surface); 1.114 + } 1.115 + 1.116 ++ if (surface->d3d9surface) { 1.117 ++ IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc); 1.118 ++ IDirect3DSurface9_Release (surface->d3d9surface); 1.119 ++ } 1.120 ++ 1.121 + if (surface->initial_clip_rgn) 1.122 + DeleteObject (surface->initial_clip_rgn); 1.123 + 1.124 + if (surface->font_subsets != NULL) 1.125 + _cairo_scaled_font_subsets_destroy (surface->font_subsets); 1.126 + 1.127 + return CAIRO_STATUS_SUCCESS; 1.128 + } 1.129 + 1.130 + static cairo_status_t 1.131 ++_cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface, 1.132 ++ int x, 1.133 ++ int y, 1.134 ++ int width, 1.135 ++ int height, 1.136 ++ cairo_image_surface_t **local_out) 1.137 ++{ 1.138 ++ cairo_image_surface_t *local; 1.139 ++ cairo_int_status_t status; 1.140 ++ 1.141 ++ RECT rectin = { x, y, x+width, y+height }; 1.142 ++ D3DLOCKED_RECT rectout; 1.143 ++ HRESULT hr; 1.144 ++ hr = IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc); 1.145 ++ hr = IDirect3DSurface9_LockRect (surface->d3d9surface, 1.146 ++ &rectout, &rectin, 0); 1.147 ++ surface->dc = 0; // Don't use the DC when this is locked! 1.148 ++ if (hr) { 1.149 ++ IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); 1.150 ++ return CAIRO_INT_STATUS_UNSUPPORTED; 1.151 ++ } 1.152 ++ local = cairo_image_surface_create_for_data (rectout.pBits, 1.153 ++ surface->format, 1.154 ++ width, height, 1.155 ++ rectout.Pitch); 1.156 ++ if (local == NULL) { 1.157 ++ IDirect3DSurface9_UnlockRect (surface->d3d9surface); 1.158 ++ IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); 1.159 ++ return CAIRO_INT_STATUS_UNSUPPORTED; 1.160 ++ } 1.161 ++ if (local->base.status) { 1.162 ++ IDirect3DSurface9_UnlockRect (surface->d3d9surface); 1.163 ++ IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); 1.164 ++ return local->base.status; 1.165 ++ } 1.166 ++ 1.167 ++ *local_out = local; 1.168 ++ 1.169 ++ return CAIRO_STATUS_SUCCESS; 1.170 ++} 1.171 ++ 1.172 ++static cairo_status_t 1.173 + _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface, 1.174 + int x, 1.175 + int y, 1.176 + int width, 1.177 + int height, 1.178 + cairo_win32_surface_t **local_out) 1.179 + { 1.180 + cairo_win32_surface_t *local; 1.181 +@@ -599,17 +648,16 @@ static void 1.182 + } 1.183 + 1.184 + static cairo_status_t 1.185 + _cairo_win32_surface_acquire_source_image (void *abstract_surface, 1.186 + cairo_image_surface_t **image_out, 1.187 + void **image_extra) 1.188 + { 1.189 + cairo_win32_surface_t *surface = abstract_surface; 1.190 +- cairo_win32_surface_t *local; 1.191 + cairo_status_t status; 1.192 + 1.193 + if (!surface->image && !surface->is_dib && surface->bitmap && 1.194 + (surface->flags & CAIRO_WIN32_SURFACE_CAN_CONVERT_TO_DIB) != 0) 1.195 + { 1.196 + /* This is a DDB, and we're being asked to use it as a source for 1.197 + * something that we couldn't support natively. So turn it into 1.198 + * a DIB, so that we have an equivalent image surface, as long 1.199 +@@ -619,69 +667,109 @@ static cairo_status_t 1.200 + } 1.201 + 1.202 + if (surface->image) { 1.203 + *image_out = (cairo_image_surface_t *)surface->image; 1.204 + *image_extra = NULL; 1.205 + return CAIRO_STATUS_SUCCESS; 1.206 + } 1.207 + 1.208 +- status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0, 1.209 +- surface->extents.width, 1.210 +- surface->extents.height, &local); 1.211 +- if (status) 1.212 +- return status; 1.213 +- 1.214 +- *image_out = (cairo_image_surface_t *)local->image; 1.215 +- *image_extra = local; 1.216 ++ if (surface->d3d9surface) { 1.217 ++ cairo_image_surface_t *local; 1.218 ++ status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface, 0, 0, 1.219 ++ surface->extents.width, 1.220 ++ surface->extents.height, &local); 1.221 ++ if (status) 1.222 ++ return status; 1.223 ++ 1.224 ++ *image_out = local; 1.225 ++ *image_extra = surface; 1.226 ++ } else { 1.227 ++ cairo_win32_surface_t *local; 1.228 ++ status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0, 1.229 ++ surface->extents.width, 1.230 ++ surface->extents.height, &local); 1.231 ++ if (status) 1.232 ++ return status; 1.233 ++ 1.234 ++ *image_out = (cairo_image_surface_t *)local->image; 1.235 ++ *image_extra = local; 1.236 ++ } 1.237 ++ // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points 1.238 ++ // to the original surface to get back the d3d9surface and properly unlock. 1.239 ++ 1.240 + return CAIRO_STATUS_SUCCESS; 1.241 + } 1.242 + 1.243 + static void 1.244 + _cairo_win32_surface_release_source_image (void *abstract_surface, 1.245 + cairo_image_surface_t *image, 1.246 + void *image_extra) 1.247 + { 1.248 ++ cairo_win32_surface_t *surface = abstract_surface; 1.249 + cairo_win32_surface_t *local = image_extra; 1.250 + 1.251 +- if (local) 1.252 ++ if (local && local->d3d9surface) { 1.253 ++ IDirect3DSurface9_UnlockRect (local->d3d9surface); 1.254 ++ IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc); 1.255 ++ cairo_surface_destroy ((cairo_surface_t *)image); 1.256 ++ } else { 1.257 + cairo_surface_destroy ((cairo_surface_t *)local); 1.258 ++ } 1.259 + } 1.260 + 1.261 + static cairo_status_t 1.262 + _cairo_win32_surface_acquire_dest_image (void *abstract_surface, 1.263 + cairo_rectangle_int_t *interest_rect, 1.264 + cairo_image_surface_t **image_out, 1.265 + cairo_rectangle_int_t *image_rect, 1.266 + void **image_extra) 1.267 + { 1.268 + cairo_win32_surface_t *surface = abstract_surface; 1.269 +- cairo_win32_surface_t *local = NULL; 1.270 + cairo_status_t status; 1.271 + 1.272 + if (surface->image) { 1.273 + GdiFlush(); 1.274 + 1.275 + *image_out = (cairo_image_surface_t *) surface->image; 1.276 + *image_extra = NULL; 1.277 + *image_rect = surface->extents; 1.278 + return CAIRO_STATUS_SUCCESS; 1.279 + } 1.280 + 1.281 +- status = _cairo_win32_surface_get_subimage (abstract_surface, 1.282 ++ if (surface->d3d9surface) { 1.283 ++ cairo_image_surface_t *local = NULL; 1.284 ++ status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface, 1.285 + interest_rect->x, 1.286 + interest_rect->y, 1.287 + interest_rect->width, 1.288 +- interest_rect->height, 1.289 +- &local); 1.290 +- if (status) 1.291 +- return status; 1.292 +- 1.293 +- *image_out = (cairo_image_surface_t *) local->image; 1.294 +- *image_extra = local; 1.295 ++ interest_rect->height, &local); 1.296 ++ 1.297 ++ if (status) 1.298 ++ return status; 1.299 ++ 1.300 ++ *image_out = local; 1.301 ++ *image_extra = surface; 1.302 ++ } else { 1.303 ++ cairo_win32_surface_t *local = NULL; 1.304 ++ status = _cairo_win32_surface_get_subimage (abstract_surface, 1.305 ++ interest_rect->x, 1.306 ++ interest_rect->y, 1.307 ++ interest_rect->width, 1.308 ++ interest_rect->height, &local); 1.309 ++ 1.310 ++ if (status) 1.311 ++ return status; 1.312 ++ 1.313 ++ *image_out = (cairo_image_surface_t *) local->image; 1.314 ++ *image_extra = local; 1.315 ++ } 1.316 ++ // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points 1.317 ++ // to the original surface to get back the d3d9surface and properly unlock. 1.318 ++ 1.319 + *image_rect = *interest_rect; 1.320 + return CAIRO_STATUS_SUCCESS; 1.321 + } 1.322 + 1.323 + static void 1.324 + _cairo_win32_surface_release_dest_image (void *abstract_surface, 1.325 + cairo_rectangle_int_t *interest_rect, 1.326 + cairo_image_surface_t *image, 1.327 +@@ -689,29 +777,37 @@ static void 1.328 + void *image_extra) 1.329 + { 1.330 + cairo_win32_surface_t *surface = abstract_surface; 1.331 + cairo_win32_surface_t *local = image_extra; 1.332 + 1.333 + if (!local) 1.334 + return; 1.335 + 1.336 +- /* clear any clip that's currently set on the surface 1.337 +- so that we can blit uninhibited. */ 1.338 +- _cairo_win32_surface_set_clip_region (surface, NULL); 1.339 +- 1.340 +- if (!BitBlt (surface->dc, 1.341 +- image_rect->x, image_rect->y, 1.342 +- image_rect->width, image_rect->height, 1.343 +- local->dc, 1.344 +- 0, 0, 1.345 +- SRCCOPY)) 1.346 +- _cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image"); 1.347 +- 1.348 +- cairo_surface_destroy ((cairo_surface_t *)local); 1.349 ++ if (local->d3d9surface) { 1.350 ++ IDirect3DSurface9_UnlockRect (local->d3d9surface); 1.351 ++ IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc); 1.352 ++ cairo_surface_destroy ((cairo_surface_t *)image); 1.353 ++ } else { 1.354 ++ 1.355 ++ /* clear any clip that's currently set on the surface 1.356 ++ so that we can blit uninhibited. */ 1.357 ++ _cairo_win32_surface_set_clip_region (surface, NULL); 1.358 ++ 1.359 ++ if (!BitBlt (surface->dc, 1.360 ++ image_rect->x, image_rect->y, 1.361 ++ image_rect->width, image_rect->height, 1.362 ++ local->dc, 1.363 ++ 0, 0, 1.364 ++ SRCCOPY)) 1.365 ++ _cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image"); 1.366 ++ 1.367 ++ cairo_surface_destroy ((cairo_surface_t *)local); 1.368 ++ } 1.369 ++ 1.370 + } 1.371 + 1.372 + cairo_status_t 1.373 + _cairo_win32_surface_set_clip_region (void *abstract_surface, 1.374 + cairo_region_t *region) 1.375 + { 1.376 + cairo_win32_surface_t *surface = abstract_surface; 1.377 + cairo_status_t status = CAIRO_STATUS_SUCCESS; 1.378 +@@ -1849,16 +1945,17 @@ cairo_win32_surface_create_internal (HDC 1.379 + free (surface); 1.380 + return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); 1.381 + } 1.382 + 1.383 + surface->clip_region = NULL; 1.384 + surface->image = NULL; 1.385 + surface->format = format; 1.386 + 1.387 ++ surface->d3d9surface = NULL; 1.388 + surface->dc = hdc; 1.389 + surface->bitmap = NULL; 1.390 + surface->is_dib = FALSE; 1.391 + surface->saved_dc_bitmap = NULL; 1.392 + surface->brush = NULL; 1.393 + surface->old_brush = NULL; 1.394 + surface->font_subsets = NULL; 1.395 + 1.396 +@@ -2009,16 +2106,29 @@ cairo_win32_surface_create_with_ddb (HDC 1.397 + 1.398 + FINISH: 1.399 + if (screen_dc) 1.400 + ReleaseDC (NULL, screen_dc); 1.401 + 1.402 + return (cairo_surface_t*) new_surf; 1.403 + } 1.404 + 1.405 ++cairo_public cairo_surface_t * 1.406 ++cairo_win32_surface_create_with_d3dsurface9 (IDirect3DSurface9 *surface) 1.407 ++{ 1.408 ++ HDC dc; 1.409 ++ cairo_win32_surface_t *win_surface; 1.410 ++ 1.411 ++ IDirect3DSurface9_AddRef (surface); 1.412 ++ IDirect3DSurface9_GetDC (surface, &dc); 1.413 ++ win_surface = cairo_win32_surface_create_internal(dc, CAIRO_FORMAT_RGB24); 1.414 ++ win_surface->d3d9surface = surface; 1.415 ++ return (cairo_surface_t*) win_surface; 1.416 ++ 1.417 ++} 1.418 + /** 1.419 + * _cairo_surface_is_win32: 1.420 + * @surface: a #cairo_surface_t 1.421 + * 1.422 + * Checks if a surface is a win32 surface. This will 1.423 + * return False if this is a win32 printing surface; use 1.424 + * _cairo_surface_is_win32_printing() to check for that. 1.425 + * 1.426 +diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h 1.427 +--- a/gfx/cairo/cairo/src/cairo-win32.h 1.428 ++++ b/gfx/cairo/cairo/src/cairo-win32.h 1.429 +@@ -59,17 +59,16 @@ cairo_win32_surface_create_with_ddb (HDC hdc, 1.430 + cairo_format_t format, 1.431 + int width, 1.432 + int height); 1.433 + 1.434 + cairo_public cairo_surface_t * 1.435 + cairo_win32_surface_create_with_dib (cairo_format_t format, 1.436 + int width, 1.437 + int height); 1.438 +- 1.439 + cairo_public HDC 1.440 + cairo_win32_surface_get_dc (cairo_surface_t *surface); 1.441 + 1.442 + cairo_public HDC 1.443 + cairo_win32_get_dc_with_clip (cairo_t *cr); 1.444 + 1.445 + cairo_public cairo_surface_t * 1.446 + cairo_win32_surface_get_image (cairo_surface_t *surface); 1.447 +@@ -143,16 +142,21 @@ cairo_dwrite_scaled_font_get_force_GDI_classic(cairo_scaled_font_t *dwrite_scale 1.448 + void 1.449 + cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode); 1.450 + 1.451 + int 1.452 + cairo_dwrite_get_cleartype_rendering_mode(); 1.453 + 1.454 + #endif /* CAIRO_HAS_DWRITE_FONT */ 1.455 + 1.456 ++struct IDirect3DSurface9; 1.457 ++cairo_public cairo_surface_t * 1.458 ++cairo_win32_surface_create_with_d3dsurface9 (struct IDirect3DSurface9 *surface); 1.459 ++ 1.460 ++ 1.461 + #if CAIRO_HAS_D2D_SURFACE 1.462 + 1.463 + struct _cairo_device 1.464 + { 1.465 + int type; 1.466 + int refcount; 1.467 + }; 1.468 +