summaryrefslogtreecommitdiff
path: root/src/sna/sna_trapezoids_precise.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sna/sna_trapezoids_precise.c')
-rw-r--r--src/sna/sna_trapezoids_precise.c108
1 files changed, 46 insertions, 62 deletions
diff --git a/src/sna/sna_trapezoids_precise.c b/src/sna/sna_trapezoids_precise.c
index b4d7592d..3720d8ba 100644
--- a/src/sna/sna_trapezoids_precise.c
+++ b/src/sna/sna_trapezoids_precise.c
@@ -268,9 +268,7 @@ struct tor {
struct active_list active[1];
struct cell_list coverages[1];
- /* Clip box. */
- int xmin, xmax;
- int ymin, ymax;
+ BoxRec extents;
};
/* Compute the floored division a/b. Assumes / and % perform symmetric
@@ -473,13 +471,9 @@ polygon_fini(struct polygon *polygon)
}
static bool
-polygon_init(struct polygon *polygon,
- int num_edges,
- int ymin,
- int ymax)
+polygon_init(struct polygon *polygon, int num_edges, int ymin, int ymax)
{
- unsigned num_buckets =
- EDGE_Y_BUCKET_INDEX(ymax+EDGE_Y_BUCKET_HEIGHT-1, ymin);
+ unsigned num_buckets = EDGE_Y_BUCKET_INDEX(ymax-1, ymin) + 1;
if (unlikely(ymax - ymin > 0x7FFFFFFFU - EDGE_Y_BUCKET_HEIGHT))
return false;
@@ -516,6 +510,7 @@ _polygon_insert_edge_into_its_y_bucket(struct polygon *polygon, struct edge *e)
{
unsigned ix = EDGE_Y_BUCKET_INDEX(e->ytop, polygon->ymin);
struct edge **ptail = &polygon->y_buckets[ix];
+ assert(e->ytop < polygon->ymax);
e->next = *ptail;
*ptail = e;
}
@@ -534,7 +529,7 @@ polygon_add_edge(struct polygon *polygon,
int ymin = polygon->ymin;
int ymax = polygon->ymax;
- assert (dy > 0);
+ assert(dy > 0);
e->dy = dy;
e->dir = dir;
@@ -934,10 +929,7 @@ tor_init(struct tor *converter, const BoxRec *box, int num_edges)
SAMPLES_X, SAMPLES_Y,
num_edges));
- converter->xmin = box->x1;
- converter->ymin = box->y1;
- converter->xmax = box->x2;
- converter->ymax = box->y2;
+ converter->extents = *box;
if (!cell_list_init(converter->coverages, box->x1, box->x2))
return false;
@@ -1033,6 +1025,7 @@ tor_blt_span_clipped(struct sna *sna,
static void
tor_blt(struct sna *sna,
+ struct tor *converter,
struct sna_composite_spans_op *op,
pixman_region16_t *clip,
void (*span)(struct sna *sna,
@@ -1040,18 +1033,18 @@ tor_blt(struct sna *sna,
pixman_region16_t *clip,
const BoxRec *box,
int coverage),
- struct cell_list *cells,
int y, int height,
- int xmin, int xmax,
int unbounded)
{
+ struct cell_list *cells = converter->coverages;
struct cell *cell;
BoxRec box;
int cover;
- box.y1 = y;
- box.y2 = y + height;
- box.x1 = xmin;
+ box.y1 = y + converter->extents.y1;
+ box.y2 = box.y1 + height;
+ assert(box.y2 <= converter->extents.y2);
+ box.x1 = converter->extents.x1;
/* Form the spans from the coverages and areas. */
cover = cells->head.covered_height*SAMPLES_X*2;
@@ -1059,8 +1052,8 @@ tor_blt(struct sna *sna,
for (cell = cells->head.next; cell != &cells->tail; cell = cell->next) {
int x = cell->x;
- assert(x >= xmin);
- assert(x < xmax);
+ assert(x >= converter->extents.x1);
+ assert(x < converter->extents.x2);
__DBG(("%s: cell=(%d, %d, %d), cover=%d, max=%d\n", __FUNCTION__,
cell->x, cell->covered_height, cell->uncovered_area,
cover, xmax));
@@ -1094,7 +1087,7 @@ tor_blt(struct sna *sna,
}
}
- box.x2 = xmax;
+ box.x2 = converter->extents.x2;
if (box.x2 > box.x1 && (unbounded || cover)) {
__DBG(("%s: span (%d, %d)x(%d, %d) @ %d\n", __FUNCTION__,
box.x1, box.y1,
@@ -1105,28 +1098,6 @@ tor_blt(struct sna *sna,
}
}
-static void
-tor_blt_empty(struct sna *sna,
- struct sna_composite_spans_op *op,
- pixman_region16_t *clip,
- void (*span)(struct sna *sna,
- struct sna_composite_spans_op *op,
- pixman_region16_t *clip,
- const BoxRec *box,
- int coverage),
- int y, int height,
- int xmin, int xmax)
-{
- BoxRec box;
-
- box.x1 = xmin;
- box.x2 = xmax;
- box.y1 = y;
- box.y2 = y + height;
-
- span(sna, op, clip, &box, 0);
-}
-
flatten static void
tor_render(struct sna *sna,
struct tor *converter,
@@ -1139,14 +1110,11 @@ tor_render(struct sna *sna,
int coverage),
int unbounded)
{
- int ymin = converter->ymin;
- int xmin = converter->xmin;
- int xmax = converter->xmax;
- int i, j, h = converter->ymax - ymin;
struct polygon *polygon = converter->polygon;
struct cell_list *coverages = converter->coverages;
struct active_list *active = converter->active;
struct edge *buckets[SAMPLES_Y] = { 0 };
+ int16_t i, j, h = converter->extents.y2 - converter->extents.y1;
__DBG(("%s: unbounded=%d\n", __FUNCTION__, unbounded));
@@ -1158,15 +1126,23 @@ tor_render(struct sna *sna,
/* Determine if we can ignore this row or use the full pixel
* stepper. */
- if (!polygon->y_buckets[i]) {
+ if (polygon->y_buckets[i] == NULL) {
if (active->head.next == &active->tail) {
- for (; !polygon->y_buckets[j]; j++)
+ for (; polygon->y_buckets[j] == NULL; j++)
;
__DBG(("%s: no new edges and no exisiting edges, skipping, %d -> %d\n",
__FUNCTION__, i, j));
- if (unbounded)
- tor_blt_empty(sna, op, clip, span, i+ymin, j-i, xmin, xmax);
+ assert(j <= h);
+ if (unbounded) {
+ BoxRec box;
+
+ box = converter->extents;
+ box.y1 += i;
+ box.y2 = converter->extents.y1 + j;
+
+ span(sna, op, clip, &box, 0);
+ }
continue;
}
@@ -1185,6 +1161,7 @@ tor_render(struct sna *sna,
do_full_step -= SAMPLES_Y;
j++;
}
+ assert(j >= i + 1 && j <= h);
if (j != i + 1)
step_edges(active, j - (i + 1));
@@ -1193,7 +1170,7 @@ tor_render(struct sna *sna,
} else {
int suby;
- fill_buckets(active, polygon->y_buckets[i], (i+ymin)*SAMPLES_Y, buckets);
+ fill_buckets(active, polygon->y_buckets[i], (i+converter->extents.y1)*SAMPLES_Y, buckets);
/* Subsample this row. */
for (suby = 0; suby < SAMPLES_Y; suby++) {
@@ -1206,9 +1183,8 @@ tor_render(struct sna *sna,
}
}
- tor_blt(sna, op, clip, span, coverages,
- i+ymin, j-i, xmin, xmax,
- unbounded);
+ assert(j > i);
+ tor_blt(sna, converter, op, clip, span, i, j-i, unbounded);
cell_list_reset(coverages);
}
}
@@ -1478,7 +1454,7 @@ flatten static void
tor_inplace(struct tor *converter, PixmapPtr scratch)
{
uint8_t buf[TOR_INPLACE_SIZE];
- int i, j, h = converter->ymax - converter->ymin;
+ int i, j, h = converter->extents.y2 - converter->extents.y1;
struct polygon *polygon = converter->polygon;
struct active_list *active = converter->active;
struct edge *buckets[SAMPLES_Y] = { 0 };
@@ -1487,10 +1463,10 @@ tor_inplace(struct tor *converter, PixmapPtr scratch)
int width = scratch->drawable.width;
__DBG(("%s: buf?=%d\n", __FUNCTION__, buf != NULL));
- assert(converter->xmin == 0);
+ assert(converter->extents.x1 == 0);
assert(scratch->drawable.depth == 8);
- row += converter->ymin * stride;
+ row += converter->extents.y1 * stride;
/* Render each pixel row. */
for (i = 0; i < h; i = j) {
@@ -1540,7 +1516,7 @@ tor_inplace(struct tor *converter, PixmapPtr scratch)
} else {
int suby;
- fill_buckets(active, polygon->y_buckets[i], (i+converter->ymin)*SAMPLES_Y, buckets);
+ fill_buckets(active, polygon->y_buckets[i], (i+converter->extents.y1)*SAMPLES_Y, buckets);
/* Subsample this row. */
memset(ptr, 0, width);
@@ -1931,6 +1907,7 @@ precise_trapezoid_span_converter(struct sna *sna,
y = clip.extents.y1;
h = clip.extents.y2 - clip.extents.y1;
h = (h + num_threads - 1) / num_threads;
+ num_threads = (clip.extents.y2 - clip.extents.y1 + h - 1) / h;
for (n = 1; n < num_threads; n++) {
threads[n] = threads[0];
@@ -1940,6 +1917,7 @@ precise_trapezoid_span_converter(struct sna *sna,
sna_threads_run(span_thread, &threads[n]);
}
+ assert(y < threads[0].extents.y2);
threads[0].extents.y1 = y;
span_thread(&threads[0]);
@@ -2155,6 +2133,7 @@ precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst,
y = extents.y1;
h = extents.y2 - extents.y1;
h = (h + num_threads - 1) / num_threads;
+ num_threads = (extents.y2 - extents.y1 + h - 1) / h;
for (n = 1; n < num_threads; n++) {
threads[n] = threads[0];
@@ -2164,6 +2143,7 @@ precise_trapezoid_mask_converter(CARD8 op, PicturePtr src, PicturePtr dst,
sna_threads_run(mask_thread, &threads[n]);
}
+ assert(y < threads[0].extents.y2);
threads[0].extents.y1 = y;
mask_thread(&threads[0]);
@@ -2859,6 +2839,7 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op,
y = region.extents.y1;
h = region.extents.y2 - region.extents.y1;
h = (h + num_threads - 1) / num_threads;
+ num_threads = (region.extents.y2 - region.extents.y1 + h - 1) / h;
for (n = 1; n < num_threads; n++) {
threads[n] = threads[0];
@@ -2868,8 +2849,8 @@ trapezoid_span_inplace__x8r8g8b8(CARD8 op,
sna_threads_run(inplace_x8r8g8b8_thread, &threads[n]);
}
+ assert(y < threads[0].extents.y2);
threads[0].extents.y1 = y;
- threads[0].extents.y2 = region.extents.y2;
inplace_x8r8g8b8_thread(&threads[0]);
sna_threads_wait();
@@ -3130,6 +3111,7 @@ precise_trapezoid_span_inplace(struct sna *sna,
y = region.extents.y1;
h = region.extents.y2 - region.extents.y1;
h = (h + num_threads - 1) / num_threads;
+ num_threads = (region.extents.y2 - region.extents.y1 + h - 1) / h;
for (n = 1; n < num_threads; n++) {
threads[n] = threads[0];
@@ -3139,8 +3121,8 @@ precise_trapezoid_span_inplace(struct sna *sna,
sna_threads_run(inplace_thread, &threads[n]);
}
+ assert(y < threads[0].extents.y2);
threads[0].extents.y1 = y;
- threads[0].extents.y2 = region.extents.y2;
inplace_thread(&threads[0]);
sna_threads_wait();
@@ -3273,6 +3255,7 @@ precise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst,
y = extents.y1;
h = extents.y2 - extents.y1;
h = (h + num_threads - 1) / num_threads;
+ num_threads = (extents.y2 - extents.y1 + h - 1) / h;
for (n = 1; n < num_threads; n++) {
threads[n] = threads[0];
@@ -3282,6 +3265,7 @@ precise_trapezoid_span_fallback(CARD8 op, PicturePtr src, PicturePtr dst,
sna_threads_run(mask_thread, &threads[n]);
}
+ assert(y < threads[0].extents.y2);
threads[0].extents.y1 = y;
mask_thread(&threads[0]);