wok rev 13173

cairo: Forgot patch.
author Christopher Rogers <slaxemulator@gmail.com>
date Mon Jul 30 04:43:16 2012 +0000 (2012-07-30)
parents d8228805d4f0
children 27727d07d680
files cairo/stuff/cairo-1.12.2-reduce-broken-stopped-edge-continuation.patch
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/cairo/stuff/cairo-1.12.2-reduce-broken-stopped-edge-continuation.patch	Mon Jul 30 04:43:16 2012 +0000
     1.3 @@ -0,0 +1,275 @@
     1.4 +From f228769dfe5a8b5d73c49a41e95e31ed73a77fb3 Mon Sep 17 00:00:00 2001
     1.5 +From: Chris Wilson <chris@chris-wilson.co.uk>
     1.6 +Date: Fri, 08 Jun 2012 16:22:41 +0000
     1.7 +Subject: polygon-reduce: Reduce broken stopped-edge continuation
     1.8 +
     1.9 +This is hopefully a lesser used path and the attempted optimisation to
    1.10 +continue a stopped edge with a colinear stopped edge highly unlikely and
    1.11 +lost in the noise of the general inefficiency of the routine. As it was
    1.12 +broken, rather than attempt to rectify the "optimisation" remove it.
    1.13 +
    1.14 +Reported-by: Evangelos Foutras <evangelos@foutrelis.com>
    1.15 +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=50852
    1.16 +Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
    1.17 +---
    1.18 +diff --git a/src/cairo-polygon-reduce.c b/src/cairo-polygon-reduce.c
    1.19 +index 8758070..ea457fe 100644
    1.20 +--- a/src/cairo-polygon-reduce.c
    1.21 ++++ b/src/cairo-polygon-reduce.c
    1.22 +@@ -42,6 +42,8 @@
    1.23 + #include "cairo-freelist-private.h"
    1.24 + #include "cairo-combsort-inline.h"
    1.25 +
    1.26 ++#define DEBUG_POLYGON 0
    1.27 ++
    1.28 + typedef cairo_point_t cairo_bo_point32_t;
    1.29 +
    1.30 + typedef struct _cairo_bo_intersect_ordinate {
    1.31 +@@ -114,7 +116,6 @@ typedef struct _cairo_bo_event_queue {
    1.32 +
    1.33 + typedef struct _cairo_bo_sweep_line {
    1.34 +     cairo_bo_edge_t *head;
    1.35 +-    cairo_bo_edge_t *stopped;
    1.36 +     int32_t current_y;
    1.37 +     cairo_bo_edge_t *current_edge;
    1.38 + } cairo_bo_sweep_line_t;
    1.39 +@@ -476,8 +477,8 @@ edges_compare_x_for_y (const cairo_bo_edge_t *a,
    1.40 + static inline int
    1.41 + _line_equal (const cairo_line_t *a, const cairo_line_t *b)
    1.42 + {
    1.43 +-    return a->p1.x == b->p1.x && a->p1.y == b->p1.y &&
    1.44 +-           a->p2.x == b->p2.x && a->p2.y == b->p2.y;
    1.45 ++    return (a->p1.x == b->p1.x && a->p1.y == b->p1.y &&
    1.46 ++	    a->p2.x == b->p2.x && a->p2.y == b->p2.y);
    1.47 + }
    1.48 +
    1.49 + static int
    1.50 +@@ -1024,7 +1025,6 @@ static void
    1.51 + _cairo_bo_sweep_line_init (cairo_bo_sweep_line_t *sweep_line)
    1.52 + {
    1.53 +     sweep_line->head = NULL;
    1.54 +-    sweep_line->stopped = NULL;
    1.55 +     sweep_line->current_y = INT32_MIN;
    1.56 +     sweep_line->current_edge = NULL;
    1.57 + }
    1.58 +@@ -1139,6 +1139,8 @@ edges_colinear (const cairo_bo_edge_t *a, const cairo_bo_edge_t *b)
    1.59 +      */
    1.60 +     if (a->edge.line.p1.y == b->edge.line.p1.y) {
    1.61 +	return a->edge.line.p1.x == b->edge.line.p1.x;
    1.62 ++    } else if (a->edge.line.p2.y == b->edge.line.p2.y) {
    1.63 ++	return a->edge.line.p2.x == b->edge.line.p2.x;
    1.64 +     } else if (a->edge.line.p1.y < b->edge.line.p1.y) {
    1.65 +	return edge_compare_for_y_against_x (b,
    1.66 +					     a->edge.line.p1.y,
    1.67 +@@ -1205,82 +1207,48 @@ _active_edges_to_polygon (cairo_bo_edge_t		*left,
    1.68 +			  cairo_polygon_t	        *polygon)
    1.69 + {
    1.70 +     cairo_bo_edge_t *right;
    1.71 ++    unsigned int mask;
    1.72 +
    1.73 +-    if (fill_rule == CAIRO_FILL_RULE_WINDING) {
    1.74 +-	while (left != NULL) {
    1.75 +-	    int in_out = left->edge.dir;
    1.76 +-
    1.77 +-	    right = left->next;
    1.78 +-	    if (left->deferred.right == NULL) {
    1.79 +-		while (right != NULL && right->deferred.right == NULL)
    1.80 +-		    right = right->next;
    1.81 +-
    1.82 +-		if (right != NULL && edges_colinear (left, right)) {
    1.83 +-		    /* continuation on left */
    1.84 +-		    left->deferred = right->deferred;
    1.85 +-		    right->deferred.right = NULL;
    1.86 +-		}
    1.87 +-	    }
    1.88 +-
    1.89 +-	    right = left->next;
    1.90 +-	    while (right != NULL) {
    1.91 +-		if (right->deferred.right != NULL)
    1.92 +-		    _cairo_bo_edge_end (right, top, polygon);
    1.93 +-
    1.94 +-		in_out += right->edge.dir;
    1.95 +-		if (in_out == 0) {
    1.96 +-		    cairo_bo_edge_t *next;
    1.97 +-		    cairo_bool_t skip = FALSE;
    1.98 +-
    1.99 +-		    /* skip co-linear edges */
   1.100 +-		    next = right->next;
   1.101 +-		    if (next != NULL)
   1.102 +-			skip = edges_colinear (right, next);
   1.103 ++    if (fill_rule == CAIRO_FILL_RULE_WINDING)
   1.104 ++	mask = ~0;
   1.105 ++    else
   1.106 ++	mask = 1;
   1.107 +
   1.108 +-		    if (! skip)
   1.109 +-			break;
   1.110 +-		}
   1.111 ++    while (left != NULL) {
   1.112 ++	int in_out = left->edge.dir;
   1.113 +
   1.114 ++	right = left->next;
   1.115 ++	if (left->deferred.right == NULL) {
   1.116 ++	    while (right != NULL && right->deferred.right == NULL)
   1.117 +		right = right->next;
   1.118 +-	    }
   1.119 +-
   1.120 +-	    _cairo_bo_edge_start_or_continue (left, right, top, polygon);
   1.121 +
   1.122 +-	    left = right;
   1.123 +-	    if (left != NULL)
   1.124 +-		left = left->next;
   1.125 ++	    if (right != NULL && edges_colinear (left, right)) {
   1.126 ++		/* continuation on left */
   1.127 ++		left->deferred = right->deferred;
   1.128 ++		right->deferred.right = NULL;
   1.129 ++	    }
   1.130 +	}
   1.131 +-    } else {
   1.132 +-	while (left != NULL) {
   1.133 +-	    int in_out = 0;
   1.134 +
   1.135 +-	    right = left->next;
   1.136 +-	    while (right != NULL) {
   1.137 +-		if (right->deferred.right != NULL)
   1.138 +-		    _cairo_bo_edge_end (right, top, polygon);
   1.139 ++	right = left->next;
   1.140 ++	while (right != NULL) {
   1.141 ++	    if (right->deferred.right != NULL)
   1.142 ++		_cairo_bo_edge_end (right, top, polygon);
   1.143 +
   1.144 +-		if ((in_out++ & 1) == 0) {
   1.145 +-		    cairo_bo_edge_t *next;
   1.146 +-		    cairo_bool_t skip = FALSE;
   1.147 +-
   1.148 +-		    /* skip co-linear edges */
   1.149 +-		    next = right->next;
   1.150 +-		    if (next != NULL)
   1.151 +-			skip = edges_colinear (right, next);
   1.152 +-
   1.153 +-		    if (! skip)
   1.154 +-			break;
   1.155 +-		}
   1.156 +-
   1.157 +-		right = right->next;
   1.158 ++	    in_out += right->edge.dir;
   1.159 ++	    if ((in_out & mask) == 0) {
   1.160 ++		/* skip co-linear edges */
   1.161 ++		if (right->next == NULL || !edges_colinear (right, right->next))
   1.162 ++		    break;
   1.163 +	    }
   1.164 +
   1.165 +-	    _cairo_bo_edge_start_or_continue (left, right, top, polygon);
   1.166 +-
   1.167 +-	    left = right;
   1.168 +-	    if (left != NULL)
   1.169 +-		left = left->next;
   1.170 ++	    right = right->next;
   1.171 +	}
   1.172 ++
   1.173 ++	_cairo_bo_edge_start_or_continue (left, right, top, polygon);
   1.174 ++
   1.175 ++	left = right;
   1.176 ++	if (left != NULL)
   1.177 ++	    left = left->next;
   1.178 +     }
   1.179 + }
   1.180 +
   1.181 +@@ -1303,12 +1271,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t   **start_events,
   1.182 +
   1.183 +     while ((event = _cairo_bo_event_dequeue (&event_queue))) {
   1.184 +	if (event->point.y != sweep_line.current_y) {
   1.185 +-	    for (e1 = sweep_line.stopped; e1; e1 = e1->next) {
   1.186 +-		if (e1->deferred.right != NULL)
   1.187 +-		     _cairo_bo_edge_end (e1, e1->edge.bottom, polygon);
   1.188 +-	    }
   1.189 +-	    sweep_line.stopped = NULL;
   1.190 +-
   1.191 +	    _active_edges_to_polygon (sweep_line.head,
   1.192 +				      sweep_line.current_y,
   1.193 +				      fill_rule, polygon);
   1.194 +@@ -1328,23 +1290,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t   **start_events,
   1.195 +	    if (unlikely (status))
   1.196 +		goto unwind;
   1.197 +
   1.198 +-	    /* check to see if this is a continuation of a stopped edge */
   1.199 +-	    /* XXX change to an infinitesimal lengthening rule */
   1.200 +-	    for (left = sweep_line.stopped; left; left = left->next) {
   1.201 +-		if (e1->edge.top <= left->edge.bottom &&
   1.202 +-		    edges_colinear (e1, left))
   1.203 +-		{
   1.204 +-		    e1->deferred = left->deferred;
   1.205 +-		    if (left->prev != NULL)
   1.206 +-			left->prev = left->next;
   1.207 +-		    else
   1.208 +-			sweep_line.stopped = left->next;
   1.209 +-		    if (left->next != NULL)
   1.210 +-			left->next->prev = left->prev;
   1.211 +-		    break;
   1.212 +-		}
   1.213 +-	    }
   1.214 +-
   1.215 +	    left = e1->prev;
   1.216 +	    right = e1->next;
   1.217 +
   1.218 +@@ -1371,14 +1316,8 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t   **start_events,
   1.219 +
   1.220 +	    _cairo_bo_sweep_line_delete (&sweep_line, e1);
   1.221 +
   1.222 +-	    /* first, check to see if we have a continuation via a fresh edge */
   1.223 +-	    if (e1->deferred.right != NULL) {
   1.224 +-		e1->next = sweep_line.stopped;
   1.225 +-		if (sweep_line.stopped != NULL)
   1.226 +-		    sweep_line.stopped->prev = e1;
   1.227 +-		sweep_line.stopped = e1;
   1.228 +-		e1->prev = NULL;
   1.229 +-	    }
   1.230 ++	    if (e1->deferred.right != NULL)
   1.231 ++		_cairo_bo_edge_end (e1, e1->edge.bottom, polygon);
   1.232 +
   1.233 +	    if (left != NULL && right != NULL) {
   1.234 +		status = _cairo_bo_event_queue_insert_if_intersect_below_current_y (&event_queue, left, right);
   1.235 +@@ -1420,10 +1359,6 @@ _cairo_bentley_ottmann_tessellate_bo_edges (cairo_bo_event_t   **start_events,
   1.236 +	}
   1.237 +     }
   1.238 +
   1.239 +-    for (e1 = sweep_line.stopped; e1; e1 = e1->next) {
   1.240 +-	if (e1->deferred.right != NULL)
   1.241 +-	    _cairo_bo_edge_end (e1, e1->edge.bottom, polygon);
   1.242 +-    }
   1.243 +  unwind:
   1.244 +     _cairo_bo_event_queue_fini (&event_queue);
   1.245 +
   1.246 +@@ -1447,6 +1382,12 @@ _cairo_polygon_reduce (cairo_polygon_t *polygon,
   1.247 +     if (unlikely (0 == num_events))
   1.248 +	return CAIRO_STATUS_SUCCESS;
   1.249 +
   1.250 ++    if (DEBUG_POLYGON) {
   1.251 ++	FILE *file = fopen ("reduce_in.txt", "w");
   1.252 ++	_cairo_debug_print_polygon (file, polygon);
   1.253 ++	fclose (file);
   1.254 ++    }
   1.255 ++
   1.256 +     events = stack_events;
   1.257 +     event_ptrs = stack_event_ptrs;
   1.258 +     if (num_events > ARRAY_LENGTH (stack_events)) {
   1.259 +@@ -1482,10 +1423,16 @@ _cairo_polygon_reduce (cairo_polygon_t *polygon,
   1.260 +							 num_events,
   1.261 +							 fill_rule,
   1.262 +							 polygon);
   1.263 +-     polygon->num_limits = num_limits;
   1.264 ++    polygon->num_limits = num_limits;
   1.265 +
   1.266 +     if (events != stack_events)
   1.267 +	free (events);
   1.268 +
   1.269 ++    if (DEBUG_POLYGON) {
   1.270 ++	FILE *file = fopen ("reduce_out.txt", "w");
   1.271 ++	_cairo_debug_print_polygon (file, polygon);
   1.272 ++	fclose (file);
   1.273 ++    }
   1.274 ++
   1.275 +     return status;
   1.276 + }
   1.277 +--
   1.278 +cgit v0.9.0.2-2-gbebe