Only reduce the clip if it is not in active use for the operation

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-08-13 12:33:21 +01:00
parent d391f0908c
commit 279f6ceb59
5 changed files with 44 additions and 36 deletions

View file

@ -53,11 +53,13 @@ CAIRO_BEGIN_DECLS
struct _cairo_composite_rectangles {
cairo_rectangle_int_t source;
cairo_rectangle_int_t mask;
cairo_rectangle_int_t bounded; /* dst */
cairo_rectangle_int_t unbounded; /* clip */
cairo_rectangle_int_t destination;
cairo_rectangle_int_t bounded; /* source? IN mask? IN unbounded */
cairo_rectangle_int_t unbounded; /* destination IN clip */
uint32_t is_bounded;
cairo_clip_t *clip;
cairo_clip_t *clip; /* clip will be reduced to the minimal container */
};
cairo_private cairo_int_status_t
@ -108,6 +110,10 @@ cairo_private cairo_int_status_t
_cairo_composite_rectangles_intersect_mask_extents (cairo_composite_rectangles_t *extents,
const cairo_box_t *box);
cairo_private cairo_bool_t
_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite,
cairo_clip_t *clip);
cairo_private void
_cairo_composite_rectangles_fini (cairo_composite_rectangles_t *extents);

View file

@ -54,11 +54,12 @@ _cairo_composite_rectangles_init (cairo_composite_rectangles_t *extents,
const cairo_clip_t *clip)
{
extents->clip = NULL;
extents->destination = *unbounded;
if (_cairo_clip_is_all_clipped (clip))
return FALSE;
extents->unbounded = *unbounded;
extents->unbounded = extents->destination;
if (clip != NULL) {
if (! _cairo_rectangle_intersect (&extents->unbounded,
_cairo_clip_get_extents (clip)))
@ -247,3 +248,26 @@ _cairo_composite_rectangles_init_for_glyphs (cairo_composite_rectangles_t *exten
return _cairo_composite_rectangles_intersect (extents, clip);
}
cairo_bool_t
_cairo_composite_rectangles_can_reduce_clip (cairo_composite_rectangles_t *composite,
cairo_clip_t *clip)
{
cairo_rectangle_int_t extents;
if (clip == NULL)
return TRUE;
/* XXX In the not a region case, we could still search through the boxes */
if (! _cairo_clip_is_region (clip))
return FALSE;
extents = composite->destination;
if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_SOURCE)
_cairo_rectangle_intersect (&extents, &composite->source);
if (composite->is_bounded & CAIRO_OPERATOR_BOUND_BY_MASK)
_cairo_rectangle_intersect (&extents, &composite->mask);
return cairo_region_contains_rectangle (_cairo_clip_get_region (clip),
&extents) == CAIRO_REGION_OVERLAP_IN;
}

View file

@ -5793,22 +5793,13 @@ _cairo_pdf_surface_set_clip (cairo_pdf_surface_t *surface,
{
cairo_clip_t *clip = composite->clip;
if (_cairo_clip_is_region (clip) &&
cairo_region_contains_rectangle (_cairo_clip_get_region (clip),
&composite->unbounded) == CAIRO_REGION_OVERLAP_IN)
{
clip = NULL;
}
if (_cairo_composite_rectangles_can_reduce_clip (composite, clip))
clip = NULL;
if (clip == NULL) {
cairo_clip_t *current = surface->clipper.clip;
if (current && _cairo_clip_is_region (current) &&
cairo_region_contains_rectangle (_cairo_clip_get_region (current),
&composite->unbounded) == CAIRO_REGION_OVERLAP_IN)
{
if (_cairo_composite_rectangles_can_reduce_clip (composite,
surface->clipper.clip))
return CAIRO_STATUS_SUCCESS;
}
}
return _cairo_surface_clipper_set_clip (&surface->clipper, clip);

View file

@ -3617,28 +3617,18 @@ _cairo_ps_surface_set_clip (cairo_ps_surface_t *surface,
{
cairo_clip_t *clip = composite->clip;
if (_cairo_clip_is_region (clip) &&
cairo_region_contains_rectangle (_cairo_clip_get_region (clip),
&composite->unbounded) == CAIRO_REGION_OVERLAP_IN)
{
clip = NULL;
}
if (_cairo_composite_rectangles_can_reduce_clip (composite, clip))
clip = NULL;
if (clip == NULL) {
cairo_clip_t *current = surface->clipper.clip;
if (current && _cairo_clip_is_region (current) &&
cairo_region_contains_rectangle (_cairo_clip_get_region (current),
&composite->unbounded) == CAIRO_REGION_OVERLAP_IN)
{
if (_cairo_composite_rectangles_can_reduce_clip (composite,
surface->clipper.clip))
return CAIRO_STATUS_SUCCESS;
}
}
return _cairo_surface_clipper_set_clip (&surface->clipper, clip);
}
static cairo_int_status_t
_cairo_ps_surface_paint (void *abstract_surface,
cairo_operator_t op,

View file

@ -587,11 +587,8 @@ _command_init (cairo_recording_surface_t *surface,
/* steal the clip */
command->clip = NULL;
if (! _cairo_clip_is_region (composite->clip) ||
composite->mask.width > composite->unbounded.width ||
composite->mask.height > composite->unbounded.height ||
cairo_region_contains_rectangle (_cairo_clip_get_region (composite->clip),
&composite->unbounded) != CAIRO_REGION_OVERLAP_IN)
if (! _cairo_composite_rectangles_can_reduce_clip (composite,
composite->clip))
{
command->clip = composite->clip;
composite->clip = NULL;