mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-16 05:10:44 +02:00
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>
This commit is contained in:
parent
e21b373c94
commit
63bdae27a8
10 changed files with 147 additions and 3 deletions
|
|
@ -85,6 +85,17 @@ _cairo_boilerplate_xcb_sync_server (xcb_target_closure_t *xtc)
|
|||
xcb_get_input_focus (xtc->c), NULL));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -253,6 +253,37 @@ _cairo_xcb_surface_clear_clip_region (cairo_xcb_surface_t *surface)
|
|||
values);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue