[PATCH] xlib: Mark surfaces created via cairo_xlib_surface_create()

Karl Tomlinson karlt+ at karlt.net
Sun Jul 25 16:12:23 PDT 2010


If the drawable underlying one of these surfaces is a window, then documented
behavior is to include contents of inferior windows when the surface is used
as a source.

Other surfaces, including those created via
cairo_xlib_surface_create_with_xrender_format(), do not need to support this.
They can therefore efficiently support simple self-copies with XCopyArea and
use XSetTile to work around servers with buggy EXTEND_REPEAT.

http://lists.cairographics.org/archives/cairo/2010-July/020352.html
---
 src/cairo-xlib-surface-private.h                   |    4 ++++
 src/cairo-xlib-surface.c                           |   15 +++++++++++----
 test/self-copy-source-overlap.c                    |   19 -------------------
 .../self-copy-source-overlap.xlib-window.xfail.png |  Bin 0 -> 670 bytes
 4 files changed, 15 insertions(+), 23 deletions(-)
 create mode 100644 test/self-copy-source-overlap.xlib-window.xfail.png

diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index 34732b4..044b7ee 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -77,6 +77,10 @@ struct _cairo_xlib_surface {
 #define CAIRO_XLIB_SURFACE_HAS_BUGGY_GRADIENTS 1
 #define CAIRO_XLIB_SURFACE_HAS_BUGGY_PAD_REFLECT 1
 #define CAIRO_XLIB_SURFACE_HAS_BUGGY_REPEAT 1
+    /* TRUE if the contents of inferior windows should be included when the
+     * surface is used as a source.
+     */
+    unsigned int include_src_inferiors: 1;
 
     int width;
     int height;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 6a5ef67..7fd386e 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1963,7 +1963,7 @@ _recategorize_composite_operation (cairo_xlib_surface_t	      *dst,
 {
     /* Can we use the core protocol? */
     if (! have_mask &&
-        src->owns_pixmap &&
+        ! src->include_src_inferiors &&
 	_surfaces_compatible (src, dst) &&
 	_cairo_matrix_is_integer_translation (&src_attr->matrix, NULL, NULL) &&
 	! _operator_needs_alpha_composite (op, _surface_has_alpha (dst)))
@@ -3236,6 +3236,7 @@ found:
     surface->drawable = drawable;
     surface->owns_pixmap = FALSE;
     surface->use_pixmap = 0;
+    surface->include_src_inferiors = FALSE;
     surface->width = width;
     surface->height = height;
 
@@ -3367,6 +3368,7 @@ cairo_xlib_surface_create (Display     *dpy,
     Screen *scr;
     cairo_xlib_screen_t *screen;
     cairo_status_t status;
+    cairo_surface_t *surface;
 
     if (width > XLIB_COORD_MAX || height > XLIB_COORD_MAX) {
 	/* you're lying, and you know it! */
@@ -3383,9 +3385,14 @@ cairo_xlib_surface_create (Display     *dpy,
 
     X_DEBUG ((dpy, "create (drawable=%x)", (unsigned int) drawable));
 
-    return _cairo_xlib_surface_create_internal (screen, drawable,
-                                                visual, NULL,
-                                                width, height, 0);
+    surface = _cairo_xlib_surface_create_internal (screen, drawable,
+						   visual, NULL,
+						   width, height, 0);
+
+    if (likely (_cairo_surface_is_xlib (surface)))
+	((cairo_xlib_surface_t *)surface)->include_src_inferiors = TRUE;
+
+    return surface;
 }
 
 /**
diff --git a/test/self-copy-source-overlap.c b/test/self-copy-source-overlap.c
index 4b458d0..2fa1d0f 100644
--- a/test/self-copy-source-overlap.c
+++ b/test/self-copy-source-overlap.c
@@ -35,25 +35,6 @@ draw (cairo_t *cr, int width, int height)
     cairo_content_t content = cairo_surface_get_content (target);
     int pushed_group = 0;
 
-    /* The xlib backend currently only passes if it knows that the surface is
-       a Pixmap, which is currently only for surfaces from
-       cairo_surface_create_similar.  Other surfaces behave like Windows.
-       See http://lists.cairographics.org/archives/cairo/2010-July/020352.html
-       When that is resolved, this push_group should be removed.
-    */
-    if (cairo_surface_get_type (target) == CAIRO_SURFACE_TYPE_XLIB) {
-        cairo_push_group_with_content (cr, content);
-        pushed_group = 1;
-        target = cairo_get_group_target (cr);
-        if (cairo_surface_get_type (target) == CAIRO_SURFACE_TYPE_IMAGE) {
-            /* Don't test a fallback image surface.  xlib-fallback passes
-               without push-group, but image fails (tested separately). */
-            cairo_pattern_destroy (cairo_pop_group (cr));
-            pushed_group = 0;
-            target = cairo_get_group_target (cr);
-        }
-    }
-
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
 
     /* Paint a 4-square checker board as a test image */
diff --git a/test/self-copy-source-overlap.xlib-window.xfail.png b/test/self-copy-source-overlap.xlib-window.xfail.png
new file mode 100644
index 0000000000000000000000000000000000000000..5469d5e48cfa9d5e407909e581cbbdbb5b77a934
GIT binary patch
literal 670
zcmeAS at N?(olHy`uVBq!ia0vp^CqS5k2}mkgS)K$^Y)RhkE)4%caKYZ?lNlJ8f<0Xv
zLn`LHy?c=NkbwY$W6z8IPcJyh#XU7JW?c{*arga`uU2<UWBvO-^xyO6KQOb!)hR+{
z00=vO{tw>QqITE4`cWRAt0QzsNs&BaW8eNcb1GAJ6|S0 at L!Jp>iw(cDUVXgYC*5!B
z#9j)5q)cv&T>bgXRlg~5%f`=z=VnfyY<%`lnDp{Z8$CF>TQ-nI9GO*Vd9v2{zoRs{
eCIBt2VYCU<o~*7WeG!=87(8A5T-G at yGywoBh33lu

literal 0
HcmV?d00001

-- 
1.7.1


--=-=-=--


More information about the cairo mailing list