[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