[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