[cairo-commit] 2 commits - src/cairo-clip.c src/cairo-recording-surface.c src/cairo-recording-surface-private.h

Chris Wilson ickle at kemper.freedesktop.org
Fri Jul 29 03:45:03 PDT 2011


 src/cairo-clip.c                      |   36 ++++++++++++++++++++++++++++++-
 src/cairo-recording-surface-private.h |    2 -
 src/cairo-recording-surface.c         |   39 +++++++++++++++-------------------
 3 files changed, 53 insertions(+), 24 deletions(-)

New commits:
commit aac9b261762cdb8039daedfe63a56a83faa0155f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jul 29 11:42:59 2011 +0100

    clip: Fix cairo_clip_equal()
    
    In haste, I completely removed the implementation...
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-clip.c b/src/cairo-clip.c
index a90c698..b01093e 100644
--- a/src/cairo-clip.c
+++ b/src/cairo-clip.c
@@ -340,11 +340,45 @@ cairo_bool_t
 _cairo_clip_equal (const cairo_clip_t *clip_a,
 		   const cairo_clip_t *clip_b)
 {
+    const cairo_clip_path_t *cp_a, *cp_b;
+
     /* are both all-clipped or no-clip? */
     if (clip_a == clip_b)
 	return TRUE;
 
-    return FALSE;
+    if (clip_a->num_boxes != clip_b->num_boxes)
+	return FALSE;
+
+    if (memcmp (clip_a->boxes, clip_b->boxes,
+		sizeof (cairo_box_t) * clip_a->num_boxes))
+	return FALSE;
+
+    cp_a = clip_a->path;
+    cp_b = clip_b->path;
+    while (cp_a && cp_b) {
+	if (cp_a == cp_b)
+	    return TRUE;
+
+	/* XXX compare reduced polygons? */
+
+	if (cp_a->antialias != cp_b->antialias)
+	    return FALSE;
+
+	if (cp_a->tolerance != cp_b->tolerance)
+	    return FALSE;
+
+	if (cp_a->fill_rule != cp_b->fill_rule)
+	    return FALSE;
+
+	if (! _cairo_path_fixed_equal (&cp_a->path,
+				       &cp_b->path))
+	    return FALSE;
+
+	cp_a = cp_a->prev;
+	cp_b = cp_b->prev;
+    }
+
+    return cp_a == NULL && cp_b == NULL;
 }
 
 static cairo_clip_t *
commit ecafad7149cb80bad56cc042ced4bb06c106ce1a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jul 29 11:18:36 2011 +0100

    record: Assume recording surface targets are clear
    
    The replay of the recording surface will not function correctly unless
    the target surface region is already clear. So assume that is and
    optimise away the initial clear.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-recording-surface-private.h b/src/cairo-recording-surface-private.h
index bf5eb75..c370b67 100644
--- a/src/cairo-recording-surface-private.h
+++ b/src/cairo-recording-surface-private.h
@@ -142,8 +142,6 @@ typedef struct _cairo_recording_surface {
 	struct bbtree *left, *right;
 	cairo_command_header_t *chain;
     } bbtree;
-
-    int replay_start_idx;
 } cairo_recording_surface_t;
 
 slim_hidden_proto (cairo_recording_surface_create);
diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index a0faf21..6ad276e 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -303,7 +303,7 @@ _cairo_recording_surface_destroy_bbtree (cairo_recording_surface_t *surface)
 
     elements = _cairo_array_index (&surface->commands, 0);
     num_elements = surface->commands.num_elements;
-    for (i = surface->replay_start_idx; i < num_elements; i++)
+    for (i = 0; i < num_elements; i++)
 	elements[i]->header.chain = NULL;
 
     surface->bbtree.chain = INVALID_CHAIN;
@@ -317,7 +317,7 @@ _cairo_recording_surface_create_bbtree (cairo_recording_surface_t *surface)
     int i, count;
     int *indices;
 
-    count = surface->commands.num_elements - surface->replay_start_idx;
+    count = surface->commands.num_elements;
     if (count > surface->num_indices) {
 	free (surface->indices);
 	surface->indices = _cairo_malloc_ab (count, sizeof (int));
@@ -329,7 +329,7 @@ _cairo_recording_surface_create_bbtree (cairo_recording_surface_t *surface)
 
     indices = surface->indices;
     for (i = 0; i < count; i++)
-	indices[i] = i + surface->replay_start_idx;
+	indices[i] = i;
 
     sort_commands (indices, count, elements);
 
@@ -406,8 +406,7 @@ cairo_recording_surface_create (cairo_content_t		 content,
 
     _cairo_array_init (&surface->commands, sizeof (cairo_command_t *));
 
-    surface->replay_start_idx = 0;
-    surface->base.is_clear = FALSE;
+    surface->base.is_clear = TRUE;
 
     surface->bbtree.left = surface->bbtree.right = NULL;
     surface->bbtree.chain = INVALID_CHAIN;
@@ -613,6 +612,15 @@ _cairo_recording_surface_paint (void			  *abstract_surface,
     cairo_composite_rectangles_t composite;
     const cairo_rectangle_int_t *extents;
 
+    /* An optimisation that takes care to not replay what was done
+     * before surface is cleared. We don't erase recorded commands
+     * since we may have earlier snapshots of this surface. */
+    if (op == CAIRO_OPERATOR_CLEAR && clip == NULL) {
+	_cairo_recording_surface_destroy_bbtree (surface);
+	surface->commands.num_elements = 0;
+	return CAIRO_STATUS_SUCCESS;
+    }
+
     extents = _cairo_recording_surface_extents (surface);
     status = _cairo_composite_rectangles_init_for_paint (&composite, extents,
 							 op, source,
@@ -642,12 +650,6 @@ _cairo_recording_surface_paint (void			  *abstract_surface,
 
     _cairo_recording_surface_destroy_bbtree (surface);
 
-    /* An optimisation that takes care to not replay what was done
-     * before surface is cleared. We don't erase recorded commands
-     * since we may have earlier snapshots of this surface. */
-    if (op == CAIRO_OPERATOR_CLEAR && clip == NULL)
-	surface->replay_start_idx = surface->commands.num_elements;
-
     _cairo_composite_rectangles_fini (&composite);
     return CAIRO_STATUS_SUCCESS;
 
@@ -1013,11 +1015,7 @@ _cairo_recording_surface_snapshot (void *abstract_other)
     surface->unbounded = other->unbounded;
     surface->content = other->content;
 
-    /* XXX We should in theory be able to reuse the original array, but we
-     * need to handle reference cycles during subsurface and self-copy.
-     */
-    surface->replay_start_idx = 0;
-    surface->base.is_clear = FALSE;
+    surface->base.is_clear = TRUE;
 
     surface->bbtree.left = surface->bbtree.right = NULL;
     surface->bbtree.chain = INVALID_CHAIN;
@@ -1133,7 +1131,7 @@ _cairo_recording_surface_get_path (cairo_surface_t    *abstract_surface,
 
     num_elements = surface->commands.num_elements;
     elements = _cairo_array_index (&surface->commands, 0);
-    for (i = surface->replay_start_idx; i < num_elements; i++) {
+    for (i = 0; i < num_elements; i++) {
 	cairo_command_t *command = elements[i];
 
 	switch (command->header.type) {
@@ -1239,11 +1237,10 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t	*surface,
     if (unlikely (surface->base.finished))
 	return _cairo_error (CAIRO_STATUS_SURFACE_FINISHED);
 
-    if (surface->base.is_clear && target->is_clear)
+    if (surface->base.is_clear)
 	return CAIRO_STATUS_SUCCESS;
 
     assert (_cairo_surface_is_recording (&surface->base));
-    assert ((int)surface->commands.num_elements > surface->replay_start_idx);
 
     _cairo_surface_wrapper_init (&wrapper, target);
     if (surface_extents)
@@ -1260,7 +1257,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t	*surface,
     if (! _cairo_surface_wrapper_get_target_extents (&wrapper, &extents))
 	goto done;
 
-    num_elements = surface->commands.num_elements - surface->replay_start_idx;
+    num_elements = surface->commands.num_elements;
     elements = _cairo_array_index (&surface->commands, 0);
     if (extents.width < r->width || extents.height < r->height) {
 	num_elements =
@@ -1269,7 +1266,7 @@ _cairo_recording_surface_replay_internal (cairo_recording_surface_t	*surface,
     }
 
     for (i = 0; i < num_elements; i++) {
-	cairo_command_t *command = elements[use_indices ? surface->indices[i] : i + surface->replay_start_idx];
+	cairo_command_t *command = elements[use_indices ? surface->indices[i] : i];
 
 	if (! replay_all && command->header.region != region)
 	    continue;


More information about the cairo-commit mailing list