[cairo-commit] 2 commits - src/cairo-xlib-display.c src/cairo-xlib-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Sun Sep 20 12:15:02 PDT 2009
src/cairo-xlib-display.c | 23 ++++-
src/cairo-xlib-surface.c | 197 +++++++++++++++++++++--------------------------
2 files changed, 110 insertions(+), 110 deletions(-)
New commits:
commit 9b7c5d95055c4ea5da46c53263050d6ec1331c08
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Sep 20 18:46:19 2009 +0100
[xlib] Cleanse creation of similar surfaces.
Reduce two nearly identical routines to one.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 4b2fd1f..88bad87 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -215,53 +215,6 @@ _cairo_xlib_surface_set_clip_region (cairo_xlib_surface_t *surface,
return CAIRO_STATUS_SUCCESS;
}
-static cairo_surface_t *
-_cairo_xlib_surface_create_similar_with_format (void *abstract_src,
- cairo_format_t format,
- int width,
- int height)
-{
- cairo_xlib_surface_t *src = abstract_src;
- Display *dpy = src->dpy;
- Pixmap pix;
- cairo_xlib_surface_t *surface;
- XRenderPictFormat *xrender_format;
-
- assert (width <= XLIB_COORD_MAX && height <= XLIB_COORD_MAX);
-
- /* As a good first approximation, if the display doesn't have even
- * the most elementary RENDER operation, then we're better off
- * using image surfaces for all temporary operations, so return NULL
- * and let the fallback code happen.
- */
- if (! CAIRO_SURFACE_RENDER_HAS_COMPOSITE (src))
- return NULL;
-
- xrender_format = _cairo_xlib_display_get_xrender_format (src->display,
- format);
- if (xrender_format == NULL)
- return NULL;
-
- pix = XCreatePixmap (dpy, src->drawable,
- width <= 0 ? 1 : width, height <= 0 ? 1 : height,
- xrender_format->depth);
-
- surface = (cairo_xlib_surface_t *)
- _cairo_xlib_surface_create_internal (src->screen, pix,
- NULL,
- xrender_format,
- width, height,
- xrender_format->depth);
- if (unlikely (surface->base.status)) {
- XFreePixmap (dpy, pix);
- return &surface->base;
- }
-
- surface->owns_pixmap = TRUE;
-
- return &surface->base;
-}
-
static cairo_content_t
_xrender_format_to_content (XRenderPictFormat *xrender_format)
{
@@ -301,6 +254,9 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
return NULL;
+ if (! CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (src))
+ return NULL;
+
_cairo_xlib_display_notify (src->display);
/* If we never found an XRenderFormat or if it isn't compatible
@@ -309,27 +265,60 @@ _cairo_xlib_surface_create_similar (void *abstract_src,
* arbitrarily pick a visual/depth for the similar surface.
*/
xrender_format = src->xrender_format;
- if (xrender_format == NULL ||
- _xrender_format_to_content (xrender_format) != content)
+ if ((xrender_format != NULL &&
+ _xrender_format_to_content (xrender_format) == content) ||
+ (xrender_format =
+ _cairo_xlib_display_get_xrender_format (src->display,
+ _cairo_format_from_content (content))))
{
- return _cairo_xlib_surface_create_similar_with_format (abstract_src,
- _cairo_format_from_content (content),
- width, height);
+ Visual *visual;
+
+ /* We've got a compatible XRenderFormat now, which means the
+ * similar surface will match the existing surface as closely in
+ * visual/depth etc. as possible. */
+ pix = XCreatePixmap (src->dpy, src->drawable,
+ width <= 0 ? 1 : width, height <= 0 ? 1 : height,
+ xrender_format->depth);
+
+ visual = NULL;
+ if (xrender_format == src->xrender_format)
+ visual = src->visual;
+
+ surface = (cairo_xlib_surface_t *)
+ _cairo_xlib_surface_create_internal (src->screen, pix,
+ visual,
+ xrender_format,
+ width, height,
+ xrender_format->depth);
+ }
+ else
+ {
+#ifdef DEBUG_FORCE_FALLBACKS
+ Screen *screen = src->screen->screen;
+ int depth;
+
+ /* No compatabile XRenderFormat, see if we can make an ordinary pixmap,
+ * so that we can still accelerate blits with XCopyArea(). */
+ if (content != CAIRO_CONTENT_COLOR)
+ return NULL;
+
+ depth = DefaultDepthOfScreen (screen);
+
+ pix = XCreatePixmap (src->dpy, RootWindowOfScreen (screen),
+ width <= 0 ? 1 : width, height <= 0 ? 1 : height,
+ depth);
+
+ surface = (cairo_xlib_surface_t *)
+ _cairo_xlib_surface_create_internal (src->screen, pix,
+ DefaultVisualOfScreen (screen),
+ NULL,
+ width, height, depth);
+#else
+ /* No compatabile XRenderFormat, just say no. */
+ return NULL;
+#endif
}
- /* We've got a compatible XRenderFormat now, which means the
- * similar surface will match the existing surface as closely in
- * visual/depth etc. as possible. */
- pix = XCreatePixmap (src->dpy, src->drawable,
- width <= 0 ? 1 : width, height <= 0 ? 1 : height,
- xrender_format->depth);
-
- surface = (cairo_xlib_surface_t *)
- _cairo_xlib_surface_create_internal (src->screen, pix,
- src->visual,
- xrender_format,
- width, height,
- xrender_format->depth);
if (unlikely (surface->base.status)) {
XFreePixmap (src->dpy, pix);
return &surface->base;
@@ -1032,15 +1021,14 @@ _draw_image_surface (cairo_xlib_surface_t *surface,
cairo_bool_t true_color;
int ret;
- if (surface->depth > 16) {
+ if (surface->depth > 16)
ximage.bits_per_pixel = 32;
- } else if (surface->depth > 8) {
+ else if (surface->depth > 8)
ximage.bits_per_pixel = 16;
- } else if (surface->depth > 1) {
+ else if (surface->depth > 1)
ximage.bits_per_pixel = 8;
- } else {
+ else
ximage.bits_per_pixel = 1;
- }
stride = CAIRO_STRIDE_FOR_WIDTH_BPP (ximage.width,
ximage.bits_per_pixel);
ximage.bytes_per_line = stride;
@@ -1270,21 +1258,14 @@ _cairo_xlib_surface_clone_similar (void *abstract_surface,
}
} else if (_cairo_surface_is_image (src)) {
cairo_image_surface_t *image_src = (cairo_image_surface_t *)src;
- cairo_format_t format;
if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX)
return UNSUPPORTED ("roi too large for xlib");
- format = image_src->format;
- if (format == CAIRO_FORMAT_INVALID ||
- (_cairo_content_from_format (format) & ~content))
- {
- format = _cairo_format_from_content (image_src->base.content & content);
- }
clone = (cairo_xlib_surface_t *)
- _cairo_xlib_surface_create_similar_with_format (surface,
- format,
- width, height);
+ _cairo_xlib_surface_create_similar (surface,
+ image_src->base.content & content,
+ width, height);
if (clone == NULL)
return UNSUPPORTED ("unhandled image format, no similar surface");
@@ -2777,34 +2758,42 @@ _cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
CAIRO_MUTEX_INITIALIZE ();
- if (xrender_format) {
- depth = xrender_format->depth;
+ if (depth == 0) {
+ if (xrender_format) {
+ depth = xrender_format->depth;
- /* XXX find matching visual for core/dithering fallbacks? */
- } else if (visual) {
- Screen *scr = screen->screen;
- int j, k;
+ /* XXX find matching visual for core/dithering fallbacks? */
+ } else if (visual) {
+ Screen *scr = screen->screen;
- /* This is ugly, but we have to walk over all visuals
- * for the display to find the correct depth.
- */
- depth = 0;
- for (j = 0; j < scr->ndepths; j++) {
- Depth *d = &scr->depths[j];
- for (k = 0; k < d->nvisuals; k++) {
- if (&d->visuals[k] == visual) {
- depth = d->depth;
- goto found;
+ if (visual == DefaultVisualOfScreen (scr)) {
+ depth = DefaultDepthOfScreen (scr);
+ } else {
+ int j, k;
+
+ /* This is ugly, but we have to walk over all visuals
+ * for the display to find the correct depth.
+ */
+ depth = 0;
+ for (j = 0; j < scr->ndepths; j++) {
+ Depth *d = &scr->depths[j];
+ for (k = 0; k < d->nvisuals; k++) {
+ if (&d->visuals[k] == visual) {
+ depth = d->depth;
+ goto found;
+ }
+ }
}
}
}
- found:
+
+ if (depth == 0)
+ return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
+
+found:
;
}
- if (depth == 0)
- return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_INVALID_VISUAL));
-
surface = malloc (sizeof (cairo_xlib_surface_t));
if (unlikely (surface == NULL))
return _cairo_surface_create_in_error (_cairo_error (CAIRO_STATUS_NO_MEMORY));
@@ -2830,11 +2819,7 @@ _cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
}
}
} else {
- xrender_format = NULL;
- }
-
- /* we cannot use XRender for this surface, so ensure we don't try */
- if (xrender_format == NULL) {
+ /* we cannot use XRender for this surface, so ensure we don't try */
surface->render_major = -1;
surface->render_minor = -1;
}
@@ -2914,7 +2899,7 @@ _cairo_xlib_surface_create_internal (cairo_xlib_screen_t *screen,
surface->b_mask = 0;
}
- return (cairo_surface_t *) surface;
+ return &surface->base;
}
static Screen *
commit 878cef62b525e9f13ab2a8ab562ba8b6628aaa1f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sun Sep 20 18:45:09 2009 +0100
[xlib] Interim CAIRO_DEBUG variable to specify xrender level
Use CAIRO_DEBUG=xrender-version=x.y to override what the server reports.
Useful to test cairo's behaviour against older servers.
diff --git a/src/cairo-xlib-display.c b/src/cairo-xlib-display.c
index b517fbf..56ea7c8 100644
--- a/src/cairo-xlib-display.c
+++ b/src/cairo-xlib-display.c
@@ -237,7 +237,7 @@ _cairo_xlib_display_get (Display *dpy,
cairo_xlib_display_t *display;
cairo_xlib_display_t **prev;
XExtCodes *codes;
- int render_major, render_minor;
+ const char *env;
cairo_status_t status = CAIRO_STATUS_SUCCESS;
/* There is an apparent deadlock between this mutex and the
@@ -281,7 +281,24 @@ _cairo_xlib_display_get (Display *dpy,
* add our hook. For now, that means Render, so we call into its
* QueryVersion function to ensure it gets initialized.
*/
- XRenderQueryVersion (dpy, &render_major, &render_minor);
+ display->render_major = display->render_minor = -1;
+ XRenderQueryVersion (dpy, &display->render_major, &display->render_minor);
+ env = getenv ("CAIRO_DEBUG");
+ if (env != NULL && (env = strstr (env, "xrender-version=")) != NULL) {
+ int max_render_major, max_render_minor;
+
+ env += sizeof ("xrender-version=") - 1;
+ if (sscanf (env, "%d.%d", &max_render_major, &max_render_minor) != 2)
+ max_render_major = max_render_minor = -1;
+
+ if (max_render_major < display->render_major ||
+ (max_render_major == display->render_major &&
+ max_render_minor < display->render_minor))
+ {
+ display->render_major = max_render_major;
+ display->render_minor = max_render_minor;
+ }
+ }
codes = XAddExtension (dpy);
if (unlikely (codes == NULL)) {
@@ -303,8 +320,6 @@ _cairo_xlib_display_get (Display *dpy,
display->close_display_hooks = NULL;
display->closed = FALSE;
- display->render_major = render_major;
- display->render_minor = render_minor;
memset (display->cached_xrender_formats, 0,
sizeof (display->cached_xrender_formats));
More information about the cairo-commit
mailing list