[cairo-commit] boilerplate/cairo-boilerplate-xcb.c boilerplate/cairo-boilerplate-xlib.c src/cairo-xcb-connection.c src/cairo-xcb.h src/cairo-xcb-private.h src/cairo-xcb-surface-render.c src/cairo-xlib-display.c src/cairo-xlib.h src/cairo-xlib-private.h src/cairo-xlib-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Wed Jun 1 08:50:53 PDT 2011


 boilerplate/cairo-boilerplate-xcb.c  |   14 ++++++++++++++
 boilerplate/cairo-boilerplate-xlib.c |   23 ++++++++++++++++++++++-
 src/cairo-xcb-connection.c           |   20 ++++++++++++++++++++
 src/cairo-xcb-private.h              |    3 +++
 src/cairo-xcb-surface-render.c       |   32 ++++++++++++++++++++++++++++++++
 src/cairo-xcb.h                      |   11 +++++++++++
 src/cairo-xlib-display.c             |   21 +++++++++++++++++++++
 src/cairo-xlib-private.h             |    6 ++++++
 src/cairo-xlib-surface.c             |    7 +++++--
 src/cairo-xlib.h                     |   13 +++++++++++++
 10 files changed, 147 insertions(+), 3 deletions(-)

New commits:
commit 63bdae27a83381fb8c3786c2d7a6c2592e388ee9
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri May 27 15:59:37 2011 +0100

    xlib,xcb: Force strict adherence to the Render specification when testing
    
    Introduce cairo_xlib_device_debug_set_precision() to override the
    automatic selection of rendering precision and force the Xorg/DDX to
    strictly adhere to the precise rendering mode of the Render
    specification. This allows us to test drivers without worrying, too
    much, about minor discrepancies in antialiasing.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c
index c5dee8e..d4c70be 100644
--- a/boilerplate/cairo-boilerplate-xcb.c
+++ b/boilerplate/cairo-boilerplate-xcb.c
@@ -86,6 +86,17 @@ _cairo_boilerplate_xcb_sync_server (xcb_target_closure_t *xtc)
 }
 
 static void
+_cairo_boilerplate_xcb_setup_test_surface (cairo_surface_t *surface)
+{
+
+    /* For testing purposes, tell the X server to strictly adhere to the
+     * Render specification.
+     */
+    cairo_xcb_device_debug_set_precision(cairo_surface_get_device(surface),
+					 PolyModePrecise);
+}
+
+static void
 _cairo_boilerplate_xcb_cleanup (void *closure)
 {
     xcb_target_closure_t *xtc = closure;
@@ -241,6 +252,9 @@ _cairo_boilerplate_xcb_create_surface (const char		 *name,
 							    width, height);
     free (formats);
 
+    if (mode != CAIRO_BOILERPLATE_MODE_PERF)
+	cairo_xcb_surface_setup_test_surface(surface);
+
     xtc->device = cairo_device_reference (cairo_surface_get_device (surface));
     status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL);
     if (status == CAIRO_STATUS_SUCCESS)
diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c
index fbc9990..f82b78b 100644
--- a/boilerplate/cairo-boilerplate-xlib.c
+++ b/boilerplate/cairo-boilerplate-xlib.c
@@ -78,6 +78,18 @@ _cairo_boilerplate_xlib_check_screen_size (Display *dpy,
     return width <= WidthOfScreen (scr) && height <= HeightOfScreen (scr);
 }
 
+static void
+_cairo_boilerplate_xlib_setup_test_surface (cairo_surface_t *surface)
+{
+
+    /* For testing purposes, tell the X server to strictly adhere to the
+     * Render specification.
+     */
+    cairo_xlib_device_debug_set_precision(cairo_surface_get_device(surface),
+					  PolyModePrecise);
+}
+
+
 #if CAIRO_HAS_XLIB_XRENDER_SURFACE
 /* For the xlib backend we distinguish between TEST and PERF mode in a
  * couple of ways.
@@ -98,6 +110,7 @@ _cairo_boilerplate_xlib_test_create_surface (Display		   *dpy,
 					     xlib_target_closure_t *xtc)
 {
     XRenderPictFormat *xrender_format;
+    cairo_surface_t *surface;
 
     /* This kills performance, but it makes debugging much
      * easier. That's why we have it here when in TEST mode, but not
@@ -133,10 +146,14 @@ _cairo_boilerplate_xlib_test_create_surface (Display		   *dpy,
 				   width, height, xrender_format->depth);
     xtc->drawable_is_pixmap = TRUE;
 
-    return cairo_xlib_surface_create_with_xrender_format (dpy, xtc->drawable,
+    surface = cairo_xlib_surface_create_with_xrender_format (dpy, xtc->drawable,
 							  DefaultScreenOfDisplay (dpy),
 							  xrender_format,
 							  width, height);
+
+    _cairo_boilerplate_xlib_setup_test_surface(surface);
+
+    return surface;
 }
 
 static cairo_surface_t *
@@ -333,6 +350,8 @@ _cairo_boilerplate_xlib_window_create_surface (const char		 *name,
     if (cairo_surface_status (surface))
 	_cairo_boilerplate_xlib_cleanup (xtc);
 
+    _cairo_boilerplate_xlib_setup_test_surface(surface);
+
     return surface;
 }
 
@@ -477,6 +496,8 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char		   *name,
     else
 	cairo_boilerplate_xlib_surface_disable_render (surface);
 
+    _cairo_boilerplate_xlib_setup_test_surface(surface);
+
     return surface;
 }
 #endif
diff --git a/src/cairo-xcb-connection.c b/src/cairo-xcb-connection.c
index 0c244b1..56bf5ae 100644
--- a/src/cairo-xcb-connection.c
+++ b/src/cairo-xcb-connection.c
@@ -889,3 +889,23 @@ cairo_xcb_device_debug_cap_xrender_version (cairo_device_t *device,
 	    connection->flags &= ~CAIRO_XCB_RENDER_HAS_GRADIENTS;
     }
 }
+
+
+void
+cairo_xcb_device_debug_set_precision (cairo_device_t *device,
+				      int precision)
+{
+    if (device->status)
+	    return;
+
+    ((cairo_xcb_connection_t *) device)->force_precision = precision;
+}
+
+int
+cairo_xcb_device_debug_get_precision (cairo_device_t *device)
+{
+    if (device->status)
+	    return -1;
+
+    return ((cairo_xcb_connection_t *) device)->force_precision;
+}
diff --git a/src/cairo-xcb-private.h b/src/cairo-xcb-private.h
index be6ca44..ae6027e 100644
--- a/src/cairo-xcb-private.h
+++ b/src/cairo-xcb-private.h
@@ -96,6 +96,7 @@ struct _cairo_xcb_surface {
     xcb_render_picture_t picture;
     xcb_render_pictformat_t xrender_format;
     pixman_format_code_t pixman_format;
+    uint32_t precision;
 
     cairo_list_t link;
 };
@@ -178,6 +179,8 @@ struct _cairo_xcb_connection {
     unsigned int maximum_request_length;
     unsigned int flags;
 
+    int force_precision;
+
     const xcb_setup_t *root;
     const xcb_query_extension_reply_t *render;
     const xcb_query_extension_reply_t *shm;
diff --git a/src/cairo-xcb-surface-render.c b/src/cairo-xcb-surface-render.c
index 8e9acf5..4d5a88f 100644
--- a/src/cairo-xcb-surface-render.c
+++ b/src/cairo-xcb-surface-render.c
@@ -254,6 +254,37 @@ _cairo_xcb_surface_clear_clip_region (cairo_xcb_surface_t *surface)
 }
 
 static void
+_cairo_xcb_surface_set_precision (cairo_xcb_surface_t	*surface,
+				  cairo_antialias_t	 antialias)
+{
+    cairo_xcb_connection_t *connection = surface->connection;
+    uint32_t precision;
+
+    if (connection->force_precision != -1)
+	    precision = connection->force_precision;
+    else switch (antialias) {
+    default:
+    case CAIRO_ANTIALIAS_DEFAULT:
+    case CAIRO_ANTIALIAS_GRAY:
+    case CAIRO_ANTIALIAS_NONE:
+	precision = 1;
+	break;
+    case CAIRO_ANTIALIAS_SUBPIXEL:
+	precision = 0;
+	break;
+    }
+
+    if (surface->precision != precision) {
+	_cairo_xcb_connection_render_change_picture (connection,
+						     surface->picture,
+						     XCB_RENDER_CP_POLY_MODE,
+						     &precision);
+	surface->precision = precision;
+    }
+}
+
+
+static void
 _cairo_xcb_surface_ensure_picture (cairo_xcb_surface_t *surface)
 {
     assert (surface->fallback == NULL);
@@ -1595,6 +1626,7 @@ _composite_traps (void *closure,
 	render_reference_y = xtraps[0].left.p2.y >> 16;
     }
 
+    _cairo_xcb_surface_set_precision (dst, info->antialias);
     _cairo_xcb_connection_render_trapezoids (dst->connection,
 					     _render_operator (op),
 					     src->picture,
diff --git a/src/cairo-xcb.h b/src/cairo-xcb.h
index 3f64dcb..9a3798d 100644
--- a/src/cairo-xcb.h
+++ b/src/cairo-xcb.h
@@ -87,6 +87,17 @@ cairo_xcb_device_debug_cap_xrender_version (cairo_device_t *device,
                                             int major_version,
                                             int minor_version);
 
+/*
+ * @precision: -1 implies automatically choose based on antialiasing mode,
+ *            any other value overrides and sets the corresponding PolyMode.
+ */
+cairo_public void
+cairo_xcb_device_debug_set_precision (cairo_device_t *device,
+				      int precision);
+
+cairo_public int
+cairo_xcb_device_debug_get_precision (cairo_device_t *device);
+
 CAIRO_END_DECLS
 
 #else  /* CAIRO_HAS_XCB_SURFACE */
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index bef9c83..0dab558 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -350,6 +350,8 @@ _cairo_xlib_device_create (Display *dpy)
     memset (display->cached_xrender_formats, 0,
 	    sizeof (display->cached_xrender_formats));
 
+    display->force_precision = -1;
+
     /* Prior to Render 0.10, there is no protocol support for gradients and
      * we call function stubs instead, which would silently consume the drawing.
      */
@@ -642,3 +644,22 @@ _cairo_xlib_display_has_gradients (cairo_device_t *device)
 {
     return ! ((cairo_xlib_display_t *) device)->buggy_gradients;
 }
+
+void
+cairo_xlib_device_debug_set_precision (cairo_device_t *device,
+				       int precision)
+{
+    if (device->status)
+	    return;
+
+    ((cairo_xlib_display_t *) device)->force_precision = precision;
+}
+
+int
+cairo_xlib_device_debug_get_precision (cairo_device_t *device)
+{
+    if (device->status)
+	    return -1;
+
+    return ((cairo_xlib_display_t *) device)->force_precision;
+}
diff --git a/src/cairo-xlib-private.h b/src/cairo-xlib-private.h
index bd260bc..a44a932 100644
--- a/src/cairo-xlib-private.h
+++ b/src/cairo-xlib-private.h
@@ -80,6 +80,8 @@ struct _cairo_xlib_display {
     cairo_xlib_job_t *workqueue;
     cairo_freelist_t wq_freelist;
 
+    int force_precision;
+
     cairo_xlib_hook_t *close_display_hooks;
     unsigned int buggy_gradients :1;
     unsigned int buggy_pad_reflect :1;
@@ -151,6 +153,10 @@ _cairo_xlib_display_has_reflect (cairo_device_t *device);
 cairo_private cairo_bool_t
 _cairo_xlib_display_has_gradients (cairo_device_t *device);
 
+cairo_private void
+_cairo_xlib_display_set_precision(cairo_device_t *device,
+				  int precision);
+
 cairo_private XRenderPictFormat *
 _cairo_xlib_display_get_xrender_format (cairo_xlib_display_t	*display,
 	                                cairo_format_t		 format);
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 90db7d3..d9c9854 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1098,12 +1098,15 @@ _cairo_xlib_surface_set_precision (cairo_xlib_display_t	*display,
 {
     int precision;
 
-    switch (antialias) {
+    if (display->force_precision != -1)
+	    precision = display->force_precision;
+    else switch (antialias) {
+    default:
     case CAIRO_ANTIALIAS_DEFAULT:
     case CAIRO_ANTIALIAS_GRAY:
+    case CAIRO_ANTIALIAS_NONE:
 	precision = PolyModeImprecise;
 	break;
-    case CAIRO_ANTIALIAS_NONE:
     case CAIRO_ANTIALIAS_SUBPIXEL:
 	precision = PolyModePrecise;
 	break;
diff --git a/src/cairo-xlib.h b/src/cairo-xlib.h
index 4ee592c..7f770b9 100644
--- a/src/cairo-xlib.h
+++ b/src/cairo-xlib.h
@@ -91,6 +91,19 @@ cairo_xlib_surface_get_width (cairo_surface_t *surface);
 cairo_public int
 cairo_xlib_surface_get_height (cairo_surface_t *surface);
 
+/* debug interface */
+
+/*
+ * @precision: -1 implies automatically choose based on antialiasing mode,
+ *            any other value overrides and sets the corresponding PolyMode.
+ */
+cairo_public void
+cairo_xlib_device_debug_set_precision (cairo_device_t *device,
+				       int precision);
+
+cairo_public int
+cairo_xlib_device_debug_get_precision (cairo_device_t *device);
+
 CAIRO_END_DECLS
 
 #else  /* CAIRO_HAS_XLIB_SURFACE */


More information about the cairo-commit mailing list