[cairo-commit] src/cairo-image-surface.c src/cairo-paginated-private.h src/cairo-paginated-surface.c

Chris Wilson ickle at kemper.freedesktop.org
Fri Jul 29 10:40:28 PDT 2011


 src/cairo-image-surface.c     |   72 +++++++++++++++++++++++++++++++++++-------
 src/cairo-paginated-private.h |    3 +
 src/cairo-paginated-surface.c |   12 ++++++-
 3 files changed, 74 insertions(+), 13 deletions(-)

New commits:
commit 2342e4da4fdbeed5672d586742fa19cf1018264c
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jul 29 18:36:52 2011 +0100

    image: extend support of direct replay for paginated surfaces
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-image-surface.c b/src/cairo-image-surface.c
index 3eb4e05..7a0ddc6 100644
--- a/src/cairo-image-surface.c
+++ b/src/cairo-image-surface.c
@@ -44,9 +44,10 @@
 #include "cairo-composite-rectangles-private.h"
 #include "cairo-default-context-private.h"
 #include "cairo-error-private.h"
+#include "cairo-paginated-private.h"
+#include "cairo-pattern-private.h"
 #include "cairo-recording-surface-private.h"
 #include "cairo-region-private.h"
-#include "cairo-pattern-private.h"
 #include "cairo-scaled-font-private.h"
 #include "cairo-surface-snapshot-private.h"
 #include "cairo-surface-subsurface-private.h"
@@ -2912,22 +2913,68 @@ _composite_unaligned_boxes (cairo_image_surface_t *dst,
 static cairo_bool_t
 is_recording_pattern (const cairo_pattern_t *pattern)
 {
-    const cairo_surface_pattern_t *surface_pattern;
+    cairo_surface_t *surface;
 
     if (pattern->type != CAIRO_PATTERN_TYPE_SURFACE)
 	return FALSE;
 
-   surface_pattern = (const cairo_surface_pattern_t *) pattern;
-   return _cairo_surface_is_recording (surface_pattern->surface);
+    surface = ((const cairo_surface_pattern_t *) pattern)->surface;
+    if (_cairo_surface_is_paginated (surface))
+	surface = _cairo_paginated_surface_get_recording (surface);
+    return _cairo_surface_is_recording (surface);
 }
 
 static cairo_surface_t *
-pattern_get_surface (const cairo_pattern_t *pattern)
+recording_pattern_get_surface (const cairo_pattern_t *pattern)
+{
+    cairo_surface_t *surface;
+
+    surface = ((const cairo_surface_pattern_t *) pattern)->surface;
+    if (_cairo_surface_is_paginated (surface))
+	surface = _cairo_paginated_surface_get_recording (surface);
+    return surface;
+}
+
+static cairo_bool_t
+op_reduces_to_source (cairo_operator_t op,
+		      cairo_image_surface_t *dst)
+{
+    if (op == CAIRO_OPERATOR_SOURCE)
+	return TRUE;
+
+    if (dst->base.is_clear)
+	return op == CAIRO_OPERATOR_OVER || op == CAIRO_OPERATOR_ADD;
+
+    return FALSE;
+}
+
+static cairo_bool_t
+recording_pattern_contains_sample (const cairo_pattern_t *pattern,
+				   const cairo_rectangle_int_t *extents)
 {
-    const cairo_surface_pattern_t *surface_pattern;
+    cairo_rectangle_int_t area;
+    cairo_recording_surface_t *surface;
+
+    if (! is_recording_pattern (pattern))
+	return FALSE;
+
+    if (pattern->extend == CAIRO_EXTEND_NONE)
+	return TRUE;
 
-   surface_pattern = (const cairo_surface_pattern_t *) pattern;
-   return surface_pattern->surface;
+    surface = (cairo_recording_surface_t *) recording_pattern_get_surface (pattern);
+    if (surface->unbounded)
+	return TRUE;
+
+    sampled_area ((cairo_surface_pattern_t *) pattern, extents, &area);
+    if (area.x >= surface->extents.x &&
+	area.y >= surface->extents.y &&
+	area.x + area.width <= surface->extents.x + surface->extents.width &&
+	area.y + area.height <= surface->extents.y + surface->extents.height)
+    {
+	return TRUE;
+    }
+
+    return FALSE;
 }
 
 static cairo_status_t
@@ -2970,12 +3017,13 @@ _composite_boxes (cairo_image_surface_t *dst,
 
     /* Are we just copying a recording surface? */
     if (! need_clip_mask &&
-	op == CAIRO_OPERATOR_SOURCE &&
-	pattern->extend == CAIRO_EXTEND_NONE && /* or if sample is contained */
-	is_recording_pattern (pattern))
+	op_reduces_to_source (op, dst) &&
+	recording_pattern_contains_sample (pattern, &extents->bounded))
     {
 	cairo_clip_t *recording_clip;
 
+	/* XXX could also do tiling repeat modes... */
+
 	/* first clear the area about to be overwritten */
 	if (! dst->base.is_clear) {
 	    for (chunk = &boxes->chunks; chunk != NULL; chunk = chunk->next) {
@@ -3000,7 +3048,7 @@ _composite_boxes (cairo_image_surface_t *dst,
 	}
 
 	recording_clip = _cairo_clip_from_boxes (boxes);
-	status = _cairo_recording_surface_replay_with_clip (pattern_get_surface (pattern),
+	status = _cairo_recording_surface_replay_with_clip (recording_pattern_get_surface (pattern),
 							    &pattern->matrix,
 							    &dst->base,
 							    recording_clip);
diff --git a/src/cairo-paginated-private.h b/src/cairo-paginated-private.h
index 42badbf..b827fab 100644
--- a/src/cairo-paginated-private.h
+++ b/src/cairo-paginated-private.h
@@ -154,6 +154,9 @@ _cairo_paginated_surface_create (cairo_surface_t				*target,
 cairo_private cairo_surface_t *
 _cairo_paginated_surface_get_target (cairo_surface_t *surface);
 
+cairo_private cairo_surface_t *
+_cairo_paginated_surface_get_recording (cairo_surface_t *surface);
+
 cairo_private cairo_bool_t
 _cairo_surface_is_paginated (cairo_surface_t *surface);
 
diff --git a/src/cairo-paginated-surface.c b/src/cairo-paginated-surface.c
index 5fe3439..9595587 100644
--- a/src/cairo-paginated-surface.c
+++ b/src/cairo-paginated-surface.c
@@ -147,10 +147,20 @@ _cairo_paginated_surface_get_target (cairo_surface_t *surface)
     assert (_cairo_surface_is_paginated (surface));
 
     paginated_surface = (cairo_paginated_surface_t *) surface;
-
     return paginated_surface->target;
 }
 
+cairo_surface_t *
+_cairo_paginated_surface_get_recording (cairo_surface_t *surface)
+{
+    cairo_paginated_surface_t *paginated_surface;
+
+    assert (_cairo_surface_is_paginated (surface));
+
+    paginated_surface = (cairo_paginated_surface_t *) surface;
+    return paginated_surface->recording_surface;
+}
+
 cairo_status_t
 _cairo_paginated_surface_set_size (cairo_surface_t	*surface,
 				   int			 width,


More information about the cairo-commit mailing list