[cairo-commit] 3 commits - configure.in src/cairo-xcb-surface.c

Jamey Sharp jamey at kemper.freedesktop.org
Mon Jul 31 10:07:27 PDT 2006


 configure.in            |    2 
 src/cairo-xcb-surface.c |  295 +++++++++++++++++++++---------------------------
 2 files changed, 135 insertions(+), 162 deletions(-)

New commits:
diff-tree 72b51b6f0c49f9eac7d8ef4caff59733312b1ca6 (from 2eeb338590957a90bdebfc6a00fc05323e76f9ee)
Author: Ian Osgood <iano at quirkster.com>
Date:   Wed Jun 21 07:06:20 2006 -0700

    XCB: implement set_clip_region

diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index abd3e1b..f60bc3b 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -95,6 +95,9 @@ typedef struct cairo_xcb_surface {
     int height;
     int depth;
 
+    XCBRECTANGLE *clip_rects;
+    int num_clip_rects;
+
     XCBRenderPICTURE picture;
     XCBRenderPICTFORMINFO format;
     int has_format;
@@ -195,6 +198,8 @@ _cairo_xcb_surface_finish (void *abstrac
     if (surface->gc.xid)
 	XCBFreeGC (surface->dpy, surface->gc);
 
+    free (surface->clip_rects);
+
     surface->dpy = NULL;
 
     return CAIRO_STATUS_SUCCESS;
@@ -454,6 +459,26 @@ _get_image_surface (cairo_xcb_surface_t 
 }
 
 static void
+_cairo_xcb_surface_set_picture_clip_rects (cairo_xcb_surface_t *surface)
+{
+    if (surface->num_clip_rects)
+	XCBRenderSetPictureClipRectangles (surface->dpy, surface->picture,
+					   0, 0,
+					   surface->num_clip_rects,
+					   surface->clip_rects);
+}
+
+static void
+_cairo_xcb_surface_set_gc_clip_rects (cairo_xcb_surface_t *surface)
+{
+    if (surface->num_clip_rects)
+	XCBSetClipRectangles(surface->dpy, XCBClipOrderingYXSorted, surface->gc,
+			     0, 0,
+			     surface->num_clip_rects,
+			     surface->clip_rects );
+}
+
+static void
 _cairo_xcb_surface_ensure_gc (cairo_xcb_surface_t *surface)
 {
     if (surface->gc.xid)
@@ -461,6 +486,7 @@ _cairo_xcb_surface_ensure_gc (cairo_xcb_
 
     surface->gc = XCBGCONTEXTNew(surface->dpy);
     XCBCreateGC (surface->dpy, surface->gc, surface->drawable, 0, 0);
+    _cairo_xcb_surface_set_gc_clip_rects(surface);
 }
 
 static cairo_status_t
@@ -940,6 +966,69 @@ _cairo_xcb_surface_composite_trapezoids 
 }
 
 static cairo_int_status_t
+_cairo_xcb_surface_set_clip_region (void              *abstract_surface,
+				    pixman_region16_t *region)
+{
+    cairo_xcb_surface_t *surface = abstract_surface;
+
+    if (surface->clip_rects) {
+	free (surface->clip_rects);
+	surface->clip_rects = NULL;
+    }
+
+    surface->num_clip_rects = 0;
+
+    if (region == NULL) {
+	if (surface->gc.xid) {
+	    CARD32 mask = XCBGCClipMask;
+	    CARD32 pa[] = { XCBNone };
+
+	    XCBChangeGC (surface->dpy, surface->gc, mask, pa);
+	}
+
+	if (surface->has_format && surface->picture.xid) {
+	    CARD32 mask = XCBRenderCPClipMask;
+	    CARD32 pa[] = { XCBNone };
+
+	    XCBRenderChangePicture (surface->dpy, surface->picture, mask, pa);
+	}
+    } else {
+	pixman_box16_t *boxes;
+	XCBRECTANGLE *rects = NULL;
+	int n_boxes, i;
+
+	n_boxes = pixman_region_num_rects (region);
+	if (n_boxes > 0) {
+	    rects = malloc (sizeof(XCBRECTANGLE) * n_boxes);
+	    if (rects == NULL)
+		return CAIRO_STATUS_NO_MEMORY;
+	} else {
+	    rects = NULL;
+	}
+
+	boxes = pixman_region_rects (region);
+
+	for (i = 0; i < n_boxes; i++) {
+	    rects[i].x = boxes[i].x1;
+	    rects[i].y = boxes[i].y1;
+	    rects[i].width = boxes[i].x2 - boxes[i].x1;
+	    rects[i].height = boxes[i].y2 - boxes[i].y1;
+	}
+
+	surface->clip_rects = rects;
+	surface->num_clip_rects = n_boxes;
+
+	if (surface->gc.xid)
+	    _cairo_xcb_surface_set_gc_clip_rects (surface);
+
+	if (surface->picture.xid)
+	    _cairo_xcb_surface_set_picture_clip_rects (surface);
+    }
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+static cairo_int_status_t
 _cairo_xcb_surface_get_extents (void		        *abstract_surface,
 				cairo_rectangle_int16_t *rectangle)
 {
@@ -968,7 +1057,7 @@ static const cairo_surface_backend_t cai
     _cairo_xcb_surface_composite_trapezoids,
     NULL, /* copy_page */
     NULL, /* show_page */
-    NULL, /* _cairo_xcb_surface_set_clip_region */
+    _cairo_xcb_surface_set_clip_region,
     NULL, /* intersect_clip_path */
     _cairo_xcb_surface_get_extents,
     NULL, /* old_show_glyphs */
@@ -1034,6 +1123,9 @@ _cairo_xcb_surface_create_internal (XCBC
     surface->height = height;
     surface->depth = depth;
 
+    surface->clip_rects = NULL;
+    surface->num_clip_rects = 0;
+
     if (format) {
 	surface->depth = format->depth;
     } else if (visual) {
diff-tree 2eeb338590957a90bdebfc6a00fc05323e76f9ee (from 6b0d3433b7073ece1f7959475e6058911dc382ad)
Author: Jamey Sharp <jamey at minilop.net>
Date:   Mon Jun 12 17:47:55 2006 -0700

    XCB: Use xcb-renderutil where cairo-xlib used libXrender.

diff --git a/configure.in b/configure.in
index 9e48511..218289f 100644
--- a/configure.in
+++ b/configure.in
@@ -241,7 +241,7 @@ CAIRO_BACKEND_ENABLE(quartz, Quartz, qua
 dnl ===========================================================================
 
 CAIRO_BACKEND_ENABLE(xcb, XCB, xcb, XCB_SURFACE, no, [
-  xcb_REQUIRES="xcb xcb-render"
+  xcb_REQUIRES="xcb xcb-render xcb-renderutil"
   PKG_CHECK_MODULES(xcb, $xcb_REQUIRES, , [
   use_xcb="no (requires XCB http://xcb.freedesktop.org)"])
 ])
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 7e379cf..abd3e1b 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -37,35 +37,10 @@
 #include "cairoint.h"
 #include "cairo-xcb.h"
 #include "cairo-xcb-xrender.h"
+#include <X11/XCB/xcb_renderutil.h>
 
 #define AllPlanes               ((unsigned long)~0L)
 
-static XCBRenderPICTFORMAT
-format_from_visual(XCBConnection *c, XCBVISUALID visual)
-{
-    static const XCBRenderPICTFORMAT nil = { 0 };
-    XCBRenderQueryPictFormatsRep *r;
-    XCBRenderPICTSCREENIter si;
-    XCBRenderPICTDEPTHIter di;
-    XCBRenderPICTVISUALIter vi;
-
-    r = XCBRenderQueryPictFormatsReply(c, XCBRenderQueryPictFormats(c), 0);
-    if(!r)
-	return nil;
-
-    for(si = XCBRenderQueryPictFormatsScreensIter(r); si.rem; XCBRenderPICTSCREENNext(&si))
-	for(di = XCBRenderPICTSCREENDepthsIter(si.data); di.rem; XCBRenderPICTDEPTHNext(&di))
-	    for(vi = XCBRenderPICTDEPTHVisualsIter(di.data); vi.rem; XCBRenderPICTVISUALNext(&vi))
-		if(vi.data->visual.id == visual.id)
-		{
-		    XCBRenderPICTFORMAT ret = vi.data->format;
-		    free(r);
-		    return ret;
-		}
-
-    return nil;
-}
-
 static cairo_content_t
 _xcb_render_format_to_content (XCBRenderPICTFORMINFO *xrender_format)
 {
@@ -92,95 +67,6 @@ _xcb_render_format_to_content (XCBRender
 
 }
 
-/* XXX: Why is this ridiculously complex compared to the equivalent
- * function in cairo-xlib-surface.c */
-static XCBRenderPICTFORMINFO
-_format_from_cairo(XCBConnection *c, cairo_format_t fmt)
-{
-    XCBRenderPICTFORMINFO ret = {{ 0 }};
-    struct tmpl_t {
-	XCBRenderDIRECTFORMAT direct;
-	CARD8 depth;
-    };
-    static const struct tmpl_t templates[] = {
-	/* CAIRO_FORMAT_ARGB32 */
-	{
-	    {
-		16, 0xff,
-		8,  0xff,
-		0,  0xff,
-		24, 0xff
-	    },
-	    32
-	},
-	/* CAIRO_FORMAT_RGB24 */
-	{
-	    {
-		16, 0xff,
-		8,  0xff,
-		0,  0xff,
-		0,  0x00
-	    },
-	    24
-	},
-	/* CAIRO_FORMAT_A8 */
-	{
-	    {
-		0,  0x00,
-		0,  0x00,
-		0,  0x00,
-		0,  0xff
-	    },
-	    8
-	},
-	/* CAIRO_FORMAT_A1 */
-	{
-	    {
-		0,  0x00,
-		0,  0x00,
-		0,  0x00,
-		0,  0x01
-	    },
-	    1
-	},
-    };
-    const struct tmpl_t *tmpl;
-    XCBRenderQueryPictFormatsRep *r;
-    XCBRenderPICTFORMINFOIter fi;
-
-    if(fmt < 0 || fmt >= (sizeof(templates) / sizeof(*templates)))
-	return ret;
-    tmpl = templates + fmt;
-
-    r = XCBRenderQueryPictFormatsReply(c, XCBRenderQueryPictFormats(c), 0);
-    if(!r)
-	return ret;
-
-    for(fi = XCBRenderQueryPictFormatsFormatsIter(r); fi.rem; XCBRenderPICTFORMINFONext(&fi))
-    {
-	const XCBRenderDIRECTFORMAT *t, *f;
-	if(fi.data->type != XCBRenderPictTypeDirect)
-	    continue;
-	if(fi.data->depth != tmpl->depth)
-	    continue;
-	t = &tmpl->direct;
-	f = &fi.data->direct;
-	if(t->red_mask && (t->red_mask != f->red_mask || t->red_shift != f->red_shift))
-	    continue;
-	if(t->green_mask && (t->green_mask != f->green_mask || t->green_shift != f->green_shift))
-	    continue;
-	if(t->blue_mask && (t->blue_mask != f->blue_mask || t->blue_shift != f->blue_shift))
-	    continue;
-	if(t->alpha_mask && (t->alpha_mask != f->alpha_mask || t->alpha_shift != f->alpha_shift))
-	    continue;
-
-	ret = *fi.data;
-    }
-
-    free(r);
-    return ret;
-}
-
 /*
  * Instead of taking two round trips for each blending request,
  * assume that if a particular drawable fails GetImage that it will
@@ -265,7 +151,7 @@ _cairo_xcb_surface_create_similar (void	
     XCBDRAWABLE d;
     cairo_xcb_surface_t *surface;
     cairo_format_t format = _cairo_format_from_content (content);
-    XCBRenderPICTFORMINFO xrender_format = _format_from_cairo (dpy, format);
+    XCBRenderPICTFORMINFO *xrender_format;
 
     /* As a good first approximation, if the display doesn't have COMPOSITE,
      * we're better off using image surfaces for all temporary operations
@@ -280,9 +166,11 @@ _cairo_xcb_surface_create_similar (void	
 		     width <= 0 ? 1 : width,
 		     height <= 0 ? 1 : height);
 
+    xrender_format = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dpy), format);
+    /* XXX: what to do if xrender_format is null? */
     surface = (cairo_xcb_surface_t *)
 	cairo_xcb_surface_create_with_xrender_format (dpy, d, src->screen,
-						      &xrender_format,
+						      xrender_format,
 						      width, height);
     if (surface->base.status) {
 	_cairo_error (CAIRO_STATUS_NO_MEMORY);
@@ -1000,7 +888,8 @@ _cairo_xcb_surface_composite_trapezoids 
     cairo_int_status_t		status;
     int				render_reference_x, render_reference_y;
     int				render_src_x, render_src_y;
-    XCBRenderPICTFORMINFO	render_format;
+    int				cairo_format;
+    XCBRenderPICTFORMINFO	*render_format;
 
     if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1025,21 +914,22 @@ _cairo_xcb_surface_composite_trapezoids 
 
     switch (antialias) {
     case CAIRO_ANTIALIAS_NONE:
-	render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A1);
+	cairo_format = CAIRO_FORMAT_A1;
 	break;
     default:
-	render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8);
+	cairo_format = CAIRO_FORMAT_A8;
 	break;
     }
+    render_format = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dst->dpy), cairo_format);
+    /* XXX: what to do if render_format is null? */
 
     /* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
-    /* XXX: _format_from_cairo is slow. should cache something. */
     status = _cairo_xcb_surface_set_attributes (src, &attributes);
     if (status == CAIRO_STATUS_SUCCESS)
 	XCBRenderTrapezoids (dst->dpy,
 			     _render_operator (op),
 			     src->picture, dst->picture,
-			     render_format.id,
+			     render_format->id,
 			     render_src_x + attributes.x_offset,
 			     render_src_y + attributes.y_offset,
 			     num_traps, (XCBRenderTRAPEZOID *) traps);
@@ -1103,26 +993,6 @@ _cairo_surface_is_xcb (cairo_surface_t *
     return surface->backend == &cairo_xcb_surface_backend;
 }
 
-static void
-query_render_version (XCBConnection *c, cairo_xcb_surface_t *surface)
-{
-    XCBRenderQueryVersionRep *r;
-
-    surface->render_major = -1;
-    surface->render_minor = -1;
-
-    if (!XCBRenderInit(c))
-	return;
-
-    r = XCBRenderQueryVersionReply(c, XCBRenderQueryVersion(c, 0, 6), 0);
-    if (!r)
-	return;
-
-    surface->render_major = r->major_version;
-    surface->render_minor = r->minor_version;
-    free(r);
-}
-
 static cairo_surface_t *
 _cairo_xcb_surface_create_internal (XCBConnection	     *dpy,
 				    XCBDRAWABLE		      drawable,
@@ -1134,6 +1004,7 @@ _cairo_xcb_surface_create_internal (XCBC
 				    int			      depth)
 {
     cairo_xcb_surface_t *surface;
+    const XCBRenderQueryVersionRep *r;
 
     surface = malloc (sizeof (cairo_xcb_surface_t));
     if (surface == NULL) {
@@ -1189,30 +1060,40 @@ _cairo_xcb_surface_create_internal (XCBC
 	;
     }
 
-    query_render_version(dpy, surface);
+    surface->render_major = -1;
+    surface->render_minor = -1;
+
+    r = XCBRenderUtilQueryVersion(dpy);
+    if (r) {
+	surface->render_major = r->major_version;
+	surface->render_minor = r->minor_version;
+    }
 
     surface->picture.xid = 0;
 
     if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface))
     {
-	XCBRenderPICTFORMAT pict_format = {0};
-	XCBRenderPICTFORMINFO format_info;
+	static const XCBRenderPICTFORMAT nil = { 0 };
+	const XCBRenderPICTFORMAT *pict_format = &nil;
 
-	surface->picture = XCBRenderPICTURENew(dpy);
-
-	if (!format) {
-	    if (visual) {
-		pict_format = format_from_visual (dpy, visual->visual_id);
-	    } else if (depth == 1) {
-		format_info = _format_from_cairo (dpy, CAIRO_FORMAT_A1);
-		pict_format = format_info.id;
-	    }
-	    XCBRenderCreatePicture (dpy, surface->picture, drawable,
-				    pict_format, 0, NULL);
-	} else {
-	    XCBRenderCreatePicture (dpy, surface->picture, drawable,
-				    format->id, 0, NULL);
+	if (format) {
+	    pict_format = &format->id;
+	} else if (visual) {
+	    XCBRenderPICTVISUAL *pict_visual;
+	    pict_visual = XCBRenderUtilFindVisualFormat (XCBRenderUtilQueryFormats (dpy), visual->visual_id);
+	    if (pict_visual)
+		pict_format = &pict_visual->format;
+	} else if (depth == 1) {
+	    XCBRenderPICTFORMINFO *format_info;
+	    format_info = XCBRenderUtilFindStandardFormat (XCBRenderUtilQueryFormats (dpy), CAIRO_FORMAT_A1);
+	    if (format_info)
+		pict_format = &format_info->id;
 	}
+
+	/* XXX: if pict_format is nil, should we still call CreatePicture? */
+	surface->picture = XCBRenderPICTURENew(dpy);
+	XCBRenderCreatePicture (dpy, surface->picture, drawable,
+				*pict_format, 0, NULL);
     }
 
     return (cairo_surface_t *) surface;
diff-tree 6b0d3433b7073ece1f7959475e6058911dc382ad (from 88675958efbe57c7cc5135d6fb73e99f42d848d8)
Author: Jamey Sharp <jamey at minilop.net>
Date:   Mon Jul 31 08:53:57 2006 -0700

    XCB: XCBRenderTRAP was renamed to XCBRenderTRAPEZOID.

diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 15e45e8..7e379cf 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -1042,7 +1042,7 @@ _cairo_xcb_surface_composite_trapezoids 
 			     render_format.id,
 			     render_src_x + attributes.x_offset,
 			     render_src_y + attributes.y_offset,
-			     num_traps, (XCBRenderTRAP *) traps);
+			     num_traps, (XCBRenderTRAPEZOID *) traps);
 
     _cairo_pattern_release_surface (pattern, &src->base, &attributes);
 


More information about the cairo-commit mailing list