clip: Embed a single box to avoid a common allocation

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2011-07-24 00:58:06 +01:00
parent 926287aeea
commit 04ef07ee3b
3 changed files with 62 additions and 36 deletions

View file

@ -163,26 +163,22 @@ _cairo_clip_intersect_rectangle_box (cairo_clip_t *clip,
clip = _cairo_clip_create ();
if (clip == NULL)
return _cairo_clip_set_all_clipped (clip);
clip->boxes = _cairo_malloc (sizeof (cairo_box_t));
if (clip->boxes == NULL)
return _cairo_clip_set_all_clipped (clip);
clip->extents = *r;
clip->num_boxes = 1;
clip->boxes[0] = *box;
return clip;
}
if (clip->num_boxes == 0) {
clip->boxes = _cairo_malloc (sizeof (cairo_box_t));
if (clip->boxes == NULL)
return _cairo_clip_set_all_clipped (clip);
j = 1;
clip->boxes = &clip->embedded_box;
clip->boxes[0] = *box;
} else for (i = j = 0; i < clip->num_boxes; i++) {
clip->num_boxes = 1;
if (clip->path == NULL) {
clip->extents = *r;
} else {
if (! _cairo_rectangle_intersect (&clip->extents, r))
clip = _cairo_clip_set_all_clipped (clip);
}
return clip;
}
for (i = j = 0; i < clip->num_boxes; i++) {
cairo_box_t *b = &clip->boxes[j];
if (j != i)
@ -268,19 +264,28 @@ _cairo_clip_intersect_boxes (cairo_clip_t *clip,
if (clip == NULL)
clip = _cairo_clip_create ();
if (clip->num_boxes == 0) {
clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
_cairo_boxes_extents (boxes, &extents);
} else {
if (clip->num_boxes) {
_cairo_boxes_init_for_array (&clip_boxes, clip->boxes, clip->num_boxes);
if (unlikely (_cairo_boxes_intersect (&clip_boxes, boxes, &clip_boxes)))
return _cairo_clip_set_all_clipped (clip);
free (clip->boxes);
clip->boxes = _cairo_boxes_to_array (&clip_boxes, &clip->num_boxes, TRUE);
_cairo_boxes_extents (&clip_boxes, &extents);
if (clip->boxes != &clip->embedded_box)
free (clip->boxes);
boxes = &clip_boxes;
}
if(boxes->num_boxes == 1) {
clip->boxes = &clip->embedded_box;
clip->boxes[0] = boxes->chunks.base[0];
clip->num_boxes = 1;
} else {
clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
}
_cairo_boxes_extents (boxes, &extents);
if (boxes == &clip_boxes)
_cairo_boxes_fini (&clip_boxes);
if (clip->path == NULL)
clip->extents = extents;
else if (! _cairo_rectangle_intersect (&clip->extents, &extents))
@ -569,9 +574,15 @@ _cairo_clip_from_boxes (const cairo_boxes_t *boxes)
return _cairo_clip_set_all_clipped (clip);
/* XXX cow-boxes? */
clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
if (clip->boxes == NULL)
return _cairo_clip_set_all_clipped (clip);
if(boxes->num_boxes == 1) {
clip->boxes = &clip->embedded_box;
clip->boxes[0] = boxes->chunks.base[0];
clip->num_boxes = 1;
} else {
clip->boxes = _cairo_boxes_to_array (boxes, &clip->num_boxes, TRUE);
if (clip->boxes == NULL)
return _cairo_clip_set_all_clipped (clip);
}
_cairo_boxes_extents (boxes, &clip->extents);

View file

@ -66,6 +66,8 @@ struct _cairo_clip {
cairo_region_t *region;
cairo_bool_t is_region;
cairo_box_t embedded_box;
};
cairo_private cairo_clip_t *

View file

@ -139,7 +139,8 @@ _cairo_clip_destroy (cairo_clip_t *clip)
if (clip->path != NULL)
_cairo_clip_path_destroy (clip->path);
free (clip->boxes);
if (clip->boxes != &clip->embedded_box)
free (clip->boxes);
cairo_region_destroy (clip->region);
_freed_pool_put (&clip_pool, clip);
@ -159,9 +160,13 @@ _cairo_clip_copy (const cairo_clip_t *clip)
copy->path = _cairo_clip_path_reference (clip->path);
if (clip->num_boxes) {
copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (unlikely (copy->boxes == NULL))
return _cairo_clip_set_all_clipped (copy);
if (clip->num_boxes == 1) {
copy->boxes = &copy->embedded_box;
} else {
copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (unlikely (copy->boxes == NULL))
return _cairo_clip_set_all_clipped (copy);
}
memcpy (copy->boxes, clip->boxes,
clip->num_boxes * sizeof (cairo_box_t));
@ -189,9 +194,13 @@ _cairo_clip_copy_region (const cairo_clip_t *clip)
copy = _cairo_clip_create ();
copy->extents = clip->extents;
copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (unlikely (copy->boxes == NULL))
return _cairo_clip_set_all_clipped (copy);
if (clip->num_boxes == 1) {
copy->boxes = &copy->embedded_box;
} else {
copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (unlikely (copy->boxes == NULL))
return _cairo_clip_set_all_clipped (copy);
}
for (i = 0; i < clip->num_boxes; i++) {
copy->boxes[i].p1.x = _cairo_fixed_floor (clip->boxes[i].p1.x);
@ -397,9 +406,13 @@ _cairo_clip_copy_with_translation (const cairo_clip_t *clip, int tx, int ty)
fy = _cairo_fixed_from_int (ty);
if (clip->num_boxes) {
copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (unlikely (copy->boxes == NULL))
return _cairo_clip_set_all_clipped (copy);
if (clip->num_boxes == 1) {
copy->boxes = &copy->embedded_box;
} else {
copy->boxes = _cairo_malloc_ab (clip->num_boxes, sizeof (cairo_box_t));
if (unlikely (copy->boxes == NULL))
return _cairo_clip_set_all_clipped (copy);
}
for (i = 0; i < clip->num_boxes; i++) {
copy->boxes[i].p1.x = clip->boxes[i].p1.x + fx;