michael@0: diff --git a/gfx/cairo/cairo/src/cairo-rename.h b/gfx/cairo/cairo/src/cairo-rename.h michael@0: --- a/gfx/cairo/cairo/src/cairo-rename.h michael@0: +++ b/gfx/cairo/cairo/src/cairo-rename.h michael@0: @@ -335,16 +335,17 @@ michael@0: #define cairo_win32_font_face_create_for_logfontw_hfont _moz_cairo_win32_font_face_create_for_logfontw_hfont michael@0: #define cairo_win32_printing_surface_create _moz_cairo_win32_printing_surface_create michael@0: #define cairo_win32_scaled_font_done_font _moz_cairo_win32_scaled_font_done_font michael@0: #define cairo_win32_scaled_font_get_device_to_logical _moz_cairo_win32_scaled_font_get_device_to_logical michael@0: #define cairo_win32_scaled_font_get_logical_to_device _moz_cairo_win32_scaled_font_get_logical_to_device michael@0: #define cairo_win32_scaled_font_get_metrics_factor _moz_cairo_win32_scaled_font_get_metrics_factor michael@0: #define cairo_win32_scaled_font_select_font _moz_cairo_win32_scaled_font_select_font michael@0: #define cairo_win32_surface_create _moz_cairo_win32_surface_create michael@0: +#define cairo_win32_surface_create_with_d3dsurface9 _moz_cairo_win32_surface_create_with_d3dsurface9 michael@0: #define cairo_win32_surface_create_with_ddb _moz_cairo_win32_surface_create_with_ddb michael@0: #define cairo_win32_surface_create_with_dib _moz_cairo_win32_surface_create_with_dib michael@0: #define cairo_win32_surface_get_dc _moz_cairo_win32_surface_get_dc michael@0: #define cairo_win32_surface_get_image _moz_cairo_win32_surface_get_image michael@0: #define cairo_xcb_surface_create _moz_cairo_xcb_surface_create michael@0: #define cairo_xcb_surface_create_for_bitmap _moz_cairo_xcb_surface_create_for_bitmap michael@0: #define cairo_xcb_surface_create_with_xrender_format _moz_cairo_xcb_surface_create_with_xrender_format michael@0: #define cairo_xcb_surface_set_size _moz_cairo_xcb_surface_set_size michael@0: diff --git a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c michael@0: --- a/gfx/cairo/cairo/src/cairo-win32-printing-surface.c michael@0: +++ b/gfx/cairo/cairo/src/cairo-win32-printing-surface.c michael@0: @@ -1852,16 +1852,17 @@ cairo_win32_printing_surface_create (HDC michael@0: } michael@0: michael@0: _cairo_surface_clipper_init (&surface->clipper, michael@0: _cairo_win32_printing_surface_clipper_intersect_clip_path); michael@0: michael@0: surface->image = NULL; michael@0: surface->format = CAIRO_FORMAT_RGB24; michael@0: surface->content = CAIRO_CONTENT_COLOR_ALPHA; michael@0: + surface->d3d9surface = NULL; michael@0: michael@0: surface->dc = hdc; michael@0: surface->bitmap = NULL; michael@0: surface->is_dib = FALSE; michael@0: surface->saved_dc_bitmap = NULL; michael@0: surface->brush = NULL; michael@0: surface->old_brush = NULL; michael@0: surface->font_subsets = _cairo_scaled_font_subsets_create_scaled (); michael@0: diff --git a/gfx/cairo/cairo/src/cairo-win32-private.h b/gfx/cairo/cairo/src/cairo-win32-private.h michael@0: --- a/gfx/cairo/cairo/src/cairo-win32-private.h michael@0: +++ b/gfx/cairo/cairo/src/cairo-win32-private.h michael@0: @@ -54,16 +54,18 @@ CAIRO_BEGIN_DECLS michael@0: michael@0: typedef struct _cairo_win32_surface { michael@0: cairo_surface_t base; michael@0: michael@0: cairo_format_t format; michael@0: michael@0: HDC dc; michael@0: michael@0: + struct IDirect3DSurface9 *d3d9surface; michael@0: + michael@0: /* We create off-screen surfaces as DIBs or DDBs, based on what we created michael@0: * originally*/ michael@0: HBITMAP bitmap; michael@0: cairo_bool_t is_dib; michael@0: michael@0: /* Used to save the initial 1x1 monochrome bitmap for the DC to michael@0: * select back into the DC before deleting the DC and our michael@0: * bitmap. For Windows XP, this doesn't seem to be necessary michael@0: diff --git a/gfx/cairo/cairo/src/cairo-win32-surface.c b/gfx/cairo/cairo/src/cairo-win32-surface.c michael@0: --- a/gfx/cairo/cairo/src/cairo-win32-surface.c michael@0: +++ b/gfx/cairo/cairo/src/cairo-win32-surface.c michael@0: @@ -54,16 +54,17 @@ michael@0: #include "cairo-win32-private.h" michael@0: #include "cairo-scaled-font-subsets-private.h" michael@0: #include "cairo-surface-fallback-private.h" michael@0: #include "cairo-surface-clipper-private.h" michael@0: #include "cairo-gstate-private.h" michael@0: #include "cairo-private.h" michael@0: #include michael@0: #include michael@0: +#include michael@0: michael@0: #if defined(__MINGW32__) && !defined(ETO_PDY) michael@0: # define ETO_PDY 0x2000 michael@0: #endif michael@0: michael@0: #undef DEBUG_COMPOSITE michael@0: michael@0: /* for older SDKs */ michael@0: @@ -384,16 +385,17 @@ static cairo_surface_t * michael@0: michael@0: surface->image = cairo_image_surface_create_for_data (bits, format, michael@0: width, height, rowstride); michael@0: status = surface->image->status; michael@0: if (status) michael@0: goto FAIL; michael@0: michael@0: surface->format = format; michael@0: + surface->d3d9surface = NULL; michael@0: michael@0: surface->clip_rect.x = 0; michael@0: surface->clip_rect.y = 0; michael@0: surface->clip_rect.width = width; michael@0: surface->clip_rect.height = height; michael@0: michael@0: surface->initial_clip_rgn = NULL; michael@0: surface->had_simple_clip = FALSE; michael@0: @@ -481,26 +483,73 @@ cairo_status_t michael@0: if (surface->bitmap) { michael@0: SelectObject (surface->dc, surface->saved_dc_bitmap); michael@0: DeleteObject (surface->bitmap); michael@0: DeleteDC (surface->dc); michael@0: } else { michael@0: _cairo_win32_restore_initial_clip (surface); michael@0: } michael@0: michael@0: + if (surface->d3d9surface) { michael@0: + IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc); michael@0: + IDirect3DSurface9_Release (surface->d3d9surface); michael@0: + } michael@0: + michael@0: if (surface->initial_clip_rgn) michael@0: DeleteObject (surface->initial_clip_rgn); michael@0: michael@0: if (surface->font_subsets != NULL) michael@0: _cairo_scaled_font_subsets_destroy (surface->font_subsets); michael@0: michael@0: return CAIRO_STATUS_SUCCESS; michael@0: } michael@0: michael@0: static cairo_status_t michael@0: +_cairo_win32_surface_d3d9_lock_rect (cairo_win32_surface_t *surface, michael@0: + int x, michael@0: + int y, michael@0: + int width, michael@0: + int height, michael@0: + cairo_image_surface_t **local_out) michael@0: +{ michael@0: + cairo_image_surface_t *local; michael@0: + cairo_int_status_t status; michael@0: + michael@0: + RECT rectin = { x, y, x+width, y+height }; michael@0: + D3DLOCKED_RECT rectout; michael@0: + HRESULT hr; michael@0: + hr = IDirect3DSurface9_ReleaseDC (surface->d3d9surface, surface->dc); michael@0: + hr = IDirect3DSurface9_LockRect (surface->d3d9surface, michael@0: + &rectout, &rectin, 0); michael@0: + surface->dc = 0; // Don't use the DC when this is locked! michael@0: + if (hr) { michael@0: + IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); michael@0: + return CAIRO_INT_STATUS_UNSUPPORTED; michael@0: + } michael@0: + local = cairo_image_surface_create_for_data (rectout.pBits, michael@0: + surface->format, michael@0: + width, height, michael@0: + rectout.Pitch); michael@0: + if (local == NULL) { michael@0: + IDirect3DSurface9_UnlockRect (surface->d3d9surface); michael@0: + IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); michael@0: + return CAIRO_INT_STATUS_UNSUPPORTED; michael@0: + } michael@0: + if (local->base.status) { michael@0: + IDirect3DSurface9_UnlockRect (surface->d3d9surface); michael@0: + IDirect3DSurface9_GetDC (surface->d3d9surface, &surface->dc); michael@0: + return local->base.status; michael@0: + } michael@0: + michael@0: + *local_out = local; michael@0: + michael@0: + return CAIRO_STATUS_SUCCESS; michael@0: +} michael@0: + michael@0: +static cairo_status_t michael@0: _cairo_win32_surface_get_subimage (cairo_win32_surface_t *surface, michael@0: int x, michael@0: int y, michael@0: int width, michael@0: int height, michael@0: cairo_win32_surface_t **local_out) michael@0: { michael@0: cairo_win32_surface_t *local; michael@0: @@ -599,17 +648,16 @@ static void michael@0: } michael@0: michael@0: static cairo_status_t michael@0: _cairo_win32_surface_acquire_source_image (void *abstract_surface, michael@0: cairo_image_surface_t **image_out, michael@0: void **image_extra) michael@0: { michael@0: cairo_win32_surface_t *surface = abstract_surface; michael@0: - cairo_win32_surface_t *local; michael@0: cairo_status_t status; michael@0: michael@0: if (!surface->image && !surface->is_dib && surface->bitmap && michael@0: (surface->flags & CAIRO_WIN32_SURFACE_CAN_CONVERT_TO_DIB) != 0) michael@0: { michael@0: /* This is a DDB, and we're being asked to use it as a source for michael@0: * something that we couldn't support natively. So turn it into michael@0: * a DIB, so that we have an equivalent image surface, as long michael@0: @@ -619,69 +667,109 @@ static cairo_status_t michael@0: } michael@0: michael@0: if (surface->image) { michael@0: *image_out = (cairo_image_surface_t *)surface->image; michael@0: *image_extra = NULL; michael@0: return CAIRO_STATUS_SUCCESS; michael@0: } michael@0: michael@0: - status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0, michael@0: - surface->extents.width, michael@0: - surface->extents.height, &local); michael@0: - if (status) michael@0: - return status; michael@0: - michael@0: - *image_out = (cairo_image_surface_t *)local->image; michael@0: - *image_extra = local; michael@0: + if (surface->d3d9surface) { michael@0: + cairo_image_surface_t *local; michael@0: + status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface, 0, 0, michael@0: + surface->extents.width, michael@0: + surface->extents.height, &local); michael@0: + if (status) michael@0: + return status; michael@0: + michael@0: + *image_out = local; michael@0: + *image_extra = surface; michael@0: + } else { michael@0: + cairo_win32_surface_t *local; michael@0: + status = _cairo_win32_surface_get_subimage (abstract_surface, 0, 0, michael@0: + surface->extents.width, michael@0: + surface->extents.height, &local); michael@0: + if (status) michael@0: + return status; michael@0: + michael@0: + *image_out = (cairo_image_surface_t *)local->image; michael@0: + *image_extra = local; michael@0: + } michael@0: + // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points michael@0: + // to the original surface to get back the d3d9surface and properly unlock. michael@0: + michael@0: return CAIRO_STATUS_SUCCESS; michael@0: } michael@0: michael@0: static void michael@0: _cairo_win32_surface_release_source_image (void *abstract_surface, michael@0: cairo_image_surface_t *image, michael@0: void *image_extra) michael@0: { michael@0: + cairo_win32_surface_t *surface = abstract_surface; michael@0: cairo_win32_surface_t *local = image_extra; michael@0: michael@0: - if (local) michael@0: + if (local && local->d3d9surface) { michael@0: + IDirect3DSurface9_UnlockRect (local->d3d9surface); michael@0: + IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc); michael@0: + cairo_surface_destroy ((cairo_surface_t *)image); michael@0: + } else { michael@0: cairo_surface_destroy ((cairo_surface_t *)local); michael@0: + } michael@0: } michael@0: michael@0: static cairo_status_t michael@0: _cairo_win32_surface_acquire_dest_image (void *abstract_surface, michael@0: cairo_rectangle_int_t *interest_rect, michael@0: cairo_image_surface_t **image_out, michael@0: cairo_rectangle_int_t *image_rect, michael@0: void **image_extra) michael@0: { michael@0: cairo_win32_surface_t *surface = abstract_surface; michael@0: - cairo_win32_surface_t *local = NULL; michael@0: cairo_status_t status; michael@0: michael@0: if (surface->image) { michael@0: GdiFlush(); michael@0: michael@0: *image_out = (cairo_image_surface_t *) surface->image; michael@0: *image_extra = NULL; michael@0: *image_rect = surface->extents; michael@0: return CAIRO_STATUS_SUCCESS; michael@0: } michael@0: michael@0: - status = _cairo_win32_surface_get_subimage (abstract_surface, michael@0: + if (surface->d3d9surface) { michael@0: + cairo_image_surface_t *local = NULL; michael@0: + status = _cairo_win32_surface_d3d9_lock_rect (abstract_surface, michael@0: interest_rect->x, michael@0: interest_rect->y, michael@0: interest_rect->width, michael@0: - interest_rect->height, michael@0: - &local); michael@0: - if (status) michael@0: - return status; michael@0: - michael@0: - *image_out = (cairo_image_surface_t *) local->image; michael@0: - *image_extra = local; michael@0: + interest_rect->height, &local); michael@0: + michael@0: + if (status) michael@0: + return status; michael@0: + michael@0: + *image_out = local; michael@0: + *image_extra = surface; michael@0: + } else { michael@0: + cairo_win32_surface_t *local = NULL; michael@0: + status = _cairo_win32_surface_get_subimage (abstract_surface, michael@0: + interest_rect->x, michael@0: + interest_rect->y, michael@0: + interest_rect->width, michael@0: + interest_rect->height, &local); michael@0: + michael@0: + if (status) michael@0: + return status; michael@0: + michael@0: + *image_out = (cairo_image_surface_t *) local->image; michael@0: + *image_extra = local; michael@0: + } michael@0: + // image_extra is always of type cairo_win32_surface_t. For d3d9surface it points michael@0: + // to the original surface to get back the d3d9surface and properly unlock. michael@0: + michael@0: *image_rect = *interest_rect; michael@0: return CAIRO_STATUS_SUCCESS; michael@0: } michael@0: michael@0: static void michael@0: _cairo_win32_surface_release_dest_image (void *abstract_surface, michael@0: cairo_rectangle_int_t *interest_rect, michael@0: cairo_image_surface_t *image, michael@0: @@ -689,29 +777,37 @@ static void michael@0: void *image_extra) michael@0: { michael@0: cairo_win32_surface_t *surface = abstract_surface; michael@0: cairo_win32_surface_t *local = image_extra; michael@0: michael@0: if (!local) michael@0: return; michael@0: michael@0: - /* clear any clip that's currently set on the surface michael@0: - so that we can blit uninhibited. */ michael@0: - _cairo_win32_surface_set_clip_region (surface, NULL); michael@0: - michael@0: - if (!BitBlt (surface->dc, michael@0: - image_rect->x, image_rect->y, michael@0: - image_rect->width, image_rect->height, michael@0: - local->dc, michael@0: - 0, 0, michael@0: - SRCCOPY)) michael@0: - _cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image"); michael@0: - michael@0: - cairo_surface_destroy ((cairo_surface_t *)local); michael@0: + if (local->d3d9surface) { michael@0: + IDirect3DSurface9_UnlockRect (local->d3d9surface); michael@0: + IDirect3DSurface9_GetDC (local->d3d9surface, &local->dc); michael@0: + cairo_surface_destroy ((cairo_surface_t *)image); michael@0: + } else { michael@0: + michael@0: + /* clear any clip that's currently set on the surface michael@0: + so that we can blit uninhibited. */ michael@0: + _cairo_win32_surface_set_clip_region (surface, NULL); michael@0: + michael@0: + if (!BitBlt (surface->dc, michael@0: + image_rect->x, image_rect->y, michael@0: + image_rect->width, image_rect->height, michael@0: + local->dc, michael@0: + 0, 0, michael@0: + SRCCOPY)) michael@0: + _cairo_win32_print_gdi_error ("_cairo_win32_surface_release_dest_image"); michael@0: + michael@0: + cairo_surface_destroy ((cairo_surface_t *)local); michael@0: + } michael@0: + michael@0: } michael@0: michael@0: cairo_status_t michael@0: _cairo_win32_surface_set_clip_region (void *abstract_surface, michael@0: cairo_region_t *region) michael@0: { michael@0: cairo_win32_surface_t *surface = abstract_surface; michael@0: cairo_status_t status = CAIRO_STATUS_SUCCESS; michael@0: @@ -1849,16 +1945,17 @@ cairo_win32_surface_create_internal (HDC michael@0: free (surface); michael@0: return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); michael@0: } michael@0: michael@0: surface->clip_region = NULL; michael@0: surface->image = NULL; michael@0: surface->format = format; michael@0: michael@0: + surface->d3d9surface = NULL; michael@0: surface->dc = hdc; michael@0: surface->bitmap = NULL; michael@0: surface->is_dib = FALSE; michael@0: surface->saved_dc_bitmap = NULL; michael@0: surface->brush = NULL; michael@0: surface->old_brush = NULL; michael@0: surface->font_subsets = NULL; michael@0: michael@0: @@ -2009,16 +2106,29 @@ cairo_win32_surface_create_with_ddb (HDC michael@0: michael@0: FINISH: michael@0: if (screen_dc) michael@0: ReleaseDC (NULL, screen_dc); michael@0: michael@0: return (cairo_surface_t*) new_surf; michael@0: } michael@0: michael@0: +cairo_public cairo_surface_t * michael@0: +cairo_win32_surface_create_with_d3dsurface9 (IDirect3DSurface9 *surface) michael@0: +{ michael@0: + HDC dc; michael@0: + cairo_win32_surface_t *win_surface; michael@0: + michael@0: + IDirect3DSurface9_AddRef (surface); michael@0: + IDirect3DSurface9_GetDC (surface, &dc); michael@0: + win_surface = cairo_win32_surface_create_internal(dc, CAIRO_FORMAT_RGB24); michael@0: + win_surface->d3d9surface = surface; michael@0: + return (cairo_surface_t*) win_surface; michael@0: + michael@0: +} michael@0: /** michael@0: * _cairo_surface_is_win32: michael@0: * @surface: a #cairo_surface_t michael@0: * michael@0: * Checks if a surface is a win32 surface. This will michael@0: * return False if this is a win32 printing surface; use michael@0: * _cairo_surface_is_win32_printing() to check for that. michael@0: * michael@0: diff --git a/gfx/cairo/cairo/src/cairo-win32.h b/gfx/cairo/cairo/src/cairo-win32.h michael@0: --- a/gfx/cairo/cairo/src/cairo-win32.h michael@0: +++ b/gfx/cairo/cairo/src/cairo-win32.h michael@0: @@ -59,17 +59,16 @@ cairo_win32_surface_create_with_ddb (HDC hdc, michael@0: cairo_format_t format, michael@0: int width, michael@0: int height); michael@0: michael@0: cairo_public cairo_surface_t * michael@0: cairo_win32_surface_create_with_dib (cairo_format_t format, michael@0: int width, michael@0: int height); michael@0: - michael@0: cairo_public HDC michael@0: cairo_win32_surface_get_dc (cairo_surface_t *surface); michael@0: michael@0: cairo_public HDC michael@0: cairo_win32_get_dc_with_clip (cairo_t *cr); michael@0: michael@0: cairo_public cairo_surface_t * michael@0: cairo_win32_surface_get_image (cairo_surface_t *surface); michael@0: @@ -143,16 +142,21 @@ cairo_dwrite_scaled_font_get_force_GDI_classic(cairo_scaled_font_t *dwrite_scale michael@0: void michael@0: cairo_dwrite_set_cleartype_params(FLOAT gamma, FLOAT contrast, FLOAT level, int geometry, int mode); michael@0: michael@0: int michael@0: cairo_dwrite_get_cleartype_rendering_mode(); michael@0: michael@0: #endif /* CAIRO_HAS_DWRITE_FONT */ michael@0: michael@0: +struct IDirect3DSurface9; michael@0: +cairo_public cairo_surface_t * michael@0: +cairo_win32_surface_create_with_d3dsurface9 (struct IDirect3DSurface9 *surface); michael@0: + michael@0: + michael@0: #if CAIRO_HAS_D2D_SURFACE michael@0: michael@0: struct _cairo_device michael@0: { michael@0: int type; michael@0: int refcount; michael@0: }; michael@0: