diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-04-03 15:30:18 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-05-12 20:54:49 +0100 |
commit | 2a0726337368462046ef84d9be4cf59734b39806 (patch) | |
tree | 7aacbcf2a7b535fbb71c0bf57e7e37657f940694 /src/cairo-rtree.c | |
parent | cbe8fd0794adaccdf3eb15eef780a030e3d51784 (diff) | |
download | cairo-2a0726337368462046ef84d9be4cf59734b39806.tar.gz |
rtree: defer propagating pinned nodes until eviction.
Only during infrequent eviction do we require absolute knowledge of
which graph of nodes are in use and thus pinned. So during the common
use of querying the glyph cache, we just mark the leaf as used. Then we
need to make space for a new glyph, we move the parents of the left
nodes from the evictable list to the pinned list.
Diffstat (limited to 'src/cairo-rtree.c')
-rw-r--r-- | src/cairo-rtree.c | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/src/cairo-rtree.c b/src/cairo-rtree.c index 7bba990fb..a26fa854d 100644 --- a/src/cairo-rtree.c +++ b/src/cairo-rtree.c @@ -108,9 +108,7 @@ _cairo_rtree_node_collapse (cairo_rtree_t *rtree, cairo_rtree_node_t *node) node->children[0] = NULL; node->state = CAIRO_RTREE_NODE_AVAILABLE; cairo_list_move (&node->link, &rtree->available); - - node = node->parent; - } while (node != NULL && ! node->pinned); + } while ((node = node->parent) != NULL); } cairo_status_t @@ -193,8 +191,7 @@ _cairo_rtree_node_remove (cairo_rtree_t *rtree, cairo_rtree_node_t *node) node->state = CAIRO_RTREE_NODE_AVAILABLE; cairo_list_move (&node->link, &rtree->available); - if (! node->parent->pinned) - _cairo_rtree_node_collapse (rtree, node->parent); + _cairo_rtree_node_collapse (rtree, node->parent); } cairo_int_status_t @@ -230,9 +227,17 @@ _cairo_rtree_evict_random (cairo_rtree_t *rtree, int height, cairo_rtree_node_t **out) { - cairo_rtree_node_t *node; + cairo_rtree_node_t *node, *next; int i, cnt; + /* propagate pinned from children to root */ + cairo_list_foreach_entry_safe (node, next, cairo_rtree_node_t, + &rtree->pinned, link) + { + if (node->parent != NULL) + _cairo_rtree_pin (rtree, node->parent); + } + cnt = 0; cairo_list_foreach_entry (node, cairo_rtree_node_t, &rtree->evictable, link) @@ -271,22 +276,6 @@ _cairo_rtree_evict_random (cairo_rtree_t *rtree, return CAIRO_INT_STATUS_UNSUPPORTED; } -void * -_cairo_rtree_pin (cairo_rtree_t *rtree, cairo_rtree_node_t *node) -{ - void *ptr = node; - - while (node->pinned == FALSE) { - cairo_list_move (&node->link, &rtree->pinned); - node->pinned = TRUE; - node = node->parent; - if (node == NULL) - break; - } - - return ptr; -} - void _cairo_rtree_unpin (cairo_rtree_t *rtree) { |