From 44b3c4ca7875c20429d983c47437e16a01c45d3a Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 29 Aug 2003 17:57:08 +0000 Subject: [PATCH] Optimized _cairo_surface_composite for compositing local memory surface with an X11 server surface. --- ChangeLog | 7 +++++++ src/cairo-surface.c | 28 +++++++++++++++++++++++++--- src/cairo.h | 18 +++++++++--------- src/cairo_surface.c | 28 +++++++++++++++++++++++++--- 4 files changed, 66 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 733a40fe4..cb902f87a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2003-08-29 Carl Worth + + * src/cairo_surface.c (_cairo_surface_composite): Optimized case + where src is in memory, dst is on server, and mask is NULL. Will + now do a single XPutImage rather than the painful + GetImage/PutImage dance of the general code. + 2003-08-28 Carl Worth * src/cairo_traps.c (_line_segs_intersect_ceil): One more diff --git a/src/cairo-surface.c b/src/cairo-surface.c index 25815bce6..80906b9ac 100644 --- a/src/cairo-surface.c +++ b/src/cairo-surface.c @@ -588,17 +588,39 @@ _cairo_surface_composite (cairo_operator_t operator, { if (dst->type == CAIRO_SURFACE_TYPE_DRAWABLE && CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst) - && src->dpy == dst->dpy - && (mask == NULL || mask->dpy == dst->dpy)) { + && (mask == NULL || mask->dpy == dst->dpy) + && (src->type == CAIRO_SURFACE_TYPE_ICIMAGE || src->dpy == dst->dpy)) { + + cairo_surface_t *src_on_server = NULL; + + if (src->type == CAIRO_SURFACE_TYPE_ICIMAGE) { + cairo_matrix_t matrix; + src_on_server = cairo_surface_create_similar (dst, CAIRO_FORMAT_ARGB32, + IcImageGetWidth (src->icimage), + IcImageGetWidth (src->icimage)); + if (src_on_server == NULL) + return; + + cairo_surface_get_matrix (src, &matrix); + cairo_surface_set_matrix (src_on_server, &matrix); + + cairo_surface_put_image (src_on_server, + (char *) IcImageGetData (src->icimage), + IcImageGetWidth (src->icimage), + IcImageGetHeight (src->icimage), + IcImageGetStride (src->icimage)); + } XRenderComposite (dst->dpy, operator, - src->picture, + src_on_server ? src_on_server->picture : src->picture, mask ? mask->picture : 0, dst->picture, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height); + + } else { _cairo_surface_pull_image (src); _cairo_surface_pull_image (mask); diff --git a/src/cairo.h b/src/cairo.h index eb9322b09..3b55be52d 100644 --- a/src/cairo.h +++ b/src/cairo.h @@ -403,11 +403,11 @@ cairo_get_status_string (cairo_t *cr); cairo_surface_create_for_pixmap with a cairo_format_t. Would that work? */ extern cairo_surface_t * __external_linkage -cairo_surface_create_for_drawable (Display *dpy, - Drawable drawable, - Visual *visual, +cairo_surface_create_for_drawable (Display *dpy, + Drawable drawable, + Visual *visual, cairo_format_t format, - Colormap colormap); + Colormap colormap); extern cairo_surface_t * __external_linkage cairo_surface_create_for_image (char *data, @@ -418,7 +418,7 @@ cairo_surface_create_for_image (char *data, extern cairo_surface_t * __external_linkage cairo_surface_create_similar (cairo_surface_t *other, - cairo_format_t format, + cairo_format_t format, int width, int height); @@ -441,10 +441,10 @@ cairo_surface_destroy (cairo_surface_t *surface); extern cairo_status_t __external_linkage cairo_surface_put_image (cairo_surface_t *surface, - char *data, - int width, - int height, - int stride); + char *data, + int width, + int height, + int stride); /* XXX: NYI extern cairo_status_t __external_linkage diff --git a/src/cairo_surface.c b/src/cairo_surface.c index 25815bce6..80906b9ac 100644 --- a/src/cairo_surface.c +++ b/src/cairo_surface.c @@ -588,17 +588,39 @@ _cairo_surface_composite (cairo_operator_t operator, { if (dst->type == CAIRO_SURFACE_TYPE_DRAWABLE && CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst) - && src->dpy == dst->dpy - && (mask == NULL || mask->dpy == dst->dpy)) { + && (mask == NULL || mask->dpy == dst->dpy) + && (src->type == CAIRO_SURFACE_TYPE_ICIMAGE || src->dpy == dst->dpy)) { + + cairo_surface_t *src_on_server = NULL; + + if (src->type == CAIRO_SURFACE_TYPE_ICIMAGE) { + cairo_matrix_t matrix; + src_on_server = cairo_surface_create_similar (dst, CAIRO_FORMAT_ARGB32, + IcImageGetWidth (src->icimage), + IcImageGetWidth (src->icimage)); + if (src_on_server == NULL) + return; + + cairo_surface_get_matrix (src, &matrix); + cairo_surface_set_matrix (src_on_server, &matrix); + + cairo_surface_put_image (src_on_server, + (char *) IcImageGetData (src->icimage), + IcImageGetWidth (src->icimage), + IcImageGetHeight (src->icimage), + IcImageGetStride (src->icimage)); + } XRenderComposite (dst->dpy, operator, - src->picture, + src_on_server ? src_on_server->picture : src->picture, mask ? mask->picture : 0, dst->picture, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height); + + } else { _cairo_surface_pull_image (src); _cairo_surface_pull_image (mask);