[cairo-commit] 2 commits - src/cairo-rtree.c src/cairo-rtree-private.h src/cairo-xlib-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Mon Jul 27 11:35:28 PDT 2009
src/cairo-rtree-private.h | 1
src/cairo-rtree.c | 50 ++++++++++++++++++++++++++++++++++++++++++++--
src/cairo-xlib-surface.c | 6 +++++
3 files changed, 55 insertions(+), 2 deletions(-)
New commits:
commit cf15aed0c4e843e7297c5a1979ac0318f6df4947
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jul 27 19:18:21 2009 +0100
[xlib] Add a timely reminder to ensure that bugs are properly filed.
In a discussion on IRC, attention was drawn to a dubious comment in
_cairo_xlib_show_glyphs() - the precise details of which have passed
out of the collective memory.
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 647e61f..4bc244a 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -39,6 +39,12 @@
* Karl Tomlinson <karlt+ at karlt.net>, Mozilla Corporation
*/
+/* Heed well the words of Owen Taylor:
+ * "Any patch that works around a render bug, or claims to, without a
+ * specific reference to the bug filed in bugzilla.freedesktop.org will
+ * never pass approval."
+ */
+
#include "cairoint.h"
#include "cairo-xlib-private.h"
commit 2da01ed552d48808cdf3aa7798ddfb959d016f0f
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Jul 27 18:20:22 2009 +0100
[rtree] Merge the common unpin_and_evict_unused() routine
Having written the same method to prune glyphs from the rtree three times,
I thought wise to add the common method to the core routines.
diff --git a/src/cairo-rtree-private.h b/src/cairo-rtree-private.h
index 72dc8ce..33c6bc8 100644
--- a/src/cairo-rtree-private.h
+++ b/src/cairo-rtree-private.h
@@ -51,6 +51,7 @@ enum {
typedef struct _cairo_rtree_node {
struct _cairo_rtree_node *children[4], *parent;
+ void **owner;
cairo_list_t link;
uint16_t pinned;
uint16_t state;
diff --git a/src/cairo-rtree.c b/src/cairo-rtree.c
index c0dfe31..ba142b7 100644
--- a/src/cairo-rtree.c
+++ b/src/cairo-rtree.c
@@ -56,6 +56,7 @@ _cairo_rtree_node_create (cairo_rtree_t *rtree,
node->children[0] = NULL;
node->parent = parent;
+ node->owner = NULL;
node->state = CAIRO_RTREE_NODE_AVAILABLE;
node->pinned = FALSE;
node->x = x;
@@ -76,6 +77,8 @@ _cairo_rtree_node_destroy (cairo_rtree_t *rtree, cairo_rtree_node_t *node)
cairo_list_del (&node->link);
if (node->state == CAIRO_RTREE_NODE_OCCUPIED) {
+ if (node->owner != NULL)
+ *node->owner = NULL;
if (rtree->evict != NULL)
rtree->evict (node);
} else {
@@ -235,6 +238,8 @@ _cairo_rtree_evict_random (cairo_rtree_t *rtree,
{
if (node->width >= width && node->height >= height && cnt-- == 0) {
if (node->state == CAIRO_RTREE_NODE_OCCUPIED) {
+ if (node->owner != NULL)
+ *node->owner = NULL;
if (rtree->evict != NULL)
rtree->evict (node);
} else {
@@ -274,12 +279,49 @@ void
_cairo_rtree_unpin (cairo_rtree_t *rtree)
{
cairo_rtree_node_t *node, *next;
+ cairo_list_t can_collapse;
+
+ if (cairo_list_is_empty (&rtree->pinned))
+ return;
+
+ cairo_list_init (&can_collapse);
cairo_list_foreach_entry_safe (node, next,
- cairo_rtree_node_t, &rtree->pinned, link)
+ cairo_rtree_node_t,
+ &rtree->pinned,
+ link)
{
node->pinned = FALSE;
- cairo_list_move (&node->link, &rtree->evictable);
+ if (node->state == CAIRO_RTREE_NODE_OCCUPIED && node->owner == NULL) {
+ cairo_bool_t all_available;
+ int i;
+
+ node->state = CAIRO_RTREE_NODE_AVAILABLE;
+ cairo_list_move (&node->link, &rtree->available);
+
+ all_available = TRUE;
+ node = node->parent;
+ for (i = 0; i < 4 && node->children[i] != NULL && all_available; i++)
+ all_available &= node->children[i]->state == CAIRO_RTREE_NODE_AVAILABLE;
+
+ if (all_available) {
+ cairo_list_move (&node->link, &can_collapse);
+ for (i = 0; i < 4 && node->children[i] != NULL; i++)
+ cairo_list_del (&node->children[i]->link);
+ }
+ }
+ else
+ {
+ cairo_list_move (&node->link, &rtree->evictable);
+ }
+ }
+
+ cairo_list_foreach_entry_safe (node, next,
+ cairo_rtree_node_t,
+ &can_collapse,
+ link)
+ {
+ _cairo_rtree_node_collapse (rtree, node);
}
}
@@ -315,6 +357,8 @@ _cairo_rtree_reset (cairo_rtree_t *rtree)
int i;
if (rtree->root.state == CAIRO_RTREE_NODE_OCCUPIED) {
+ if (rtree->root.owner != NULL)
+ *rtree->root.owner = NULL;
if (rtree->evict != NULL)
rtree->evict (&rtree->root);
} else {
@@ -338,6 +382,8 @@ _cairo_rtree_fini (cairo_rtree_t *rtree)
int i;
if (rtree->root.state == CAIRO_RTREE_NODE_OCCUPIED) {
+ if (rtree->root.owner != NULL)
+ *rtree->root.owner = NULL;
if (rtree->evict != NULL)
rtree->evict (&rtree->root);
} else {
More information about the cairo-commit
mailing list