[cairo-commit] cairo/src cairo-xlib-surface.c, 1.89,
1.90 cairo-xlib-xrender.h, 1.1, 1.2 cairo-xlib.h, 1.17, 1.18
Keith Packard
commit at pdx.freedesktop.org
Wed Jul 20 18:52:34 PDT 2005
Committed by: keithp
Update of /cvs/cairo/cairo/src
In directory gabe:/tmp/cvs-serv12870/src
Modified Files:
cairo-xlib-surface.c cairo-xlib-xrender.h cairo-xlib.h
Log Message:
2005-07-20 Keith Packard <keithp at keithp.com>
reviewed by: otaylor
* src/cairo-xlib-surface.c: (_cairo_xlib_surface_create_similar),
(_cairo_xlib_surface_same_screen),
(_cairo_xlib_surface_clone_similar), (_surfaces_compatible),
(_categorize_composite_operation),
(_cairo_xlib_surface_create_internal),
(_cairo_xlib_screen_from_visual), (cairo_xlib_surface_create),
(cairo_xlib_surface_create_for_bitmap),
(cairo_xlib_surface_create_with_xrender_format):
* src/cairo-xlib-xrender.h:
* src/cairo-xlib.h:
* test/cairo-test.c: (create_xlib_surface):
Add Screen* arguments to:
cairo_xlib_surface_create_with_xrender_format
cairo_xlib_surface_create_for_bitmap
Required to correctly identify when two Xlib surfaces are
compatible with Core and Render rendering requests.
cairo_xlib_surface_create can determine the screen given
the required Visual *
Index: cairo-xlib-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -d -r1.89 -r1.90
--- cairo-xlib-surface.c 15 Jul 2005 20:45:19 -0000 1.89
+++ cairo-xlib-surface.c 21 Jul 2005 01:52:31 -0000 1.90
@@ -72,6 +72,7 @@
Display *dpy;
GC gc;
Drawable drawable;
+ Screen *screen;
cairo_bool_t owns_pixmap;
Visual *visual;
@@ -186,7 +187,6 @@
{
cairo_xlib_surface_t *src = abstract_src;
Display *dpy = src->dpy;
- int scr;
Pixmap pix;
cairo_xlib_surface_t *surface;
cairo_format_t format = _cairo_format_from_content (content);
@@ -201,14 +201,12 @@
return cairo_image_surface_create (format, width, height);
}
- scr = DefaultScreen (dpy);
-
- pix = XCreatePixmap (dpy, DefaultRootWindow (dpy),
+ pix = XCreatePixmap (dpy, RootWindowOfScreen (src->screen),
width <= 0 ? 1 : width, height <= 0 ? 1 : height,
depth);
surface = (cairo_xlib_surface_t *)
- cairo_xlib_surface_create_with_xrender_format (dpy, pix,
+ cairo_xlib_surface_create_with_xrender_format (dpy, pix, src->screen,
xrender_format,
width, height);
@@ -620,6 +618,18 @@
cairo_surface_destroy (&image->base);
}
+/*
+ * Return whether two xlib surfaces share the same
+ * screen. Both core and Render drawing require this
+ * when using multiple drawables in an operation.
+ */
+static cairo_bool_t
+_cairo_xlib_surface_same_screen (cairo_xlib_surface_t *dst,
+ cairo_xlib_surface_t *src)
+{
+ return dst->dpy == src->dpy && dst->screen == src->screen;
+}
+
static cairo_status_t
_cairo_xlib_surface_clone_similar (void *abstract_surface,
cairo_surface_t *src,
@@ -631,7 +641,7 @@
if (src->backend == surface->base.backend ) {
cairo_xlib_surface_t *xlib_src = (cairo_xlib_surface_t *)src;
- if (xlib_src->dpy == surface->dpy) {
+ if (_cairo_xlib_surface_same_screen (surface, xlib_src)) {
*clone_out = src;
cairo_surface_reference (src);
@@ -793,24 +803,26 @@
* a tile in a GC.
*/
static cairo_bool_t
-_surfaces_compatible (cairo_xlib_surface_t *src,
- cairo_xlib_surface_t *dst)
+_surfaces_compatible (cairo_xlib_surface_t *dst,
+ cairo_xlib_surface_t *src)
{
-
- if (src->dpy != dst->dpy)
+ /* same screen */
+ if (!_cairo_xlib_surface_same_screen (dst, src))
return FALSE;
- /* We must not only match depth and format/visual, we must also
- * match screen. We don't have that information, and rather than
- * asking for it round-trip, we'll just return FALSE if we have
- * more than one screen on the display.
- */
- if (ScreenCount (dst->dpy) > 1)
+ /* same depth (for core) */
+ if (src->depth != dst->depth)
return FALSE;
+
+ /* if Render is supported, match picture formats */
+ if (src->format != NULL && src->format == dst->format)
+ return TRUE;
- return (src->depth == dst->depth &&
- ((src->format != NULL && src->format == dst->format) ||
- (src->visual != NULL && src->visual == dst->visual)));
+ /* Without Render, match visuals instead */
+ if (src->visual == dst->visual)
+ return TRUE;
+
+ return FALSE;
}
static cairo_bool_t
@@ -880,7 +892,7 @@
{
if (!dst->buggy_repeat)
return DO_RENDER;
-
+
if (src_pattern->type == CAIRO_PATTERN_SURFACE)
{
cairo_surface_pattern_t *surface_pattern = (cairo_surface_pattern_t *)src_pattern;
@@ -901,7 +913,12 @@
if (operator == CAIRO_OPERATOR_OVER && _surface_has_alpha (src))
return DO_UNSUPPORTED;
- if (src->dpy == dst->dpy && !_surfaces_compatible (src, dst))
+ /* If these are on the same screen but otherwise incompatible,
+ * make a copy as core drawing can't cross depths and doesn't
+ * work rightacross visuals of the same depth
+ */
+ if (_cairo_xlib_surface_same_screen (dst, src) &&
+ !_surfaces_compatible (dst, src))
return DO_UNSUPPORTED;
}
}
@@ -1354,6 +1371,7 @@
static cairo_surface_t *
_cairo_xlib_surface_create_internal (Display *dpy,
Drawable drawable,
+ Screen *screen,
Visual *visual,
XRenderPictFormat *format,
int width,
@@ -1372,6 +1390,7 @@
surface->gc = NULL;
surface->drawable = drawable;
+ surface->screen = screen;
surface->owns_pixmap = FALSE;
surface->use_pixmap = 0;
surface->width = width;
@@ -1380,20 +1399,17 @@
if (format) {
depth = format->depth;
} else if (visual) {
- int i, j, k;
+ int j, k;
/* This is ugly, but we have to walk over all visuals
* for the display to find the depth.
*/
- for (i = 0; i < ScreenCount (dpy); i++) {
- Screen *screen = ScreenOfDisplay (dpy, i);
- for (j = 0; j < screen->ndepths; j++) {
- Depth *d = &screen->depths[j];
- for (k = 0; k < d->nvisuals; k++) {
- if (&d->visuals[k] == visual) {
- depth = d->depth;
- goto found;
- }
+ for (j = 0; j < screen->ndepths; j++) {
+ Depth *d = &screen->depths[j];
+ for (k = 0; k < d->nvisuals; k++) {
+ if (&d->visuals[k] == visual) {
+ depth = d->depth;
+ goto found;
}
}
}
@@ -1441,6 +1457,29 @@
return (cairo_surface_t *) surface;
}
+static Screen *
+_cairo_xlib_screen_from_visual (Display *dpy, Visual *visual)
+{
+ int s;
+ int d;
+ int v;
+ Screen *screen;
+ Depth *depth;
+
+ for (s = 0; s < ScreenCount (dpy); s++) {
+ screen = ScreenOfDisplay (dpy, s);
+ if (visual == DefaultVisualOfScreen (screen))
+ return screen;
+ for (d = 0; d < screen->ndepths; d++) {
+ depth = &screen->depths[d];
+ for (v = 0; v < depth->nvisuals; d++)
+ if (visual == &depth->visuals[v])
+ return screen;
+ }
+ }
+ return NULL;
+}
+
/**
* cairo_xlib_surface_create:
* @dpy: an X Display
@@ -1468,7 +1507,12 @@
int width,
int height)
{
- return _cairo_xlib_surface_create_internal (dpy, drawable,
+ Screen *screen = _cairo_xlib_screen_from_visual (dpy, visual);
+
+ if (screen == NULL)
+ return NULL;
+
+ return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
visual, NULL, width, height, 0);
}
@@ -1476,6 +1520,7 @@
* cairo_xlib_surface_create_for_bitmap:
* @dpy: an X Display
* @bitmap: an X Drawable, (a depth-1 Pixmap)
+ * @screen: the X Screen associated with @bitmap
* @width: the current width of @bitmap.
* @height: the current height of @bitmap.
*
@@ -1487,10 +1532,11 @@
cairo_surface_t *
cairo_xlib_surface_create_for_bitmap (Display *dpy,
Pixmap bitmap,
+ Screen *screen,
int width,
int height)
{
- return _cairo_xlib_surface_create_internal (dpy, bitmap,
+ return _cairo_xlib_surface_create_internal (dpy, bitmap, screen,
NULL, NULL, width, height, 1);
}
@@ -1498,6 +1544,7 @@
* cairo_xlib_surface_create_with_xrender_format:
* @dpy: an X Display
* @drawable: an X Drawable, (a Pixmap or a Window)
+ * @screen: the X Screen associated with @drawable
* @format: the picture format to use for drawing to @drawable. The depth
* of @format must match the depth of the drawable.
* @width: the current width of @drawable.
@@ -1516,11 +1563,12 @@
cairo_surface_t *
cairo_xlib_surface_create_with_xrender_format (Display *dpy,
Drawable drawable,
+ Screen *screen,
XRenderPictFormat *format,
int width,
int height)
{
- return _cairo_xlib_surface_create_internal (dpy, drawable,
+ return _cairo_xlib_surface_create_internal (dpy, drawable, screen,
NULL, format, width, height, 0);
}
Index: cairo-xlib-xrender.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-xrender.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cairo-xlib-xrender.h 17 May 2005 13:05:13 -0000 1.1
+++ cairo-xlib-xrender.h 21 Jul 2005 01:52:31 -0000 1.2
@@ -48,6 +48,7 @@
cairo_surface_t *
cairo_xlib_surface_create_with_xrender_format (Display *dpy,
Drawable drawable,
+ Screen *screen,
XRenderPictFormat *format,
int width,
int height);
Index: cairo-xlib.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cairo-xlib.h 17 May 2005 13:05:13 -0000 1.17
+++ cairo-xlib.h 21 Jul 2005 01:52:31 -0000 1.18
@@ -55,6 +55,7 @@
cairo_surface_t *
cairo_xlib_surface_create_for_bitmap (Display *dpy,
Pixmap bitmap,
+ Screen *screen,
int width,
int height);
More information about the cairo-commit
mailing list