[cairo-commit] 6 commits - src/cairo-bentley-ottmann.c src/cairo-hash.c src/cairo-mono-scan-converter.c src/cairo-path-stroke-polygon.c src/skia

Chris Wilson ickle at kemper.freedesktop.org
Sat Mar 10 02:48:00 PST 2012


 src/cairo-bentley-ottmann.c     |   11 +++++++++++
 src/cairo-hash.c                |   26 ++++++++++++++++++++------
 src/cairo-mono-scan-converter.c |   12 +++++++-----
 src/cairo-path-stroke-polygon.c |   30 +++++++++++++++++++-----------
 src/skia/cairo-skia-surface.cpp |    1 +
 5 files changed, 58 insertions(+), 22 deletions(-)

New commits:
commit ab0e224b999c005c0d59b887188fddf34189a74a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Sat Mar 10 10:46:39 2012 +0000

    skia: compile fix
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/skia/cairo-skia-surface.cpp b/src/skia/cairo-skia-surface.cpp
index de94f3a..71bebb0 100644
--- a/src/skia/cairo-skia-surface.cpp
+++ b/src/skia/cairo-skia-surface.cpp
@@ -175,6 +175,7 @@ cairo_skia_surface_backend = {
     _cairo_skia_surface_map_to_image,
     _cairo_skia_surface_unmap_image,
 
+    _cairo_surface_default_source,
     _cairo_skia_surface_acquire_source_image,
     _cairo_skia_surface_release_source_image,
     NULL, /* snapshot */
commit f7d4653c1b945c93d394541e5c32397c90c2c139
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 9 14:06:58 2012 +0000

    stroke: Do not initialise the pen if will not use it
    
    The pen is only used for ensuring that we generate consist vertices
    around a fan used for end-capping or line-joining when set to ROUND.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-path-stroke-polygon.c b/src/cairo-path-stroke-polygon.c
index 5d121fa..7978af0 100644
--- a/src/cairo-path-stroke-polygon.c
+++ b/src/cairo-path-stroke-polygon.c
@@ -163,6 +163,8 @@ add_fan (struct stroker *stroker,
 {
     int start, stop, step, i, npoints;
 
+    assert (stroker->pen.num_vertices);
+
     if (clockwise) {
 	step  = 1;
 
@@ -1357,16 +1359,21 @@ _cairo_path_fixed_stroke_to_polygon (const cairo_path_fixed_t	*path,
     stroker.ctm_det_positive =
 	_cairo_matrix_compute_determinant (ctm) >= 0.0;
 
-    status = _cairo_pen_init (&stroker.pen,
-		              style->line_width / 2.0,
-			      tolerance, ctm);
-    if (unlikely (status))
-	return status;
-
-    /* If the line width is so small that the pen is reduced to a
-       single point, then we have nothing to do. */
-    if (stroker.pen.num_vertices <= 1)
-	return CAIRO_STATUS_SUCCESS;
+    stroker.pen.num_vertices = 0;
+    if (path->has_curve_to ||
+	style->line_join == CAIRO_LINE_JOIN_ROUND ||
+	style->line_cap == CAIRO_LINE_CAP_ROUND) {
+	status = _cairo_pen_init (&stroker.pen,
+				  style->line_width / 2.0,
+				  tolerance, ctm);
+	if (unlikely (status))
+	    return status;
+
+	/* If the line width is so small that the pen is reduced to a
+	   single point, then we have nothing to do. */
+	if (stroker.pen.num_vertices <= 1)
+	    return CAIRO_STATUS_SUCCESS;
+    }
 
     stroker.has_current_face = FALSE;
     stroker.has_first_face = FALSE;
@@ -1396,7 +1403,8 @@ _cairo_path_fixed_stroke_to_polygon (const cairo_path_fixed_t	*path,
 
     _cairo_contour_fini (&stroker.cw.contour);
     _cairo_contour_fini (&stroker.ccw.contour);
-    _cairo_pen_fini (&stroker.pen);
+    if (stroker.pen.num_vertices)
+	_cairo_pen_fini (&stroker.pen);
 
 #if DEBUG
     {
commit 5ff689c01771165d26cc272d65e01dfb1a1fd57e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 9 14:06:06 2012 +0000

    mono-scan-converter: Use edge->is_vertical flag
    
    The earlier bug found in edge advancement was actually due to the missed
    opportunity of not performing the increment when we know the step is
    zero.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-mono-scan-converter.c b/src/cairo-mono-scan-converter.c
index 29d5475..2a9546c 100644
--- a/src/cairo-mono-scan-converter.c
+++ b/src/cairo-mono-scan-converter.c
@@ -337,11 +337,13 @@ row (struct mono_scan_converter *c, unsigned int mask)
 	int xend = I(edge->x.quo);
 
 	if (--edge->height_left) {
-	    edge->x.quo += edge->dxdy.quo;
-	    edge->x.rem += edge->dxdy.rem;
-	    if (edge->x.rem >= 0) {
-		++edge->x.quo;
-		edge->x.rem -= edge->dy;
+	    if (!edge->vertical) {
+		edge->x.quo += edge->dxdy.quo;
+		edge->x.rem += edge->dxdy.rem;
+		if (edge->x.rem >= 0) {
+		    ++edge->x.quo;
+		    edge->x.rem -= edge->dy;
+		}
 	    }
 
 	    if (edge->x.quo < prev_x) {
commit 07b540fd35d7312bbfb362f22dac20f57f6900e6
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 9 00:14:48 2012 +0000

    bentley-ottmann: Sort by edge bounding boxes before computing x
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index 866358f..a075b40 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -570,6 +570,13 @@ _cairo_bo_sweep_line_compare_edges (cairo_bo_sweep_line_t	*sweep_line,
 
     /* compare the edges if not identical */
     if (! _line_equal (&a->edge.line, &b->edge.line)) {
+	if (MAX (a->edge.line.p1.x, a->edge.line.p2.x) <
+	    MIN (b->edge.line.p1.x, b->edge.line.p2.x))
+	    return -1;
+	else if (MIN (a->edge.line.p1.x, a->edge.line.p2.x) >
+		 MAX (b->edge.line.p1.x, b->edge.line.p2.x))
+	    return 1;
+
 	cmp = edges_compare_x_for_y (a, b, sweep_line->current_y);
 	if (cmp)
 	    return cmp;
commit 247c42357c2aaccfbcccd0656b22fc73c0303194
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Mar 9 00:01:21 2012 +0000

    bentley-ottmann: Skip intersection check if the bounds do not overlap
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-bentley-ottmann.c b/src/cairo-bentley-ottmann.c
index f30449e..866358f 100644
--- a/src/cairo-bentley-ottmann.c
+++ b/src/cairo-bentley-ottmann.c
@@ -1078,6 +1078,10 @@ _cairo_bo_event_queue_insert_if_intersect_below_current_y (cairo_bo_event_queue_
 {
     cairo_bo_point32_t intersection;
 
+    if (MAX (left->edge.line.p1.x, left->edge.line.p2.x) <=
+	MIN (right->edge.line.p1.x, right->edge.line.p2.x))
+	return CAIRO_STATUS_SUCCESS;
+
     if (_line_equal (&left->edge.line, &right->edge.line))
 	return CAIRO_STATUS_SUCCESS;
 
commit 2ab171467be53f190239e8cee083b2687ca66025
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Thu Mar 8 20:30:45 2012 +0000

    hash: Keep a simple lut in front of the main hash
    
    Whilst we wait for IvyBridge with its fast integer divide, in the
    meantime avoid the overhead by inspecting a smaller simpler cache before
    doing the full hash table lookup.
    
    Shaves around 10% off glyph microbenchmarks for -image.
    
    Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>

diff --git a/src/cairo-hash.c b/src/cairo-hash.c
index f4fb7cd..928c74b 100644
--- a/src/cairo-hash.c
+++ b/src/cairo-hash.c
@@ -111,6 +111,8 @@ static const unsigned long hash_table_sizes[] = {
 struct _cairo_hash_table {
     cairo_hash_keys_equal_func_t keys_equal;
 
+    cairo_hash_entry_t *cache[32];
+
     const unsigned long *table_size;
     cairo_hash_entry_t **entries;
 
@@ -173,6 +175,7 @@ _cairo_hash_table_create (cairo_hash_keys_equal_func_t keys_equal)
     else
 	hash_table->keys_equal = keys_equal;
 
+    memset (&hash_table->cache, 0, sizeof (hash_table->cache));
     hash_table->table_size = &hash_table_sizes[0];
 
     hash_table->entries = calloc (*hash_table->table_size,
@@ -337,19 +340,24 @@ _cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
 {
     cairo_hash_entry_t *entry;
     unsigned long table_size, i, idx, step;
+    unsigned long hash = key->hash;
+
+    entry = hash_table->cache[hash & 31];
+    if (entry && entry->hash == hash && hash_table->keys_equal (key, entry))
+	return entry;
 
     table_size = *hash_table->table_size;
-    idx = key->hash % table_size;
+    idx = hash % table_size;
 
     entry = hash_table->entries[idx];
     if (ENTRY_IS_LIVE (entry)) {
-	if (entry->hash == key->hash && hash_table->keys_equal (key, entry))
-	    return entry;
+	if (entry->hash == hash && hash_table->keys_equal (key, entry))
+		goto insert_cache;
     } else if (ENTRY_IS_FREE (entry))
 	return NULL;
 
     i = 1;
-    step = 1 + key->hash % (table_size - 2);
+    step = 1 + hash % (table_size - 2);
     do {
 	idx += step;
 	if (idx >= table_size)
@@ -357,14 +365,18 @@ _cairo_hash_table_lookup (cairo_hash_table_t *hash_table,
 
 	entry = hash_table->entries[idx];
 	if (ENTRY_IS_LIVE (entry)) {
-	    if (entry->hash == key->hash && hash_table->keys_equal (key, entry))
-		return entry;
+	    if (entry->hash == hash && hash_table->keys_equal (key, entry))
+		    goto insert_cache;
 	} else if (ENTRY_IS_FREE (entry))
 	    return NULL;
     } while (++i < table_size);
 
     ASSERT_NOT_REACHED;
     return NULL;
+
+insert_cache:
+    hash_table->cache[hash & 31] = entry;
+    return entry;
 }
 
 /**
@@ -459,6 +471,7 @@ _cairo_hash_table_insert (cairo_hash_table_t *hash_table,
 	hash_table->free_entries--;
 
     *entry = key_and_value;
+    hash_table->cache[key_and_value->hash & 31] = key_and_value;
     hash_table->live_entries++;
 
     return CAIRO_STATUS_SUCCESS;
@@ -509,6 +522,7 @@ _cairo_hash_table_remove (cairo_hash_table_t *hash_table,
 {
     *_cairo_hash_table_lookup_exact_key (hash_table, key) = DEAD_ENTRY;
     hash_table->live_entries--;
+    hash_table->cache[key->hash & 31] = NULL;
 
     /* Check for table resize. Don't do this when iterating as this will
      * reorder elements of the table and cause the iteration to potentially


More information about the cairo-commit mailing list