diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-03 13:01:34 +0000 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2013-01-03 15:07:18 +0000 |
commit | 734a541dc34565f40fe0ae4e93c81c4849198a79 (patch) | |
tree | 5b9ca98233bb1b7548e787515b23ef668b041179 | |
parent | ecc8c28b24cb5fcd85aee5d4c82b9ad72c87fa69 (diff) |
xlib: Avoid copying the source twice if it is an image
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/cairo-xlib-source.c | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/src/cairo-xlib-source.c b/src/cairo-xlib-source.c index 42fc46ab..e312222a 100644 --- a/src/cairo-xlib-source.c +++ b/src/cairo-xlib-source.c @@ -46,7 +46,7 @@ #include "cairo-xlib-surface-private.h" #include "cairo-error-private.h" -#include "cairo-image-surface-private.h" +#include "cairo-image-surface-inline.h" #include "cairo-paginated-private.h" #include "cairo-pattern-inline.h" #include "cairo-recording-surface-private.h" @@ -897,8 +897,10 @@ surface_source (cairo_xlib_surface_t *dst, cairo_xlib_surface_t *xsrc; cairo_surface_pattern_t local_pattern; cairo_status_t status; - cairo_rectangle_int_t upload, limit, map_extents; + cairo_rectangle_int_t upload, limit; cairo_matrix_t m; + pixman_format_code_t format; + int draw_x, draw_y; src = pattern->surface; if (src->type == CAIRO_SURFACE_TYPE_IMAGE && @@ -952,18 +954,31 @@ prepare_shm_image: } } - src = _cairo_xlib_surface_create_similar_shm (&dst->base, - _cairo_format_from_content (pattern->surface->content), - upload.width, - upload.height); + if (_cairo_surface_is_image (src)) + format = ((cairo_image_surface_t *)src)->pixman_format; + else + format = _cairo_format_to_pixman_format_code (_cairo_format_from_content (src->content)); + src = _cairo_xlib_surface_create_shm (dst, format, + upload.width, upload.height); + if (src == NULL) { + if (_cairo_surface_is_image (pattern->surface)) { + draw_x = upload.x; + draw_y = upload.y; + src = cairo_surface_reference (pattern->surface); + goto skip_paint; + } + + src = _cairo_image_surface_create_with_pixman_format (NULL, + format, + upload.width, + upload.height, + 0); + } _cairo_pattern_init_for_surface (&local_pattern, pattern->surface); cairo_matrix_init_translate (&local_pattern.base.matrix, upload.x, upload.y); - map_extents = upload; - map_extents.x = map_extents.y = 0; - status = _cairo_surface_paint (src, CAIRO_OPERATOR_SOURCE, &local_pattern.base, @@ -975,6 +990,8 @@ prepare_shm_image: return _cairo_surface_create_in_error (status); } + draw_x = draw_y = 0; +skip_paint: _cairo_pattern_init_static_copy (&local_pattern.base, &pattern->base); if (upload.x | upload.y) { cairo_matrix_init_translate (&m, -upload.x, -upload.y); @@ -1002,7 +1019,7 @@ prepare_shm_image: } status = _cairo_xlib_surface_draw_image (xsrc, (cairo_image_surface_t *)src, - 0, 0, + draw_x, draw_y, upload.width, upload.height, 0, 0); cairo_surface_destroy (src); |