Hi Denis,

On 10/26/2010 6:58 AM, Denis Lila wrote:
90% (guesstimate) of the time edges do not cross each other, thus if
you sort the crossings without reordering the active edges then you just
end up doing the same sorting work (same swaps) on the next scanline.  My
SpanShapeIterator code actually reordered the edges on every sample
line to match their current X coordinates in a way that involved 1 compare
per edge that was processed and only occasionally a swap of 2 edge
pointers.  It would basically eliminate the sort at line 149 at the
cost of only doing a compare in the nextY processing for the very very
common case.

I also implemented this some time ago. I didn't keep it because it slowed
things down a bit. However, I only tested it with very complex and large
paths, and in hindsight, I shouldn't have based my decision on that, so I
will re-implement it.

I tried using this new rasterizer in FX and I had a test case which had a few shapes that were essentially zig-zaggy shapes on the top and bottom and fills between the zigzags (kind of like a seismic chart with fills between the pen squiggles).

When I added a simple sort of the linear edges the performance nearly doubled in speed. Here is the code I replaced your quad-next-edge loop with:

            for (int i = elo; i < ehi; i++) {
                int ptr = edgePtrs[i];
                int cross = ((int) edges[ptr+CURX]) << 1;
                if (edges[ptr+OR] > 0) {
                    cross |= 1;
                }
                edges[ptr+CURY] += 1;
                edges[ptr+CURX] += edges[ptr+SLOPE];
                int j = crossingIdx;
                while (--j >= 0) {
                    int jcross = crossings[j];
                    if (cross >= jcross) {
                        break;
                    }
                    crossings[j+1] = jcross;
                    edgePtrs[elo+j+1] = edgePtrs[elo+j];
                }
                crossings[j+1] = cross;
                edgePtrs[elo+j+1] = ptr;
                crossingIdx++;
            }

I then did a conditional sort, moved to right after the qlo->qhi and clo->chi loops:

            for (int i = qlo; i < qhi; i++) {
                // same stuff
            }
            for (int i = clo; i < chi; i++) {
                // same stuff
            }
            if (qhi > qlo || chi > clo) {
                Arrays.sort(crossings, 0, crossingIdx);
            }

In the case of my test case where I only had a polygon to fill, the performance doubled. Obviously I didn't do much for the case where there were curves because this was just a quick hack to see the value of sorting the edges. If we moved to a Curve class or some other way to consolidate the 3 lists (may be easier in native code), this might win in more cases...

                        ...jim

Reply via email to