sna/trapezoids: filter out cancelling edges upon insertion to edge-list

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Chris Wilson 2013-01-05 18:07:50 +00:00
parent 2b4a2f52c4
commit d3be77f879
1 changed files with 65 additions and 4 deletions

View File

@ -800,6 +800,9 @@ merge_sorted_edges(struct edge *head_a, struct edge *head_b)
struct edge *head, **next, *prev;
int32_t x;
if (head_b == NULL)
return head_a;
prev = head_a->prev;
next = &head;
if (head_a->x.quo <= head_b->x.quo) {
@ -872,11 +875,39 @@ sort_edges(struct edge *list,
return remaining;
}
static struct edge *filter(struct edge *edges)
{
struct edge *e;
e = edges;
do {
struct edge *n = e->next;
if (e->dir == -n->dir &&
e->height_left == n->height_left &&
*(uint64_t *)&e->x == *(uint64_t *)&n->x &&
*(uint64_t *)&e->dxdy == *(uint64_t *)&n->dxdy) {
if (e->prev)
e->prev->next = n->next;
else
edges = n->next;
if (n->next)
n->next->prev = e->prev;
else
break;
e = n->next;
} else
e = e->next;
} while (e->next);
return edges;
}
static struct edge *
merge_unsorted_edges (struct edge *head, struct edge *unsorted)
{
sort_edges (unsorted, UINT_MAX, &unsorted);
return merge_sorted_edges (head, unsorted);
return merge_sorted_edges (head, filter(unsorted));
}
/* Test if the edges on the active list can be safely advanced by a
@ -884,11 +915,10 @@ merge_unsorted_edges (struct edge *head, struct edge *unsorted)
inline static bool
can_full_step(struct active_list *active)
{
const struct edge *e;
/* Recomputes the minimum height of all edges on the active
* list if we have been dropping edges. */
if (active->min_height <= 0) {
const struct edge *e;
int min_height = INT_MAX;
int is_vertical = 1;
@ -1922,6 +1952,9 @@ mono_merge_sorted_edges(struct mono_edge *head_a, struct mono_edge *head_b)
struct mono_edge *head, **next, *prev;
int32_t x;
if (head_b == NULL)
return head_a;
prev = head_a->prev;
next = &head;
if (head_a->x.quo <= head_b->x.quo) {
@ -1995,11 +2028,39 @@ mono_sort_edges(struct mono_edge *list,
return remaining;
}
static struct mono_edge *mono_filter(struct mono_edge *edges)
{
struct mono_edge *e;
e = edges;
do {
struct mono_edge *n = e->next;
if (e->dir == -n->dir &&
e->height_left == n->height_left &&
*(uint64_t *)&e->x == *(uint64_t *)&n->x &&
*(uint64_t *)&e->dxdy == *(uint64_t *)&n->dxdy) {
if (e->prev)
e->prev->next = n->next;
else
edges = n->next;
if (n->next)
n->next->prev = e->prev;
else
break;
e = n->next;
} else
e = e->next;
} while (e->next);
return edges;
}
static struct mono_edge *
mono_merge_unsorted_edges(struct mono_edge *head, struct mono_edge *unsorted)
{
mono_sort_edges(unsorted, UINT_MAX, &unsorted);
return mono_merge_sorted_edges(head, unsorted);
return mono_merge_sorted_edges(head, mono_filter(unsorted));
}
#if 0