[cairo-commit] 2 commits - src/cairo-xlib-render-compositor.c src/cairo-xlib-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Feb 23 05:45:32 PST 2012


 src/cairo-xlib-render-compositor.c |   96 ++++++++++++++++++++-----------------
 src/cairo-xlib-surface.c           |   22 +++-----
 2 files changed, 63 insertions(+), 55 deletions(-)

New commits:
commit b079f18fade93472db83b4decf086e30711a86d3
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 23 13:39:37 2012 +0000

    xlib: Handle window-to-window copies by avoiding the use of a clip region
    
    Rather than compress the copies into a clip + copy, iterate over and
    perform each copy separately so as to avoid the confusion for
    window-to-window copies and the solitary GC->pCompositeClip.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-xlib-render-compositor.c b/src/cairo-xlib-render-compositor.c
index 1067939..86641b9 100644
--- a/src/cairo-xlib-render-compositor.c
+++ b/src/cairo-xlib-render-compositor.c
@@ -164,18 +164,6 @@ copy_boxes (void *_dst,
     GC gc;
     int i, j;
 
-    /* We can only have a single control for subwindow_mode on the
-     * GC. If we have a Window destination, we need to set ClipByChildren,
-     * but if we have a Window source, we need IncludeInferiors. If we have
-     * both a Window destination and source, we must fallback. There is
-     * no convenient way to detect if a drawable is a Pixmap or Window,
-     * therefore we can only rely on those surfaces that we created
-     * ourselves to be Pixmaps, and treat everything else as a potential
-     * Window.
-     */
-    if (! src->owns_pixmap && ! dst->owns_pixmap)
-	return CAIRO_INT_STATUS_UNSUPPORTED;
-
     if (! _cairo_xlib_surface_same_screen  (dst, src))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
@@ -210,43 +198,67 @@ copy_boxes (void *_dst,
 		   x2 - x1, y2 - y1,
 		   x1,      y1);
     } else {
-	XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)];
-	XRectangle *rects = stack_rects;
-
-	if (boxes->num_boxes > ARRAY_LENGTH (stack_rects)) {
-	    rects = _cairo_malloc_ab (boxes->num_boxes, sizeof (XRectangle));
-	    if (unlikely (rects == NULL))
-		return _cairo_error (CAIRO_STATUS_NO_MEMORY);
-	}
+	/* We can only have a single control for subwindow_mode on the
+	 * GC. If we have a Window destination, we need to set ClipByChildren,
+	 * but if we have a Window source, we need IncludeInferiors. If we have
+	 * both a Window destination and source, we must fallback. There is
+	 * no convenient way to detect if a drawable is a Pixmap or Window,
+	 * therefore we can only rely on those surfaces that we created
+	 * ourselves to be Pixmaps, and treat everything else as a potential
+	 * Window.
+	 */
+	if (src == dst || (!src->owns_pixmap && !dst->owns_pixmap)) {
+	    for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
+		for (i = 0; i < chunk->count; i++) {
+		    int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
+		    int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
+		    int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
+		    int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
+		    XCopyArea (dst->dpy, src->drawable, dst->drawable, gc,
+			       x1 + dx, y1 + dy,
+			       x2 - x1, y2 - y1,
+			       x1,      y1);
+		}
+	    }
+	} else {
+	    XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)];
+	    XRectangle *rects = stack_rects;
 
-	j = 0;
-	for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
-	    for (i = 0; i < chunk->count; i++) {
-		int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
-		int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
-		int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
-		int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
+	    if (boxes->num_boxes > ARRAY_LENGTH (stack_rects)) {
+		rects = _cairo_malloc_ab (boxes->num_boxes, sizeof (XRectangle));
+		if (unlikely (rects == NULL))
+		    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+	    }
 
-		rects[j].x = x1;
-		rects[j].y = y1;
-		rects[j].width  = x2 - x1;
-		rects[j].height = y2 - y1;
-		j++;
+	    j = 0;
+	    for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
+		for (i = 0; i < chunk->count; i++) {
+		    int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
+		    int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
+		    int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
+		    int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
+
+		    rects[j].x = x1;
+		    rects[j].y = y1;
+		    rects[j].width  = x2 - x1;
+		    rects[j].height = y2 - y1;
+		    j++;
+		}
 	    }
-	}
-	assert (j == boxes->num_boxes);
+	    assert (j == boxes->num_boxes);
 
-	XSetClipRectangles (dst->dpy, gc, 0, 0, rects, j, Unsorted);
+	    XSetClipRectangles (dst->dpy, gc, 0, 0, rects, j, Unsorted);
 
-	XCopyArea (dst->dpy, src->drawable, dst->drawable, gc,
-		   extents->x + dx, extents->y + dy,
-		   extents->width,  extents->height,
-		   extents->x,      extents->y);
+	    XCopyArea (dst->dpy, src->drawable, dst->drawable, gc,
+		       extents->x + dx, extents->y + dy,
+		       extents->width,  extents->height,
+		       extents->x,      extents->y);
 
-	XSetClipMask (dst->dpy, gc, None);
+	    XSetClipMask (dst->dpy, gc, None);
 
-	if (rects != stack_rects)
-	    free (rects);
+	    if (rects != stack_rects)
+		free (rects);
+	}
     }
 
     if (! src->owns_pixmap) {
commit cc09b29752e857e55879a7d773b8be1317eb2001
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Feb 23 13:40:59 2012 +0000

    xlib: Tidy conversion of xrender format to cairo_content_t
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index d8b0272..563e964 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -237,26 +237,22 @@ _visual_for_xrender_format(Screen *screen,
 static cairo_content_t
 _xrender_format_to_content (XRenderPictFormat *xrender_format)
 {
-    cairo_bool_t xrender_format_has_alpha;
-    cairo_bool_t xrender_format_has_color;
+    cairo_content_t content;
 
     /* This only happens when using a non-Render server. Let's punt
      * and say there's no alpha here. */
     if (xrender_format == NULL)
 	return CAIRO_CONTENT_COLOR;
 
-    xrender_format_has_alpha = (xrender_format->direct.alphaMask != 0);
-    xrender_format_has_color = (xrender_format->direct.redMask   != 0 ||
-				xrender_format->direct.greenMask != 0 ||
-				xrender_format->direct.blueMask  != 0);
+    content = 0;
+    if (xrender_format->direct.alphaMask)
+	    content |= CAIRO_CONTENT_ALPHA;
+    if (xrender_format->direct.redMask |
+	xrender_format->direct.greenMask |
+	xrender_format->direct.blueMask)
+	    content |= CAIRO_CONTENT_COLOR;
 
-    if (xrender_format_has_alpha)
-	if (xrender_format_has_color)
-	    return CAIRO_CONTENT_COLOR_ALPHA;
-	else
-	    return CAIRO_CONTENT_ALPHA;
-    else
-	return CAIRO_CONTENT_COLOR;
+    return content;
 }
 
 static cairo_surface_t *


More information about the cairo-commit mailing list