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