Merge m-c to b2g-inbound.
[gecko.git] / gfx / cairo / win32-d3dsurface9.patch
blobb0e80252fc5e3f054ad0bc697d0d3ad931949e8e
1 diff --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
22 diff --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
28 _cairo_surface_clipper_init (&surface->clipper,
29 _cairo_win32_printing_surface_clipper_intersect_clip_path);
31 surface->image = NULL;
32 surface->format = CAIRO_FORMAT_RGB24;
33 surface->content = CAIRO_CONTENT_COLOR_ALPHA;
34 + surface->d3d9surface = NULL;
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 ();
43 diff --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
48 typedef struct _cairo_win32_surface {
49 cairo_surface_t base;
51 cairo_format_t format;
53 HDC dc;
55 + struct IDirect3DSurface9 *d3d9surface;
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;
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
65 diff --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>
79 #if defined(__MINGW32__) && !defined(ETO_PDY)
80 # define ETO_PDY 0x2000
81 #endif
83 #undef DEBUG_COMPOSITE
85 /* for older SDKs */
86 @@ -384,16 +385,17 @@ static cairo_surface_t *
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;
94 surface->format = format;
95 + surface->d3d9surface = NULL;
97 surface->clip_rect.x = 0;
98 surface->clip_rect.y = 0;
99 surface->clip_rect.width = width;
100 surface->clip_rect.height = height;
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);
113 + if (surface->d3d9surface) {
114 + IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc);
115 + IDirect3DSurface9_Release (surface->d3d9surface);
118 if (surface->initial_clip_rgn)
119 DeleteObject (surface->initial_clip_rgn);
121 if (surface->font_subsets != NULL)
122 _cairo_scaled_font_subsets_destroy (surface->font_subsets);
124 return CAIRO_STATUS_SUCCESS;
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)
135 + cairo_image_surface_t *local;
136 + cairo_int_status_t status;
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;
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;
158 + if (local->base.status) {
159 + IDirect3DSurface9_UnlockRect (surface->d3d9surface);
160 + IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc);
161 + return local->base.status;
164 + *local_out = local;
166 + return CAIRO_STATUS_SUCCESS;
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)
177 cairo_win32_surface_t *local;
178 @@ -599,17 +648,16 @@ static void
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)
186 cairo_win32_surface_t *surface = abstract_surface;
187 - cairo_win32_surface_t *local;
188 cairo_status_t status;
190 if (!surface->image && !surface->is_dib && surface->bitmap &&
191 (surface->flags & CAIRO_WIN32_SURFACE_CAN_CONVERT_TO_DIB) != 0)
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
199 if (surface->image) {
200 *image_out = (cairo_image_surface_t *)surface->image;
201 *image_extra = NULL;
202 return CAIRO_STATUS_SUCCESS;
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;
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;
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;
231 + *image_out = (cairo_image_surface_t *)local->image;
232 + *image_extra = local;
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.
237 return CAIRO_STATUS_SUCCESS;
240 static void
241 _cairo_win32_surface_release_source_image (void *abstract_surface,
242 cairo_image_surface_t *image,
243 void *image_extra)
245 + cairo_win32_surface_t *surface = abstract_surface;
246 cairo_win32_surface_t *local = image_extra;
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);
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)
265 cairo_win32_surface_t *surface = abstract_surface;
266 - cairo_win32_surface_t *local = NULL;
267 cairo_status_t status;
269 if (surface->image) {
270 GdiFlush();
272 *image_out = (cairo_image_surface_t *) surface->image;
273 *image_extra = NULL;
274 *image_rect = surface->extents;
275 return CAIRO_STATUS_SUCCESS;
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;
290 - *image_out = (cairo_image_surface_t *) local->image;
291 - *image_extra = local;
292 + interest_rect->height, &local);
294 + if (status)
295 + return status;
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);
307 + if (status)
308 + return status;
310 + *image_out = (cairo_image_surface_t *) local->image;
311 + *image_extra = local;
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.
316 *image_rect = *interest_rect;
317 return CAIRO_STATUS_SUCCESS;
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)
327 cairo_win32_surface_t *surface = abstract_surface;
328 cairo_win32_surface_t *local = image_extra;
330 if (!local)
331 return;
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);
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");
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 {
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);
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");
364 + cairo_surface_destroy ((cairo_surface_t *)local);
369 cairo_status_t
370 _cairo_win32_surface_set_clip_region (void *abstract_surface,
371 cairo_region_t *region)
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));
380 surface->clip_region = NULL;
381 surface->image = NULL;
382 surface->format = format;
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;
393 @@ -2009,16 +2106,29 @@ cairo_win32_surface_create_with_ddb (HDC
395 FINISH:
396 if (screen_dc)
397 ReleaseDC (NULL, screen_dc);
399 return (cairo_surface_t*) new_surf;
402 +cairo_public cairo_surface_t *
403 +cairo_win32_surface_create_with_d3dsurface9 (IDirect3DSurface9 *surface)
405 + HDC dc;
406 + cairo_win32_surface_t *win_surface;
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;
416 * _cairo_surface_is_win32:
417 * @surface: a #cairo_surface_t
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.
423 diff --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);
431 cairo_public cairo_surface_t *
432 cairo_win32_surface_create_with_dib (cairo_format_t format,
433 int width,
434 int height);
436 cairo_public HDC
437 cairo_win32_surface_get_dc (cairo_surface_t *surface);
439 cairo_public HDC
440 cairo_win32_get_dc_with_clip (cairo_t *cr);
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);
449 cairo_dwrite_get_cleartype_rendering_mode();
451 #endif /* CAIRO_HAS_DWRITE_FONT */
453 +struct IDirect3DSurface9;
454 +cairo_public cairo_surface_t *
455 +cairo_win32_surface_create_with_d3dsurface9 (struct IDirect3DSurface9 *surface);
458 #if CAIRO_HAS_D2D_SURFACE
460 struct _cairo_device
462 int type;
463 int refcount;