[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