[1/3] win32: introduce new flag to mark surfaces supporting solid brush drawing

Submitted by Vasily Galkin on April 28, 2018, 7:26 p.m.

Details

Message ID 20180428192701.22786-1-galkin-vv@yandex.ru
State New
Headers show
Series "Series without cover letter" ( rev: 1 ) in Cairo

Not browsing as part of any series.

Commit Message

Vasily Galkin April 28, 2018, 7:26 p.m.
This is beginning of a patch series that speedups the CAIRO_OPERATOR_SOURCE
when used to copy data
to a 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 the gdi's inability to
correctly set alpha channel on all operations except BitBlt and AlphaBlend

So CAIRO_WIN32_SURFACE_CAN_RGB_BRUSH flag introduced in this commit
will be used as a mark that surfaces that correctly such handle brushes -
essentially all surface types except argb32.
_cairo_win32_flags_for_dc receives new argument
that would be used in flag calculation.
---
 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(-)

Patch hide | download patch | download mbox

diff --git a/src/win32/cairo-win32-device.c b/src/win32/cairo-win32-device.c
index c60c494..309f16c 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 92d1f6c..0d737f5 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;
 
@@ -973,7 +973,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 7f374a0..8496077 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 6fdf96f..79e1e0f 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 CHECKJPEGFORMAT 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 {
@@ -186,7 +189,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,

Comments

On Sat, Apr 28, 2018 at 10:26:59PM +0300, Vasily Galkin wrote:
> This is beginning of a patch series that speedups the CAIRO_OPERATOR_SOURCE
> when used to copy data
> to a 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 the gdi's inability to
> correctly set alpha channel on all operations except BitBlt and AlphaBlend
> 
> So CAIRO_WIN32_SURFACE_CAN_RGB_BRUSH flag introduced in this commit
> will be used as a mark that surfaces that correctly such handle brushes -
> essentially all surface types except argb32.
> _cairo_win32_flags_for_dc receives new argument
> that would be used in flag calculation.
> ---
>  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(-)

I'm not able to test on win32 myself, but the code changes look
straightforward enough, and feedback from testers seems quite positive.

I've done some copyediting of the commit message and comments but
otherwise applied the patches as proposed and landed to trunk:

To ssh://git.freedesktop.org/git/cairo
   85fe4de..c6e12d3  master -> master

Bryce
 
> diff --git a/src/win32/cairo-win32-device.c b/src/win32/cairo-win32-device.c
> index c60c494..309f16c 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 92d1f6c..0d737f5 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;
>  
> @@ -973,7 +973,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 7f374a0..8496077 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 6fdf96f..79e1e0f 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 CHECKJPEGFORMAT 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 {
> @@ -186,7 +189,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,
> -- 
> 2.9.3
> 
> -- 
> cairo mailing list
> cairo@cairographics.org
> https://lists.cairographics.org/mailman/listinfo/cairo