From 884275c3ab6e76ec2723cc889060b2791868190d Mon Sep 17 00:00:00 2001 From: Vasily Galkin Date: Sat, 28 Apr 2018 22:26:59 +0300 Subject: [PATCH] win32: Introduce new flag to mark surfaces that support solid brush drawing This is part of a patch series to speed up CAIRO_OPERATOR_SOURCE when used to copy data to an argb32 cairo surface corresponding to a win32 dc from a "backbuffer" - DibSection-based cairo surface created with cairo_surface_create_similar(). This initial patch presents only private header changes without changing any implementation logic. The big problem with argb32 surfaces and GDI is that GDI is unable to correctly set the alpha channel when using operations other than BitBlt and AlphaBlend. To solve this, a CAIRO_WIN32_SURFACE_CAN_RGB_BRUSH flag is introduced in this commit to be mark surfaces that correctly handle such brushes - essentially all surface types except argb32. The _cairo_win32_flags_for_dc() call receives a new argument that is used to calculate the flag. --- src/win32/cairo-win32-device.c | 2 +- src/win32/cairo-win32-display-surface.c | 4 ++-- src/win32/cairo-win32-printing-surface.c | 2 +- src/win32/cairo-win32-private.h | 5 ++++- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/win32/cairo-win32-device.c b/src/win32/cairo-win32-device.c index f0df15e1d..d2c1ac585 100644 --- a/src/win32/cairo-win32-device.c +++ b/src/win32/cairo-win32-device.c @@ -153,7 +153,7 @@ _cairo_win32_device_get (void) } unsigned -_cairo_win32_flags_for_dc (HDC dc) +_cairo_win32_flags_for_dc (HDC dc, cairo_format_t format) { uint32_t flags = 0; int cap; diff --git a/src/win32/cairo-win32-display-surface.c b/src/win32/cairo-win32-display-surface.c index 2b40e1acf..304d34aea 100644 --- a/src/win32/cairo-win32-display-surface.c +++ b/src/win32/cairo-win32-display-surface.c @@ -258,7 +258,7 @@ _create_dc_and_bitmap (cairo_win32_display_surface_t *surface, } } - surface->win32.flags = _cairo_win32_flags_for_dc (surface->win32.dc); + surface->win32.flags = _cairo_win32_flags_for_dc (surface->win32.dc, format); return CAIRO_STATUS_SUCCESS; @@ -1007,7 +1007,7 @@ cairo_win32_surface_create_with_format (HDC hdc, cairo_format_t format) surface->is_dib = FALSE; surface->saved_dc_bitmap = NULL; - surface->win32.flags = _cairo_win32_flags_for_dc (surface->win32.dc); + surface->win32.flags = _cairo_win32_flags_for_dc (surface->win32.dc, format); device = _cairo_win32_device_get (); diff --git a/src/win32/cairo-win32-printing-surface.c b/src/win32/cairo-win32-printing-surface.c index 7f88cd1e5..da7357caa 100644 --- a/src/win32/cairo-win32-printing-surface.c +++ b/src/win32/cairo-win32-printing-surface.c @@ -2159,7 +2159,7 @@ cairo_win32_printing_surface_create (HDC hdc) return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY)); } - surface->win32.flags = _cairo_win32_flags_for_dc (surface->win32.dc); + surface->win32.flags = _cairo_win32_flags_for_dc (surface->win32.dc, CAIRO_FORMAT_RGB24); surface->win32.flags |= CAIRO_WIN32_SURFACE_FOR_PRINTING; _cairo_win32_printing_surface_init_ps_mode (surface); diff --git a/src/win32/cairo-win32-private.h b/src/win32/cairo-win32-private.h index e3e13d5b1..85f88a9e8 100644 --- a/src/win32/cairo-win32-private.h +++ b/src/win32/cairo-win32-private.h @@ -81,6 +81,9 @@ enum { /* Whether we can use the CHECKPNGFORMAT escape function */ CAIRO_WIN32_SURFACE_CAN_CHECK_PNG = (1<<8), + + /* Whether we can use gdi drawing with solid rgb brush with this surface */ + CAIRO_WIN32_SURFACE_CAN_RGB_BRUSH = (1<<9), }; typedef struct _cairo_win32_surface { @@ -204,7 +207,7 @@ _cairo_win32_surface_get_extents (void *abstract_surface, cairo_rectangle_int_t *rectangle); uint32_t -_cairo_win32_flags_for_dc (HDC dc); +_cairo_win32_flags_for_dc (HDC dc, cairo_format_t format); cairo_int_status_t _cairo_win32_surface_emit_glyphs (cairo_win32_surface_t *dst,