mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-24 23:00:09 +01:00
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:
parent
d391f0908c
commit
279f6ceb59
5 changed files with 44 additions and 36 deletions
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue