[cairo-commit] 3 commits - src/cairo-clip-boxes.c src/cairo-recording-surface.c src/cairo-surface-wrapper.c src/cairo-surface-wrapper-private.h

Chris Wilson ickle at kemper.freedesktop.org
Sun Jul 24 10:47:47 PDT 2011


 src/cairo-clip-boxes.c              |   29 +++++++++++++++++++++-----
 src/cairo-recording-surface.c       |   40 ++++++++++++++++--------------------
 src/cairo-surface-wrapper-private.h |    6 ++---
 src/cairo-surface-wrapper.c         |   15 ++++++-------
 4 files changed, 52 insertions(+), 38 deletions(-)

New commits:
commit 8dc9139fb291605f93ce8409aa203c87d3a5d035
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jul 24 18:10:43 2011 +0100

    recording: Combine the clip to the recording + target surface extents
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-recording-surface.c b/src/cairo-recording-surface.c
index 2866155..f711344 100644
--- a/src/cairo-recording-surface.c
+++ b/src/cairo-recording-surface.c
@@ -833,6 +833,9 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 {
     cairo_recording_surface_t *recording_surface;
     cairo_command_t **elements;
+    cairo_bool_t replay_all =
+	type == CAIRO_RECORDING_REPLAY &&
+	region != CAIRO_RECORDING_REGION_ALL;
     int i, num_elements;
     cairo_int_status_t status;
     cairo_surface_wrapper_t wrapper;
@@ -850,13 +853,18 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 	return CAIRO_STATUS_SUCCESS;
 
     assert (_cairo_surface_is_recording (surface));
+    recording_surface = (cairo_recording_surface_t *) surface;
 
     _cairo_surface_wrapper_init (&wrapper, target);
-    _cairo_surface_wrapper_set_extents (&wrapper, surface_extents);
+    if (surface_extents)
+	_cairo_surface_wrapper_intersect_extents (&wrapper,
+						  surface_extents);
+    if (! recording_surface->unbounded)
+	_cairo_surface_wrapper_intersect_extents (&wrapper,
+						  &recording_surface->extents);
     _cairo_surface_wrapper_set_inverse_transform (&wrapper, surface_transform);
     _cairo_surface_wrapper_set_clip (&wrapper, target_clip);
 
-    recording_surface = (cairo_recording_surface_t *) surface;
     status = CAIRO_STATUS_SUCCESS;
 
     num_elements = recording_surface->commands.num_elements;
@@ -864,25 +872,16 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 
     for (i = recording_surface->replay_start_idx; i < num_elements; i++) {
 	cairo_command_t *command = elements[i];
-	cairo_clip_t *clip = command->header.clip;
 
-	if (type == CAIRO_RECORDING_REPLAY &&
-	    region != CAIRO_RECORDING_REGION_ALL) {
-	    if (command->header.region != region)
-		continue;
-        }
-
-	if (! recording_surface->unbounded)
-		clip = _cairo_clip_copy_intersect_rectangle (clip, &recording_surface->extents);
-	if (_cairo_clip_is_all_clipped (clip))
-		continue;
+	if (! replay_all && command->header.region != region)
+	    continue;
 
 	switch (command->header.type) {
 	case CAIRO_COMMAND_PAINT:
 	    status = _cairo_surface_wrapper_paint (&wrapper,
 						   command->header.op,
 						   &command->paint.source.base,
-						   clip);
+						   command->header.clip);
 	    break;
 
 	case CAIRO_COMMAND_MASK:
@@ -890,7 +889,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 						  command->header.op,
 						  &command->mask.source.base,
 						  &command->mask.mask.base,
-						  clip);
+						  command->header.clip);
 	    break;
 
 	case CAIRO_COMMAND_STROKE:
@@ -903,7 +902,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 						    &command->stroke.ctm_inverse,
 						    command->stroke.tolerance,
 						    command->stroke.antialias,
-						    clip);
+						    command->header.clip);
 	    break;
 
 	case CAIRO_COMMAND_FILL:
@@ -942,7 +941,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 								 &stroke_command->stroke.ctm_inverse,
 								 stroke_command->stroke.tolerance,
 								 stroke_command->stroke.antialias,
-								 clip);
+								 command->header.clip);
 		    i++;
 		}
 	    }
@@ -954,7 +953,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 						      command->fill.fill_rule,
 						      command->fill.tolerance,
 						      command->fill.antialias,
-						      clip);
+						      command->header.clip);
 	    }
 	    break;
 
@@ -967,7 +966,7 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 							      command->show_text_glyphs.clusters, command->show_text_glyphs.num_clusters,
 							      command->show_text_glyphs.cluster_flags,
 							      command->show_text_glyphs.scaled_font,
-							      clip);
+							      command->header.clip);
 	    break;
 
 	default:
@@ -985,9 +984,6 @@ _cairo_recording_surface_replay_internal (cairo_surface_t	     *surface,
 	    }
 	}
 
-	if (clip != command->header.clip)
-	    _cairo_clip_destroy (clip);
-
 	if (unlikely (status))
 	    break;
     }
diff --git a/src/cairo-surface-wrapper-private.h b/src/cairo-surface-wrapper-private.h
index 806c8dd..e2e46b3 100644
--- a/src/cairo-surface-wrapper-private.h
+++ b/src/cairo-surface-wrapper-private.h
@@ -60,8 +60,8 @@ _cairo_surface_wrapper_init (cairo_surface_wrapper_t *wrapper,
 			     cairo_surface_t *target);
 
 cairo_private void
-_cairo_surface_wrapper_set_extents (cairo_surface_wrapper_t *wrapper,
-				    const cairo_rectangle_int_t *extents);
+_cairo_surface_wrapper_intersect_extents (cairo_surface_wrapper_t *wrapper,
+					  const cairo_rectangle_int_t *extents);
 
 cairo_private void
 _cairo_surface_wrapper_set_inverse_transform (cairo_surface_wrapper_t *wrapper,
@@ -123,7 +123,7 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
 				    cairo_fill_rule_t	     fill_rule,
 				    double		     fill_tolerance,
 				    cairo_antialias_t	     fill_antialias,
-				    cairo_path_fixed_t	    *path,
+				    const cairo_path_fixed_t*path,
 				    cairo_operator_t	     stroke_op,
 				    const cairo_pattern_t   *stroke_source,
 				    const cairo_stroke_style_t    *stroke_style,
diff --git a/src/cairo-surface-wrapper.c b/src/cairo-surface-wrapper.c
index df32837..59c87da 100644
--- a/src/cairo-surface-wrapper.c
+++ b/src/cairo-surface-wrapper.c
@@ -256,7 +256,7 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
 				    cairo_fill_rule_t	     fill_rule,
 				    double		     fill_tolerance,
 				    cairo_antialias_t	     fill_antialias,
-				    cairo_path_fixed_t	    *path,
+				    const cairo_path_fixed_t*path,
 				    cairo_operator_t	     stroke_op,
 				    const cairo_pattern_t   *stroke_source,
 				    const cairo_stroke_style_t    *stroke_style,
@@ -267,7 +267,7 @@ _cairo_surface_wrapper_fill_stroke (cairo_surface_wrapper_t *wrapper,
 				    const cairo_clip_t	    *clip)
 {
     cairo_status_t status;
-    cairo_path_fixed_t path_copy, *dev_path = path;
+    cairo_path_fixed_t path_copy, *dev_path = (cairo_path_fixed_t *)path;
     cairo_matrix_t dev_ctm = *stroke_ctm;
     cairo_matrix_t dev_ctm_inverse = *stroke_ctm_inverse;
     cairo_clip_t *dev_clip;
@@ -494,15 +494,14 @@ _cairo_surface_wrapper_needs_device_transform (cairo_surface_wrapper_t *wrapper)
 }
 
 void
-_cairo_surface_wrapper_set_extents (cairo_surface_wrapper_t *wrapper,
-				    const cairo_rectangle_int_t *extents)
+_cairo_surface_wrapper_intersect_extents (cairo_surface_wrapper_t *wrapper,
+					  const cairo_rectangle_int_t *extents)
 {
-    if (extents != NULL) {
+    if (! wrapper->has_extents) {
 	wrapper->extents = *extents;
 	wrapper->has_extents = TRUE;
-    } else {
-	wrapper->has_extents = FALSE;
-    }
+    } else
+	_cairo_rectangle_intersect (&wrapper->extents, extents);
 
     wrapper->needs_transform =
 	_cairo_surface_wrapper_needs_device_transform (wrapper);
commit 15d5014efd8f3b4d01feb39259f2df0e69ac1b46
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jul 24 17:36:51 2011 +0100

    clip: Short-cut the common condition of intersecting with a single box
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-clip-boxes.c b/src/cairo-clip-boxes.c
index 52843fa..e18c2f8 100644
--- a/src/cairo-clip-boxes.c
+++ b/src/cairo-clip-boxes.c
@@ -277,6 +277,9 @@ _cairo_clip_intersect_boxes (cairo_clip_t *clip,
     if (boxes->num_boxes == 0)
 	return _cairo_clip_set_all_clipped (clip);
 
+    if (boxes->num_boxes == 1)
+	return _cairo_clip_intersect_box (clip, boxes->chunks.base);
+
     if (clip == NULL)
 	clip = _cairo_clip_create ();
 
@@ -291,7 +294,7 @@ _cairo_clip_intersect_boxes (cairo_clip_t *clip,
 	boxes = &clip_boxes;
     }
 
-    if(boxes->num_boxes == 1) {
+    if (boxes->num_boxes == 1) {
 	clip->boxes = &clip->embedded_box;
 	clip->boxes[0] = boxes->chunks.base[0];
 	clip->num_boxes = 1;
commit 52e3814824235ff236bc013f9adc85ed85eb8fb8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sun Jul 24 17:31:39 2011 +0100

    clip: Skip processing of rectangle-intersection if it wholly subsumes the clip
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-clip-boxes.c b/src/cairo-clip-boxes.c
index 663e92b..52843fa 100644
--- a/src/cairo-clip-boxes.c
+++ b/src/cairo-clip-boxes.c
@@ -157,6 +157,7 @@ _cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
 				     const cairo_box_t *box)
 {
     cairo_box_t extents_box;
+    cairo_bool_t changed = FALSE;
     int i, j;
 
     if (clip == NULL) {
@@ -178,6 +179,18 @@ _cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
 	return clip;
     }
 
+    /* Does the new box wholly subsume the clip? Perform a cheap check
+     * for the common condition of a single clip rectangle.
+     */
+    if (clip->num_boxes == 1 &&
+	clip->boxes[0].p1.x >= box->p1.x &&
+	clip->boxes[0].p1.y >= box->p1.y &&
+	clip->boxes[0].p2.x <= box->p2.x &&
+	clip->boxes[0].p2.y <= box->p2.y)
+    {
+	return clip;
+    }
+
     for (i = j = 0; i < clip->num_boxes; i++) {
 	cairo_box_t *b = &clip->boxes[j];
 
@@ -185,14 +198,14 @@ _cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
 	    *b = clip->boxes[i];
 
 	if (box->p1.x > b->p1.x)
-	    b->p1.x = box->p1.x;
+	    b->p1.x = box->p1.x, changed = TRUE;
 	if (box->p2.x < b->p2.x)
-	    b->p2.x = box->p2.x;
+	    b->p2.x = box->p2.x, changed = TRUE;
 
 	if (box->p1.y > b->p1.y)
-	    b->p1.y = box->p1.y;
+	    b->p1.y = box->p1.y, changed = TRUE;
 	if (box->p2.y < b->p2.y)
-	    b->p2.y = box->p2.y;
+	    b->p2.y = box->p2.y, changed = TRUE;
 
 	j += b->p2.x > b->p1.x && b->p2.y > b->p1.y;
     }
@@ -201,6 +214,9 @@ _cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
     if (clip->num_boxes == 0)
 	return _cairo_clip_set_all_clipped (clip);
 
+    if (! changed)
+	return clip;
+
     extents_box = clip->boxes[0];
     for (i = 1; i < clip->num_boxes; i++) {
 	    if (clip->boxes[i].p1.x < extents_box.p1.x)


More information about the cairo-commit mailing list