[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