From 3d499ea901b3a76cd765ddce9f4e7d3acebd1bd3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 22 Feb 2012 10:41:37 +0000 Subject: [PATCH] xlib: Replace obsolete disable-xrender with shiny new device debug interface As prototyped with xcb. Signed-off-by: Chris Wilson --- boilerplate/cairo-boilerplate-xlib.c | 54 ++++---------------------- src/cairo-xlib-display.c | 57 ++++++++++++++++++++++++---- src/cairo-xlib.h | 5 +++ test/get-xrender-format.c | 10 ----- test/xlib-surface.c | 23 ++--------- 5 files changed, 66 insertions(+), 83 deletions(-) diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c index de79dcb1e..3a6beefd6 100644 --- a/boilerplate/cairo-boilerplate-xlib.c +++ b/boilerplate/cairo-boilerplate-xlib.c @@ -392,49 +392,6 @@ _cairo_boilerplate_xlib_window_create_surface (const char *name, return surface; } - -cairo_status_t -cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *abstract_surface) -{ -#if 0 - /* The following stunt doesn't work with xlib-xcb because it doesn't use - * cairo_xlib_surface_t for its surfaces. Sadly, there is no sane - * alternative, so we can't disable render with xlib-xcb. - * FIXME: Find an alternative. */ -#if !CAIRO_HAS_XLIB_XCB_FUNCTIONS - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t*) abstract_surface; - - if (cairo_surface_get_type (abstract_surface) != CAIRO_SURFACE_TYPE_XLIB) - return CAIRO_STATUS_SURFACE_TYPE_MISMATCH; - - surface->render_major = surface->render_minor = -1; - surface->xrender_format = NULL; - - /* The content type is forced by _xrender_format_to_content() during - * non-Render surface creation, so repeat the procedure here. */ - surface->base.content = CAIRO_CONTENT_COLOR; - - /* These flags are set based on known bugs and lack of RENDER support */ -#if CAIRO_XLIB_SURFACE_HAS_BUGGY_GRADIENTS - surface->buggy_gradients = TRUE; -#endif -#if CAIRO_XLIB_SURFACE_HAS_BUGGY_PAD_REFLECT - surface->buggy_pad_reflect = TRUE; -#endif -#if CAIRO_XLIB_SURFACE_HAS_BUGGY_REPEAT - surface->buggy_repeat = TRUE; -#endif -#endif -#endif - - return CAIRO_STATUS_SUCCESS; -} -#else -cairo_status_t -cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *abstract_surface) -{ - return CAIRO_STATUS_SUCCESS; -} #endif @@ -462,7 +419,7 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char *name, Display *dpy; int screen; XSetWindowAttributes attr; - cairo_surface_t *surface; + cairo_surface_t *surface, *dummy; /* We're not yet bothering to support perf mode for the * xlib-fallback surface. */ @@ -516,13 +473,18 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char *name, XMapWindow (dpy, xtc->drawable); xtc->drawable_is_pixmap = FALSE; + dummy = cairo_xlib_surface_create (dpy, xtc->drawable, + DefaultVisual (dpy, screen), + width, height); + cairo_xlib_device_debug_cap_xrender_version (cairo_surface_get_device (dummy), + -1, -1); + surface = cairo_xlib_surface_create (dpy, xtc->drawable, DefaultVisual (dpy, screen), width, height); + cairo_surface_destroy (dummy); if (cairo_surface_status (surface)) _cairo_boilerplate_xlib_cleanup (xtc); - else - cairo_boilerplate_xlib_surface_disable_render (surface); _cairo_boilerplate_xlib_setup_test_surface(surface); diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c index fd7253cc2..65cd3fbea 100644 --- a/src/cairo-xlib-display.c +++ b/src/cairo-xlib-display.c @@ -146,6 +146,17 @@ static const cairo_device_backend_t _cairo_xlib_device_backend = { _cairo_xlib_display_destroy, }; + +static void _cairo_xlib_display_select_compositor (cairo_xlib_display_t *display) +{ + if (display->render_major > 0 || display->render_minor >= 4) + display->compositor = _cairo_xlib_traps_compositor_get (); + else if (display->render_major > 0 || display->render_minor >= 0) + display->compositor = _cairo_xlib_mask_compositor_get (); + else + display->compositor = _cairo_xlib_core_compositor_get (); +} + /** * cairo_xlib_device_create: * @dpy: the display to create the device for @@ -221,6 +232,8 @@ _cairo_xlib_device_create (Display *dpy) } } + _cairo_xlib_display_select_compositor (display); + codes = XAddExtension (dpy); if (unlikely (codes == NULL)) { device = _cairo_device_create_in_error (CAIRO_STATUS_NO_MEMORY); @@ -331,13 +344,6 @@ _cairo_xlib_device_create (Display *dpy) display->buggy_pad_reflect = TRUE; } - if (display->render_major > 0 || display->render_minor >= 4) - display->compositor = _cairo_xlib_traps_compositor_get (); - else if (display->render_major > 0 || display->render_minor >= 0) - display->compositor = _cairo_xlib_mask_compositor_get (); - else - display->compositor = _cairo_xlib_core_compositor_get (); - display->next = _cairo_xlib_display_list; _cairo_xlib_display_list = display; @@ -552,6 +558,43 @@ _cairo_xlib_display_has_gradients (cairo_device_t *device) return ! ((cairo_xlib_display_t *) device)->buggy_gradients; } +/** + * cairo_xlib_device_debug_cap_xrender_version: + * @device: a #cairo_device_t for the XCB backend + * @major_version: major version to restrict to + * @minor_version: minor version to restrict to + * + * Restricts all future XCB surfaces for this devices to the specified version + * of the RENDER extension. This function exists solely for debugging purpose. + * It let's you find out how cairo would behave with an older version of + * the RENDER extension. + * + * Use the special values -1 and -1 for disabling the RENDER extension. + **/ +void +cairo_xlib_device_debug_cap_xrender_version (cairo_device_t *device, + int major_version, + int minor_version) +{ + cairo_xlib_display_t *display = (cairo_xlib_display_t *) device; + + if (device == NULL || device->status) + return; + + if (device->backend->type != CAIRO_DEVICE_TYPE_XLIB) + return; + + if (major_version < display->render_major || + (major_version == display->render_major && + minor_version < display->render_minor)) + { + display->render_major = major_version; + display->render_minor = minor_version; + } + + _cairo_xlib_display_select_compositor (display); +} + void cairo_xlib_device_debug_set_precision (cairo_device_t *device, int precision) diff --git a/src/cairo-xlib.h b/src/cairo-xlib.h index 7f770b972..ecf8d6c86 100644 --- a/src/cairo-xlib.h +++ b/src/cairo-xlib.h @@ -93,6 +93,11 @@ cairo_xlib_surface_get_height (cairo_surface_t *surface); /* debug interface */ +cairo_public void +cairo_xlib_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. diff --git a/test/get-xrender-format.c b/test/get-xrender-format.c index 8e99eb7c9..3228d57c6 100644 --- a/test/get-xrender-format.c +++ b/test/get-xrender-format.c @@ -101,16 +101,6 @@ preamble (cairo_test_context_t *ctx) goto CLEANUP_PIXMAP; } - cairo_test_log (ctx, "Testing without the X Render extension.\n"); - - cairo_boilerplate_xlib_surface_disable_render (surface); - - format = cairo_xlib_surface_get_xrender_format (surface); - if (format != NULL) { - cairo_test_log (ctx, "Error: did not receive a NULL format as expected\n"); - goto CLEANUP_PIXMAP; - } - result = CAIRO_TEST_SUCCESS; CLEANUP_PIXMAP: diff --git a/test/xlib-surface.c b/test/xlib-surface.c index be44b148b..4edc44bc4 100644 --- a/test/xlib-surface.c +++ b/test/xlib-surface.c @@ -136,7 +136,6 @@ do_test (const cairo_test_context_t *ctx, unsigned char *reference_data, unsigned char *test_data, unsigned char *diff_data, - cairo_bool_t use_render, cairo_bool_t use_pixmap, cairo_bool_t set_size, cairo_bool_t offscreen) @@ -184,9 +183,6 @@ do_test (const cairo_test_context_t *ctx, if (! surface_compare_visual_and_format (surface)) return CAIRO_TEST_FAILURE; - if (!use_render) - cairo_boilerplate_xlib_surface_disable_render (surface); - if (set_size) { cairo_xlib_surface_set_size (surface, SIZE, SIZE); @@ -243,13 +239,10 @@ do_test (const cairo_test_context_t *ctx, &result); } - cairo_test_log (ctx, "xlib-surface: %s, %s, %s%s: %s\n", - use_render ? " render" : "no-render", + cairo_test_log (ctx, "xlib-surface: %s, %s, %s: %s\n", set_size ? " size" : "no-size", use_pixmap ? "pixmap" : "window", - use_pixmap ? - " " : - (offscreen ? ", offscreen" : ", onscreen"), + use_pixmap ? " " : (offscreen ? ", offscreen" : ", onscreen"), image_diff_is_failure (&result, 0) ? "FAIL" : "PASS"); if (image_diff_is_failure (&result, 0)) @@ -335,17 +328,7 @@ preamble (cairo_test_context_t *ctx) for (offscreen = 0; offscreen <= 1; offscreen++) { status = do_test (ctx, dpy, reference_data, test_data, diff_data, - 1, use_pixmap, set_size, offscreen); - if (status) - result = status; - } - - for (set_size = 0; set_size <= 1; set_size++) - for (use_pixmap = 0; use_pixmap <= 1; use_pixmap++) - for (offscreen = 0; offscreen <= 1; offscreen++) { - status = do_test (ctx, dpy, - reference_data, test_data, diff_data, - 0, use_pixmap, set_size, offscreen); + use_pixmap, set_size, offscreen); if (status) result = status; }