summaryrefslogtreecommitdiff
path: root/src/cairo-xlib-render-compositor.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2012-02-23 13:39:37 +0000
committerChris Wilson <chris@chris-wilson.co.uk>2012-02-23 13:44:28 +0000
commitb079f18fade93472db83b4decf086e30711a86d3 (patch)
tree4b7346326871bd0848dd1fcf3ddbe81e56f91c2e /src/cairo-xlib-render-compositor.c
parentcc09b29752e857e55879a7d773b8be1317eb2001 (diff)
downloadcairo-b079f18fade93472db83b4decf086e30711a86d3.tar.gz
xlib: Handle window-to-window copies by avoiding the use of a clip region
Rather than compress the copies into a clip + copy, iterate over and perform each copy separately so as to avoid the confusion for window-to-window copies and the solitary GC->pCompositeClip. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/cairo-xlib-render-compositor.c')
-rw-r--r--src/cairo-xlib-render-compositor.c96
1 files changed, 54 insertions, 42 deletions
diff --git a/src/cairo-xlib-render-compositor.c b/src/cairo-xlib-render-compositor.c
index 106793911..86641b9f4 100644
--- a/src/cairo-xlib-render-compositor.c
+++ b/src/cairo-xlib-render-compositor.c
@@ -164,18 +164,6 @@ copy_boxes (void *_dst,
GC gc;
int i, j;
- /* We can only have a single control for subwindow_mode on the
- * GC. If we have a Window destination, we need to set ClipByChildren,
- * but if we have a Window source, we need IncludeInferiors. If we have
- * both a Window destination and source, we must fallback. There is
- * no convenient way to detect if a drawable is a Pixmap or Window,
- * therefore we can only rely on those surfaces that we created
- * ourselves to be Pixmaps, and treat everything else as a potential
- * Window.
- */
- if (! src->owns_pixmap && ! dst->owns_pixmap)
- return CAIRO_INT_STATUS_UNSUPPORTED;
-
if (! _cairo_xlib_surface_same_screen (dst, src))
return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -210,43 +198,67 @@ copy_boxes (void *_dst,
x2 - x1, y2 - y1,
x1, y1);
} else {
- XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)];
- XRectangle *rects = stack_rects;
-
- if (boxes->num_boxes > ARRAY_LENGTH (stack_rects)) {
- rects = _cairo_malloc_ab (boxes->num_boxes, sizeof (XRectangle));
- if (unlikely (rects == NULL))
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
- }
+ /* We can only have a single control for subwindow_mode on the
+ * GC. If we have a Window destination, we need to set ClipByChildren,
+ * but if we have a Window source, we need IncludeInferiors. If we have
+ * both a Window destination and source, we must fallback. There is
+ * no convenient way to detect if a drawable is a Pixmap or Window,
+ * therefore we can only rely on those surfaces that we created
+ * ourselves to be Pixmaps, and treat everything else as a potential
+ * Window.
+ */
+ if (src == dst || (!src->owns_pixmap && !dst->owns_pixmap)) {
+ for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
+ for (i = 0; i < chunk->count; i++) {
+ int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
+ int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
+ int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
+ int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
+ XCopyArea (dst->dpy, src->drawable, dst->drawable, gc,
+ x1 + dx, y1 + dy,
+ x2 - x1, y2 - y1,
+ x1, y1);
+ }
+ }
+ } else {
+ XRectangle stack_rects[CAIRO_STACK_ARRAY_LENGTH (XRectangle)];
+ XRectangle *rects = stack_rects;
- j = 0;
- for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
- for (i = 0; i < chunk->count; i++) {
- int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
- int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
- int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
- int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
+ if (boxes->num_boxes > ARRAY_LENGTH (stack_rects)) {
+ rects = _cairo_malloc_ab (boxes->num_boxes, sizeof (XRectangle));
+ if (unlikely (rects == NULL))
+ return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ }
- rects[j].x = x1;
- rects[j].y = y1;
- rects[j].width = x2 - x1;
- rects[j].height = y2 - y1;
- j++;
+ j = 0;
+ for (chunk = &boxes->chunks; chunk; chunk = chunk->next) {
+ for (i = 0; i < chunk->count; i++) {
+ int x1 = _cairo_fixed_integer_part (chunk->base[i].p1.x);
+ int y1 = _cairo_fixed_integer_part (chunk->base[i].p1.y);
+ int x2 = _cairo_fixed_integer_part (chunk->base[i].p2.x);
+ int y2 = _cairo_fixed_integer_part (chunk->base[i].p2.y);
+
+ rects[j].x = x1;
+ rects[j].y = y1;
+ rects[j].width = x2 - x1;
+ rects[j].height = y2 - y1;
+ j++;
+ }
}
- }
- assert (j == boxes->num_boxes);
+ assert (j == boxes->num_boxes);
- XSetClipRectangles (dst->dpy, gc, 0, 0, rects, j, Unsorted);
+ XSetClipRectangles (dst->dpy, gc, 0, 0, rects, j, Unsorted);
- XCopyArea (dst->dpy, src->drawable, dst->drawable, gc,
- extents->x + dx, extents->y + dy,
- extents->width, extents->height,
- extents->x, extents->y);
+ XCopyArea (dst->dpy, src->drawable, dst->drawable, gc,
+ extents->x + dx, extents->y + dy,
+ extents->width, extents->height,
+ extents->x, extents->y);
- XSetClipMask (dst->dpy, gc, None);
+ XSetClipMask (dst->dpy, gc, None);
- if (rects != stack_rects)
- free (rects);
+ if (rects != stack_rects)
+ free (rects);
+ }
}
if (! src->owns_pixmap) {