[skiplist] Provide an initial stack allocated pool.

Since we only need to allocate elts for intersection events and edges, the
number of elts in flight at any one time is actually quite small and can
usually be accommodated from an embedded pool.
This commit is contained in:
Chris Wilson 2008-12-17 20:47:09 +00:00
parent dd4276c661
commit 5e6d25e204
3 changed files with 21 additions and 34 deletions

View file

@ -968,12 +968,6 @@ _cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue,
unsigned num_events = 2*num_edges;
cairo_status_t status;
status = _cairo_skip_list_init (&event_queue->intersection_queue,
cairo_bo_event_compare_abstract,
sizeof (cairo_bo_event_t));
if (unlikely (status))
return status;
/* The skip_elt_t field of a cairo_bo_event_t isn't used for start
* or stop events, so this allocation is safe. XXX: make the
* event type a union so it doesn't always contain the skip
@ -982,10 +976,8 @@ _cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue,
sizeof (cairo_bo_event_t) +
sizeof (cairo_bo_event_t *),
sizeof (cairo_bo_event_t *));
if (unlikely (events == NULL)) {
_cairo_skip_list_fini (&event_queue->intersection_queue);
if (unlikely (events == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
}
sorted_event_ptrs = (cairo_bo_event_t **) (events + num_events);
event_queue->startstop_events = events;
@ -1012,6 +1004,10 @@ _cairo_bo_event_queue_init (cairo_bo_event_queue_t *event_queue,
_cairo_bo_event_queue_sort (sorted_event_ptrs, num_events);
event_queue->sorted_startstop_event_ptrs[num_events] = NULL;
_cairo_skip_list_init (&event_queue->intersection_queue,
cairo_bo_event_compare_abstract,
sizeof (cairo_bo_event_t));
return CAIRO_STATUS_SUCCESS;
}
@ -1058,22 +1054,16 @@ _cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_
return _cairo_bo_event_queue_insert (event_queue, &event);
}
static cairo_status_t
static void
_cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line)
{
cairo_status_t status;
status = _cairo_skip_list_init (&sweep_line->active_edges,
_sweep_line_elt_compare,
sizeof (sweep_line_elt_t));
if (unlikely (status))
return status;
_cairo_skip_list_init (&sweep_line->active_edges,
_sweep_line_elt_compare,
sizeof (sweep_line_elt_t));
sweep_line->head = NULL;
sweep_line->tail = NULL;
sweep_line->current_y = 0;
return CAIRO_STATUS_SUCCESS;
}
static void
@ -1508,9 +1498,7 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_edge_t *edges,
if (status)
return status;
status = _cairo_bo_sweep_line_init (&sweep_line);
if (unlikely (status))
goto CLEANUP_EVENT_QUEUE;
_cairo_bo_sweep_line_init (&sweep_line);
_cairo_bo_traps_init (&bo_traps, traps, xmin, ymin, xmax, ymax);
@ -1637,7 +1625,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_edge_t *edges,
}
_cairo_bo_traps_fini (&bo_traps);
_cairo_bo_sweep_line_fini (&sweep_line);
CLEANUP_EVENT_QUEUE:
_cairo_bo_event_queue_fini (&event_queue);
return status;
}

View file

@ -70,8 +70,9 @@ typedef struct _skip_list {
size_t data_size;
skip_elt_t *chains[MAX_LEVEL];
skip_elt_t *freelists[MAX_FREELIST_LEVEL];
struct pool *pool;
int max_level;
struct pool *pool;
char pool_embedded[1024];
} cairo_skip_list_t;
/* Initialize a new skip list. The compare function accepts a pointer
@ -82,10 +83,10 @@ typedef struct _skip_list {
* sizeof) is passed for elt_size. Note that the structure used for
* list elements must have as its final member a skip_elt_t
*/
cairo_private cairo_status_t
cairo_private void
_cairo_skip_list_init (cairo_skip_list_t *list,
cairo_skip_list_compare_t compare,
size_t elt_size);
cairo_skip_list_compare_t compare,
size_t elt_size);
/* Deallocate resources associated with a skip list and all elements

View file

@ -63,7 +63,7 @@ pool_new (void)
static void
pools_destroy (struct pool *pool)
{
while (pool != NULL) {
while (pool->next != NULL) {
struct pool *next = pool->next;
free (pool);
pool = next;
@ -73,7 +73,7 @@ pools_destroy (struct pool *pool)
/*
* Initialize an empty skip list
*/
cairo_status_t
void
_cairo_skip_list_init (cairo_skip_list_t *list,
cairo_skip_list_compare_t compare,
size_t elt_size)
@ -83,9 +83,10 @@ _cairo_skip_list_init (cairo_skip_list_t *list,
list->compare = compare;
list->elt_size = elt_size;
list->data_size = elt_size - sizeof (skip_elt_t);
list->pool = pool_new ();
if (unlikely (list->pool == NULL))
return _cairo_error (CAIRO_STATUS_NO_MEMORY);
list->pool = (struct pool *) list->pool_embedded;
list->pool->next = NULL;
list->pool->rem = sizeof (list->pool_embedded) - sizeof (struct pool);
list->pool->ptr = list->pool_embedded + sizeof (struct pool);
for (i = 0; i < MAX_LEVEL; i++) {
list->chains[i] = NULL;
@ -96,8 +97,6 @@ _cairo_skip_list_init (cairo_skip_list_t *list,
}
list->max_level = 0;
return CAIRO_STATUS_SUCCESS;
}
void