diff options
Diffstat (limited to 'boilerplate/cairo-boilerplate-xlib.c')
-rw-r--r-- | boilerplate/cairo-boilerplate-xlib.c | 212 |
1 files changed, 169 insertions, 43 deletions
diff --git a/boilerplate/cairo-boilerplate-xlib.c b/boilerplate/cairo-boilerplate-xlib.c index a4deeb7..fe54d98 100644 --- a/boilerplate/cairo-boilerplate-xlib.c +++ b/boilerplate/cairo-boilerplate-xlib.c @@ -24,9 +24,8 @@ * Author: Carl D. Worth <cworth@cworth.org> */ -#include "cairo-boilerplate.h" +#include "cairo-boilerplate-private.h" #include "cairo-boilerplate-xlib.h" -#include "cairo-boilerplate-xlib-private.h" #include <cairo-xlib.h> #if CAIRO_HAS_XLIB_XRENDER_SURFACE @@ -36,14 +35,28 @@ #include <X11/Xutil.h> /* for XDestroyImage */ -typedef struct _xlib_target_closure -{ +typedef struct _xlib_target_closure { Display *dpy; Drawable drawable; cairo_bool_t drawable_is_pixmap; } xlib_target_closure_t; -void +static void +_cairo_boilerplate_xlib_cleanup (void *closure) +{ + xlib_target_closure_t *xtc = closure; + + if (xtc->drawable) { + if (xtc->drawable_is_pixmap) + XFreePixmap (xtc->dpy, xtc->drawable); + else + XDestroyWindow (xtc->dpy, xtc->drawable); + } + XCloseDisplay (xtc->dpy); + free (xtc); +} + +static void _cairo_boilerplate_xlib_synchronize (void *closure) { xlib_target_closure_t *xtc = closure; @@ -185,13 +198,13 @@ _cairo_boilerplate_xlib_perf_create_surface (Display *dpy, width, height); } -cairo_surface_t * +static cairo_surface_t * _cairo_boilerplate_xlib_create_surface (const char *name, cairo_content_t content, - int width, - int height, - int max_width, - int max_height, + double width, + double height, + double max_width, + double max_height, cairo_boilerplate_mode_t mode, int id, void **closure) @@ -202,9 +215,12 @@ _cairo_boilerplate_xlib_create_surface (const char *name, *closure = xtc = xcalloc (1, sizeof (xlib_target_closure_t)); - if (width == 0) + width = ceil (width); + if (width < 1) width = 1; - if (height == 0) + + height = ceil (height); + if (height < 1) height = 1; xtc->dpy = dpy = XOpenDisplay (NULL); @@ -224,7 +240,36 @@ _cairo_boilerplate_xlib_create_surface (const char *name, return surface; } + +cairo_status_t +cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *abstract_surface) +{ + 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 + + return CAIRO_STATUS_SUCCESS; +} + /* The xlib-fallback target differs from the xlib target in two ways: * @@ -235,13 +280,13 @@ _cairo_boilerplate_xlib_create_surface (const char *name, * This provides testing of the non-Render fallback paths we have in * cairo-xlib-surface.c */ -cairo_surface_t * +static cairo_surface_t * _cairo_boilerplate_xlib_fallback_create_surface (const char *name, cairo_content_t content, - int width, - int height, - int max_width, - int max_height, + double width, + double height, + double max_width, + double max_height, cairo_boilerplate_mode_t mode, int id, void **closure) @@ -265,9 +310,12 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char *name, *closure = xtc = xmalloc (sizeof (xlib_target_closure_t)); - if (width == 0) + width = ceil (width); + if (width < 1) width = 1; - if (height == 0) + + height = ceil (height); + if (height < 1) height = 1; xtc->dpy = dpy = XOpenDisplay (NULL); @@ -329,35 +377,113 @@ _cairo_boilerplate_xlib_fallback_create_surface (const char *name, return surface; } -void -_cairo_boilerplate_xlib_cleanup (void *closure) +static cairo_surface_t * +_cairo_boilerplate_xlib_reference_create_surface (const char *name, + cairo_content_t content, + double width, + double height, + double max_width, + double max_height, + cairo_boilerplate_mode_t mode, + int id, + void **closure) { - xlib_target_closure_t *xtc = closure; - - if (xtc->drawable) { - if (xtc->drawable_is_pixmap) - XFreePixmap (xtc->dpy, xtc->drawable); - else - XDestroyWindow (xtc->dpy, xtc->drawable); + xlib_target_closure_t *xtc; + Display *dpy; + cairo_surface_t *surface; + const char *display; + + display = getenv ("CAIRO_REFERENCE_DISPLAY"); + if (display == NULL) { + return _cairo_boilerplate_xlib_fallback_create_surface (name, content, + width, height, + max_width, + max_height, + mode, id, + closure); } - XCloseDisplay (xtc->dpy); - free (xtc); -} -cairo_status_t -cairo_boilerplate_xlib_surface_disable_render (cairo_surface_t *abstract_surface) -{ - cairo_xlib_surface_t *surface = (cairo_xlib_surface_t*) abstract_surface; + *closure = xtc = xcalloc (1, sizeof (xlib_target_closure_t)); - if (cairo_surface_get_type (abstract_surface) != CAIRO_SURFACE_TYPE_XLIB) - return CAIRO_STATUS_SURFACE_TYPE_MISMATCH; + width = ceil (width); + if (width < 1) + width = 1; - surface->render_major = surface->render_minor = -1; - surface->xrender_format = NULL; + height = ceil (height); + if (height < 1) + height = 1; - /* 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; + xtc->dpy = dpy = XOpenDisplay (display); + if (xtc->dpy == NULL) { + free (xtc); + CAIRO_BOILERPLATE_DEBUG (("Failed to open display: %s\n", display)); + return NULL; + } - return CAIRO_STATUS_SUCCESS; + if (mode == CAIRO_BOILERPLATE_MODE_TEST) + surface = _cairo_boilerplate_xlib_test_create_surface (dpy, content, width, height, xtc); + else /* mode == CAIRO_BOILERPLATE_MODE_PERF */ + surface = _cairo_boilerplate_xlib_perf_create_surface (dpy, content, width, height, xtc); + + if (surface == NULL || cairo_surface_status (surface)) + _cairo_boilerplate_xlib_cleanup (xtc); + + return surface; } +#endif + +static const cairo_boilerplate_target_t targets[] = { +#if CAIRO_HAS_XLIB_XRENDER_SURFACE + /* Acceleration architectures may make the results differ by a + * bit, so we set the error tolerance to 1. */ + { + "xlib", "xlib", NULL, "xlib-reference", + CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR_ALPHA, 1, + "cairo_xlib_surface_create_with_xrender_format", + _cairo_boilerplate_xlib_create_surface, + NULL, NULL, + _cairo_boilerplate_get_image_surface, + cairo_surface_write_to_png, + _cairo_boilerplate_xlib_cleanup, + _cairo_boilerplate_xlib_synchronize + }, + { + "xlib", "xlib", NULL, "xlib-reference", + CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, + "cairo_xlib_surface_create_with_xrender_format", + _cairo_boilerplate_xlib_create_surface, + NULL, NULL, + _cairo_boilerplate_get_image_surface, + cairo_surface_write_to_png, + _cairo_boilerplate_xlib_cleanup, + _cairo_boilerplate_xlib_synchronize + }, + { + "xlib-reference", "xlib", NULL, NULL, + CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, + "cairo_xlib_surface_create", + _cairo_boilerplate_xlib_reference_create_surface, + NULL, NULL, + NULL, /* get_image */ + cairo_surface_write_to_png, + _cairo_boilerplate_xlib_cleanup, + _cairo_boilerplate_xlib_synchronize + }, +#endif +#if CAIRO_HAS_XLIB_SURFACE + /* This is a fallback surface which uses xlib fallbacks instead of + * the Render extension. */ + { + "xlib-fallback", "xlib", NULL, NULL, + CAIRO_SURFACE_TYPE_XLIB, CAIRO_CONTENT_COLOR, 1, + "cairo_xlib_surface_create", + _cairo_boilerplate_xlib_fallback_create_surface, + NULL, NULL, + _cairo_boilerplate_get_image_surface, + cairo_surface_write_to_png, + _cairo_boilerplate_xlib_cleanup, + _cairo_boilerplate_xlib_synchronize + }, +#endif +}; +CAIRO_BOILERPLATE (xlib, targets) |