[cairo-surface] Avoid allocation for common case of 1 box.

_cairo_surface_fill_region(): avoid allocating the array of boxes if we
know that the region only contains one box and is therefore defined by its
extents.
This commit is contained in:
Chris Wilson 2007-11-03 10:41:55 +00:00
parent e60a7c39cd
commit 92a18464ba

View file

@ -1285,41 +1285,49 @@ _cairo_surface_fill_region (cairo_surface_t *surface,
cairo_region_t *region)
{
int num_boxes;
cairo_box_int_t *boxes;
cairo_box_int_t *boxes = NULL;
cairo_rectangle_int_t stack_rects[CAIRO_STACK_BUFFER_SIZE / sizeof (cairo_rectangle_int_t)];
cairo_rectangle_int_t *rects;
cairo_rectangle_int_t *rects = stack_rects;
cairo_status_t status;
int i;
assert (! surface->is_snapshot);
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
if (status)
return status;
num_boxes = _cairo_region_num_boxes (region);
if (num_boxes == 0)
return CAIRO_STATUS_SUCCESS;
rects = stack_rects;
if (num_boxes > ARRAY_LENGTH (stack_rects)) {
rects = _cairo_malloc_ab (num_boxes, sizeof (cairo_rectangle_int_t));
if (!rects) {
_cairo_region_boxes_fini (region, boxes);
return _cairo_surface_set_error (surface, CAIRO_STATUS_NO_MEMORY);
}
}
/* handle the common case of a single box without allocation */
if (num_boxes > 1) {
status = _cairo_region_get_boxes (region, &num_boxes, &boxes);
if (status)
return status;
for (i = 0; i < num_boxes; i++) {
rects[i].x = boxes[i].p1.x;
rects[i].y = boxes[i].p1.y;
rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
}
if (num_boxes > ARRAY_LENGTH (stack_rects)) {
rects = _cairo_malloc_ab (num_boxes,
sizeof (cairo_rectangle_int_t));
if (!rects) {
_cairo_region_boxes_fini (region, boxes);
return _cairo_surface_set_error (surface,
CAIRO_STATUS_NO_MEMORY);
}
}
for (i = 0; i < num_boxes; i++) {
rects[i].x = boxes[i].p1.x;
rects[i].y = boxes[i].p1.y;
rects[i].width = boxes[i].p2.x - boxes[i].p1.x;
rects[i].height = boxes[i].p2.y - boxes[i].p1.y;
}
} else
_cairo_region_get_extents (region, &rects[0]);
status = _cairo_surface_fill_rectangles (surface, op,
color, rects, num_boxes);
_cairo_region_boxes_fini (region, boxes);
if (boxes != NULL)
_cairo_region_boxes_fini (region, boxes);
if (rects != stack_rects)
free (rects);