diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2011-05-27 15:59:37 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-06-01 16:50:25 +0100 |
commit | 63bdae27a83381fb8c3786c2d7a6c2592e388ee9 (patch) | |
tree | 1897d8eac8bf89bfdc1fb6c99a1ee59b044e5143 | |
parent | e21b373c94b1edb2828d4fee7ff45060fb22dbda (diff) |
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@chris-wilson.co.uk>
-rw-r--r-- | boilerplate/cairo-boilerplate-xcb.c | 14 | ||||
-rw-r--r-- | boilerplate/cairo-boilerplate-xlib.c | 23 | ||||
-rw-r--r-- | src/cairo-xcb-connection.c | 20 | ||||
-rw-r--r-- | src/cairo-xcb-private.h | 3 | ||||
-rw-r--r-- | src/cairo-xcb-surface-render.c | 32 | ||||
-rw-r--r-- | src/cairo-xcb.h | 11 | ||||
-rw-r--r-- | src/cairo-xlib-display.c | 21 | ||||
-rw-r--r-- | src/cairo-xlib-private.h | 6 | ||||
-rw-r--r-- | src/cairo-xlib-surface.c | 7 | ||||
-rw-r--r-- | src/cairo-xlib.h | 13 |
10 files changed, 147 insertions, 3 deletions
diff --git a/boilerplate/cairo-boilerplate-xcb.c b/boilerplate/cairo-boilerplate-xcb.c index c5dee8ee..d4c70be6 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 fbc99907..f82b78b8 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 0c244b1d..56bf5aef 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 be6ca441..ae6027ed 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 8e9acf5f..4d5a88f9 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 3f64dcbd..9a3798d1 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 bef9c839..0dab5586 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 bd260bc0..a44a9323 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 90db7d33..d9c9854c 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 4ee592ce..7f770b97 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 */ |