[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