diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-02-06 15:54:48 -0500 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-06-01 09:23:45 -0400 |
commit | 2875048b194b86fd5b9ed1cd326f8b9fa0b86789 (patch) | |
tree | 19c351f472a18bbf56f125b364c9d657255d65b3 | |
parent | 85477e42db11d090cfe5ba6a767207962d207e85 (diff) |
Some classification
-rw-r--r-- | pixman/pixman-polygon.c | 140 | ||||
-rw-r--r-- | test/polygon-small.c | 4 |
2 files changed, 138 insertions, 6 deletions
diff --git a/pixman/pixman-polygon.c b/pixman/pixman-polygon.c index c75a6143..84250bef 100644 --- a/pixman/pixman-polygon.c +++ b/pixman/pixman-polygon.c @@ -67,6 +67,8 @@ * +--------------------------------------------------+ */ +#define force_inline + #define POLY_N_Y_FRAC(n) ((n) == 1 ? 1 : (1 << ((n)/2)) - 1) #define POLY_N_X_FRAC(n) ((n) == 1 ? 1 : (1 << ((n)/2)) + 1) @@ -272,6 +274,7 @@ struct active_t uint32_t * buffer; uint32_t dirty[(((MAX_WIDTH + 15)/ 16) + 31)/32]; int n_edges; + uint32_t classification; edge_t edges[16]; }; @@ -513,7 +516,15 @@ edge_init (edge_t *edge, const pixman_segment_24_8_t *segment, edge->dy = dy; edge->dx = dx; + +#if 0 + if (edge->dx < 0) + edge->dxdy = - (((- dx) << 32) / dy); + else + edge->dxdy = (dx << 32) / dy; +#endif edge->dxdy = ((((dx < 0)? (-dx) : (dx))) << 32) / dy; + edge->e = 0; #ifdef PRINT_DEBUG_SPEW @@ -541,8 +552,9 @@ update_active (active_t *active) edge_t *edge; active_t *new; - if (active->global_next->line.p1.x < active->x + active->width || - active->global_next->line.p2.x < active->x + active->width) + if ((active->global_next->line.p1.x < active->x + active->width || + active->global_next->line.p2.x < active->x + active->width) && + active->global_next->bottom > active->yi) { if (!(new = allocate_edge (active, &edge))) { @@ -561,6 +573,9 @@ update_active (active_t *active) active->strategy->big_step); list_append (active, edge); +#if 0 + printf ("New edge: %p\n", edge); +#endif } } @@ -582,7 +597,9 @@ oom_bail: if (edge->bottom <= active->yi) { #ifdef PRINT_DEBUG_SPEW - printf ("death %p\n", edge); +#endif +#if 0 + printf ("Dead edge %p\n", edge); #endif list_remove (active, edge); free_edge (active, edge); @@ -598,7 +615,12 @@ oom_bail: } if (k != edge->prev) + { +#if 0 + printf ("Intersecting edge: %p\n", edge); +#endif move_after (active, edge, k); + } } i = next; @@ -628,6 +650,102 @@ oom_bail: printf ("line %f\n", pixman_fixed_24_8_to_double (active->yi)); #endif + if ((active->yi & 0xff) == active->strategy->y_frac_first) + { + uint32_t flags = 0; + pixman_fixed_24_8_t next = active->yi + pixman_fixed_24_8_1; + edge_t *prev = NULL; + +#if 0 + printf ("New scanline - classifying the state here (0x%x)\n", active->yi); +#endif + +#define DYING_EDGES (1 << 0) +#define NEW_EDGES (1 << 1) +#define POTENTIAL_INTERSECTION (1 << 2) +#define NON_VERTICAL (1 << 3) +#define NEW_SURVIVORS (1 << 4) + + for (i = active->head; i != -1; i = active->edges[i].next) + { + edge_t *edge = &(active->edges[i]); + + if (edge->bottom < next) + flags |= DYING_EDGES; + + if (prev) + { + int ps, ts; + int y; + + y = prev->bottom; + if (edge->bottom < y) + y = edge->bottom; + if (y > next) + y = next; + y -= active->yi; + + if (prev->dx < 0) + ps = - ((y * prev->dxdy) >> 32); + else + ps = (y * prev->dxdy) >> 32; + + if (edge->dx < 0) + ts = - ((y * edge->dxdy) >> 32); + else + ts = (y * edge->dxdy >> 32); + + if (edge->x + ts < prev->x + ps) + { + flags |= POTENTIAL_INTERSECTION; +#if 0 + printf ("%p and %p may intersect\n", edge, prev); +#endif + } + } + + if (edge->dxdy != 0) + flags |= NON_VERTICAL; + + prev = edge; + + active->classification = flags; + } + + const pixman_segment_24_8_t *g; + + for (g = active->global_next; g != active->global_last; g++) + { + if (g->top >= next) + break; + + flags |= NEW_EDGES; + if (g->bottom > next) + flags |= NEW_SURVIVORS; + } + + if (flags & NON_VERTICAL) + { + printf ("Classification: %d %c %c %c %c %c\n", + active->n_edges, + (flags & NEW_EDGES)? 'N' : ' ', + (flags & NEW_SURVIVORS)? 'S' : ' ', + (flags & DYING_EDGES)? 'D' : ' ', + (flags & POTENTIAL_INTERSECTION)? 'I' : ' ', + (!(flags & NON_VERTICAL))? 'V' : ' '); + } +#if 0 + if ((flags & NEW_EDGES)) + printf ("- New edges may arrive\n"); + if ((flags & DYING_EDGES)) + printf ("- Some edges may die\n"); + if ((flags & POTENTIAL_INTERSECTION)) + printf ("- Edges may intersect\n"); + if (!(flags & NON_VERTICAL)) + printf ("- All edges are vertical\n"); +#endif + } + return active; } @@ -644,6 +762,10 @@ create_active (polygon_t *polygon, pixman_iter_t *iter) width = iter->width; height = iter->height; +#if 0 + printf ("new polygon\n"); +#endif + #ifdef PRINT_DEBUG_SPEW printf ("x y %d %d\n", x, y); #endif @@ -754,6 +876,10 @@ step_active_inline (active_t *active, int offset, uint winding_mask, uint32_t *d unsigned winding = 0; int i; +#if 0 + printf ("Active: %d (%x)\n", active->n_edges, active->yi); +#endif + for (i = active->head; i != -1; i = active->edges[i].next) { edge_t *edge = &(active->edges[i]); @@ -799,7 +925,9 @@ step_active (active_t *active, pixman_fixed_24_8_t step_size, uint32_t *dirty) active->yi += step_size; - return update_active (active); + active = update_active (active); + + return active; } static uint32_t * @@ -811,6 +939,10 @@ polygon_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask) uint32_t acc; int i, j; +#if 0 + printf ("Get scanline\n"); +#endif + n_dirty_words = ((iter->width + 15) / 16 + 31) / 32; for (i = 0; i < n_dirty_words; ++i) diff --git a/test/polygon-small.c b/test/polygon-small.c index da6706de..29cd6d90 100644 --- a/test/polygon-small.c +++ b/test/polygon-small.c @@ -134,7 +134,7 @@ test_polygon (int testnum, assert (dst_img); - image_endian_swap (dst_img, dst_bpp * 8); + image_endian_swap (dst_img); if (verbose) { @@ -184,7 +184,7 @@ test_polygon (int testnum, dstbuf[i] &= 0xFFFFFF; } - image_endian_swap (dst_img, dst_bpp * 8); + image_endian_swap (dst_img); if (verbose) { |