xf86-video-intel: src/sna/sna_trapezoids_imprecise.c src/sna/sna_trapezoids_precise.c
Chris Wilson
ickle at kemper.freedesktop.org
Mon Oct 7 02:26:25 PDT 2013
src/sna/sna_trapezoids_imprecise.c | 87 +++++++++---------------------------
src/sna/sna_trapezoids_precise.c | 88 ++++++++++---------------------------
2 files changed, 47 insertions(+), 128 deletions(-)
New commits:
commit d462475b7ecca6eb001b521185d2f7286031a8d8
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Mon Oct 7 10:04:15 2013 +0100
sna/trapezoids: Fix overstepping vertical edges
Regression from
commit c98b770a87a5ec5ed9dc0aa375ad173b0e98322e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Oct 4 18:37:01 2013 +0100
sna/trapezoids: Add a precise scan converter
Reported-by: Joseph Yasi <joe.yasi at gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=70204
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
diff --git a/src/sna/sna_trapezoids_imprecise.c b/src/sna/sna_trapezoids_imprecise.c
index bbb7f2f..2cfab80 100644
--- a/src/sna/sna_trapezoids_imprecise.c
+++ b/src/sna/sna_trapezoids_imprecise.c
@@ -248,13 +248,6 @@ struct cell_list {
struct active_list {
/* Leftmost edge on the current scan line. */
struct edge head, tail;
-
- /* A lower bound on the height of the active edges is used to
- * estimate how soon some active edge ends. We can't advance the
- * scan conversion by a full pixel row if an edge ends somewhere
- * within it. */
- int min_height;
- int is_vertical;
};
struct tor {
@@ -663,8 +656,6 @@ active_list_reset(struct active_list *active)
active->tail.x.quo = INT_MAX;
active->tail.height_left = INT_MAX;
active->tail.dy = 0;
- active->min_height = INT_MAX;
- active->is_vertical = 1;
}
static struct edge *
@@ -788,35 +779,30 @@ merge_unsorted_edges(struct edge *head, struct edge *unsorted)
inline static bool
can_full_step(struct active_list *active)
{
- /* 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;
-
- for (e = active->head.next; &active->tail != e; e = e->next) {
- if (e->height_left < min_height)
- min_height = e->height_left;
- if (is_vertical)
- is_vertical = e->dy == 0;
- }
+ const struct edge *e;
+ int min_height = INT_MAX;
- active->is_vertical = is_vertical;
- active->min_height = min_height;
- }
+ assert(active->head.next != &active->tail);
+ for (e = active->head.next; &active->tail != e; e = e->next) {
+ assert(e->height_left >= 0);
- if (active->min_height < FAST_SAMPLES_Y)
- return false;
+ if (e->dy != 0)
+ return 0;
+
+ if (e->height_left < min_height) {
+ min_height = e->height_left;
+ if (min_height < FAST_SAMPLES_Y)
+ return 0;
+ }
+ }
- return active->is_vertical;
+ return min_height;
}
inline static void
merge_edges(struct active_list *active, struct edge *edges)
{
active->head.next = merge_unsorted_edges(active->head.next, edges);
- active->min_height = -1;
}
inline static void
@@ -824,9 +810,6 @@ fill_buckets(struct active_list *active,
struct edge *edge,
struct edge **buckets)
{
- int min_height = active->min_height;
- int is_vertical = active->is_vertical;
-
while (edge) {
struct edge *next = edge->next;
struct edge **b = &buckets[edge->ytop & (FAST_SAMPLES_Y-1)];
@@ -835,15 +818,8 @@ fill_buckets(struct active_list *active,
edge->next = *b;
edge->prev = NULL;
*b = edge;
- if (edge->height_left < min_height)
- min_height = edge->height_left;
- if (is_vertical)
- is_vertical = edge->dy == 0;
edge = next;
}
-
- active->is_vertical = is_vertical;
- active->min_height = min_height;
}
inline static void
@@ -902,13 +878,12 @@ nonzero_row(struct active_list *active, struct cell_list *coverages)
{
struct edge *left = active->head.next;
- assert(active->is_vertical);
-
while (&active->tail != left) {
struct edge *right;
int winding = left->dir;
left->height_left -= FAST_SAMPLES_Y;
+ assert(left->height_left >= 0);
if (! left->height_left) {
left->prev->next = left->next;
left->next->prev = left->prev;
@@ -917,6 +892,7 @@ nonzero_row(struct active_list *active, struct cell_list *coverages)
right = left->next;
do {
right->height_left -= FAST_SAMPLES_Y;
+ assert(right->height_left >= 0);
if (!right->height_left) {
right->prev->next = right->next;
right->next->prev = right->prev;
@@ -1224,8 +1200,6 @@ tor_render(struct sna *sna,
* stepper. */
if (!polygon->y_buckets[i]) {
if (active->head.next == &active->tail) {
- active->min_height = INT_MAX;
- active->is_vertical = 1;
for (; !polygon->y_buckets[j]; j++)
;
__DBG(("%s: no new edges and no exisiting edges, skipping, %d -> %d\n",
@@ -1242,16 +1216,13 @@ tor_render(struct sna *sna,
__DBG(("%s: y=%d [%d], do_full_step=%d, new edges=%d, min_height=%d, vertical=%d\n",
__FUNCTION__,
i, i+ymin, do_full_step,
- polygon->y_buckets[i] != NULL,
- active->min_height,
- active->is_vertical));
+ polygon->y_buckets[i] != NULL));
if (do_full_step) {
- assert(active->is_vertical);
nonzero_row(active, coverages);
while (polygon->y_buckets[j] == NULL &&
- active->min_height >= FAST_SAMPLES_Y) {
- active->min_height -= FAST_SAMPLES_Y;
+ do_full_step >= 2*FAST_SAMPLES_Y) {
+ do_full_step -= FAST_SAMPLES_Y;
j++;
}
if (j != i + 1)
@@ -1279,8 +1250,6 @@ tor_render(struct sna *sna,
i+ymin, j-i, xmin, xmax,
unbounded);
cell_list_reset(coverages);
-
- active->min_height -= FAST_SAMPLES_Y;
}
}
@@ -1289,8 +1258,6 @@ inplace_row(struct active_list *active, uint8_t *row, int width)
{
struct edge *left = active->head.next;
- assert(active->is_vertical);
-
while (&active->tail != left) {
struct edge *right;
int winding = left->dir;
@@ -1583,8 +1550,6 @@ tor_inplace(struct tor *converter, PixmapPtr scratch, int mono, uint8_t *buf)
* stepper. */
if (!polygon->y_buckets[i]) {
if (active->head.next == &active->tail) {
- active->min_height = INT_MAX;
- active->is_vertical = 1;
for (; !polygon->y_buckets[j]; j++)
;
__DBG(("%s: no new edges and no exisiting edges, skipping, %d -> %d\n",
@@ -1601,21 +1566,16 @@ tor_inplace(struct tor *converter, PixmapPtr scratch, int mono, uint8_t *buf)
__DBG(("%s: y=%d, do_full_step=%d, new edges=%d, min_height=%d, vertical=%d\n",
__FUNCTION__,
i, do_full_step,
- polygon->y_buckets[i] != NULL,
- active->min_height,
- active->is_vertical));
+ polygon->y_buckets[i] != NULL));
if (do_full_step) {
- assert(active->is_vertical);
-
memset(ptr, 0, width);
inplace_row(active, ptr, width);
if (row != ptr)
memcpy(row, ptr, width);
while (polygon->y_buckets[j] == NULL &&
- active->min_height >= FAST_SAMPLES_Y)
- {
- active->min_height -= FAST_SAMPLES_Y;
+ do_full_step >= 2*FAST_SAMPLES_Y) {
+ do_full_step -= FAST_SAMPLES_Y;
row += stride;
memcpy(row, ptr, width);
j++;
@@ -1648,7 +1608,6 @@ tor_inplace(struct tor *converter, PixmapPtr scratch, int mono, uint8_t *buf)
memset(row+max, 0, width-max);
}
- active->min_height -= FAST_SAMPLES_Y;
row += stride;
}
}
diff --git a/src/sna/sna_trapezoids_precise.c b/src/sna/sna_trapezoids_precise.c
index e7a5578..345922f 100644
--- a/src/sna/sna_trapezoids_precise.c
+++ b/src/sna/sna_trapezoids_precise.c
@@ -261,13 +261,6 @@ struct cell_list {
struct active_list {
/* Leftmost edge on the current scan line. */
struct edge head, tail;
-
- /* A lower bound on the height of the active edges is used to
- * estimate how soon some active edge ends. We can't advance the
- * scan conversion by a full pixel row if an edge ends somewhere
- * within it. */
- int min_height;
- int is_vertical;
};
struct tor {
@@ -668,8 +661,6 @@ active_list_reset(struct active_list *active)
active->tail.x.quo = INT_MAX;
active->tail.height_left = INT_MAX;
active->tail.dy = 0;
- active->min_height = INT_MAX;
- active->is_vertical = 1;
}
static struct edge *
@@ -793,35 +784,30 @@ merge_unsorted_edges(struct edge *head, struct edge *unsorted)
inline static bool
can_full_step(struct active_list *active)
{
- /* 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;
-
- for (e = active->head.next; &active->tail != e; e = e->next) {
- if (e->height_left < min_height)
- min_height = e->height_left;
- if (is_vertical)
- is_vertical = e->dy == 0;
- }
+ const struct edge *e;
+ int min_height = INT_MAX;
- active->is_vertical = is_vertical;
- active->min_height = min_height;
- }
+ assert(active->head.next != &active->tail);
+ for (e = active->head.next; &active->tail != e; e = e->next) {
+ assert(e->height_left >= 0);
- if (active->min_height < SAMPLES_Y)
- return false;
+ if (e->dy != 0)
+ return 0;
+
+ if (e->height_left < min_height) {
+ min_height = e->height_left;
+ if (min_height < SAMPLES_Y)
+ return 0;
+ }
+ }
- return active->is_vertical;
+ return min_height;
}
inline static void
merge_edges(struct active_list *active, struct edge *edges)
{
active->head.next = merge_unsorted_edges(active->head.next, edges);
- active->min_height = -1;
}
inline static void
@@ -830,9 +816,6 @@ fill_buckets(struct active_list *active,
int ymin,
struct edge **buckets)
{
- int min_height = active->min_height;
- int is_vertical = active->is_vertical;
-
while (edge) {
struct edge *next = edge->next;
struct edge **b = &buckets[edge->ytop - ymin];
@@ -841,15 +824,8 @@ fill_buckets(struct active_list *active,
edge->next = *b;
edge->prev = NULL;
*b = edge;
- if (edge->height_left < min_height)
- min_height = edge->height_left;
- if (is_vertical)
- is_vertical = edge->dy == 0;
edge = next;
}
-
- active->is_vertical = is_vertical;
- active->min_height = min_height;
}
inline static void
@@ -908,13 +884,12 @@ nonzero_row(struct active_list *active, struct cell_list *coverages)
{
struct edge *left = active->head.next;
- assert(active->is_vertical);
-
while (&active->tail != left) {
struct edge *right;
int winding = left->dir;
left->height_left -= SAMPLES_Y;
+ assert(left->height_left >= 0);
if (!left->height_left) {
left->prev->next = left->next;
left->next->prev = left->prev;
@@ -923,6 +898,7 @@ nonzero_row(struct active_list *active, struct cell_list *coverages)
right = left->next;
do {
right->height_left -= SAMPLES_Y;
+ assert(right->height_left >= 0);
if (!right->height_left) {
right->prev->next = right->next;
right->next->prev = right->prev;
@@ -1181,8 +1157,6 @@ tor_render(struct sna *sna,
* stepper. */
if (!polygon->y_buckets[i]) {
if (active->head.next == &active->tail) {
- active->min_height = INT_MAX;
- active->is_vertical = 1;
for (; !polygon->y_buckets[j]; j++)
;
__DBG(("%s: no new edges and no exisiting edges, skipping, %d -> %d\n",
@@ -1196,19 +1170,16 @@ tor_render(struct sna *sna,
do_full_step = can_full_step(active);
}
- __DBG(("%s: y=%d [%d], do_full_step=%d, new edges=%d, min_height=%d, vertical=%d\n",
+ __DBG(("%s: y=%d [%d], do_full_step=%d, new edges=%d\n",
__FUNCTION__,
i, i+ymin, do_full_step,
- polygon->y_buckets[i] != NULL,
- active->min_height,
- active->is_vertical));
+ polygon->y_buckets[i] != NULL));
if (do_full_step) {
- assert(active->is_vertical);
nonzero_row(active, coverages);
while (polygon->y_buckets[j] == NULL &&
- active->min_height >= SAMPLES_Y) {
- active->min_height -= SAMPLES_Y;
+ do_full_step >= 2*SAMPLES_Y) {
+ do_full_step -= SAMPLES_Y;
j++;
}
if (j != i + 1)
@@ -1236,8 +1207,6 @@ tor_render(struct sna *sna,
i+ymin, j-i, xmin, xmax,
unbounded);
cell_list_reset(coverages);
-
- active->min_height -= SAMPLES_Y;
}
}
@@ -1246,8 +1215,6 @@ inplace_row(struct active_list *active, uint8_t *row, int width)
{
struct edge *left = active->head.next;
- assert(active->is_vertical);
-
while (&active->tail != left) {
struct edge *right;
int winding = left->dir;
@@ -1528,8 +1495,6 @@ tor_inplace(struct tor *converter, PixmapPtr scratch)
* stepper. */
if (!polygon->y_buckets[i]) {
if (active->head.next == &active->tail) {
- active->min_height = INT_MAX;
- active->is_vertical = 1;
for (; !polygon->y_buckets[j]; j++)
;
__DBG(("%s: no new edges and no exisiting edges, skipping, %d -> %d\n",
@@ -1546,20 +1511,16 @@ tor_inplace(struct tor *converter, PixmapPtr scratch)
__DBG(("%s: y=%d, do_full_step=%d, new edges=%d, min_height=%d, vertical=%d\n",
__FUNCTION__,
i, do_full_step,
- polygon->y_buckets[i] != NULL,
- active->min_height,
- active->is_vertical));
+ polygon->y_buckets[i] != NULL));
if (do_full_step) {
- assert(active->is_vertical);
-
memset(ptr, 0, width);
inplace_row(active, ptr, width);
if (row != ptr)
memcpy(row, ptr, width);
while (polygon->y_buckets[j] == NULL &&
- active->min_height >= SAMPLES_Y) {
- active->min_height -= SAMPLES_Y;
+ do_full_step >= 2*SAMPLES_Y) {
+ do_full_step -= SAMPLES_Y;
row += stride;
memcpy(row, ptr, width);
j++;
@@ -1588,7 +1549,6 @@ tor_inplace(struct tor *converter, PixmapPtr scratch)
memcpy(row, ptr, width);
}
- active->min_height -= SAMPLES_Y;
row += stride;
}
}
More information about the xorg-commit
mailing list