diff options
author | reed <reed@google.com> | 2015-02-07 12:18:41 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-02-07 12:18:41 -0800 |
commit | 01d3319b67b1ad404006a0026803efc1573f4570 (patch) | |
tree | c350a7e529a518fa74befb485332bb767257bf35 /src/core/SkScan_Path.cpp | |
parent | 5cc0f6c1ac6636efaf4da775f464a0288fef04e7 (diff) |
Faster edge re-sort
For now, disable dropping trailing edges
This reverts commit 0692c5f2c1df7d1b66c62025200dd666f9ecd311.
BUG=skia:
TBR=
Review URL: https://codereview.chromium.org/882733004
Diffstat (limited to 'src/core/SkScan_Path.cpp')
-rw-r--r-- | src/core/SkScan_Path.cpp | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/src/core/SkScan_Path.cpp b/src/core/SkScan_Path.cpp index 5d9e0ca2a6..430cd1d841 100644 --- a/src/core/SkScan_Path.cpp +++ b/src/core/SkScan_Path.cpp @@ -45,34 +45,23 @@ static inline void remove_edge(SkEdge* edge) { edge->fNext->fPrev = edge->fPrev; } -static inline void swap_edges(SkEdge* prev, SkEdge* next) { - SkASSERT(prev->fNext == next && next->fPrev == prev); - - // remove prev from the list - prev->fPrev->fNext = next; - next->fPrev = prev->fPrev; - - // insert prev after next - prev->fNext = next->fNext; - next->fNext->fPrev = prev; - next->fNext = prev; - prev->fPrev = next; +static inline void insert_edge_after(SkEdge* edge, SkEdge* afterMe) { + edge->fPrev = afterMe; + edge->fNext = afterMe->fNext; + afterMe->fNext->fPrev = edge; + afterMe->fNext = edge; } static void backward_insert_edge_based_on_x(SkEdge* edge SkDECLAREPARAM(int, curr_y)) { SkFixed x = edge->fX; - for (;;) { - SkEdge* prev = edge->fPrev; - - // add 1 to curr_y since we may have added new edges (built from curves) - // that start on the next scanline - SkASSERT(prev && prev->fFirstY <= curr_y + 1); - - if (prev->fX <= x) { - break; - } - swap_edges(prev, edge); + SkEdge* prev = edge->fPrev; + while (prev->fX > x) { + prev = prev->fPrev; + } + if (prev->fNext != edge) { + remove_edge(edge); + insert_edge_after(edge, prev); } } @@ -113,7 +102,7 @@ typedef void (*PrePostProc)(SkBlitter* blitter, int y, bool isStartOfScanline); static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType, SkBlitter* blitter, int start_y, int stop_y, - PrePostProc proc) { + PrePostProc proc, int rightClip) { validate_sort(prevHead->fNext); int curr_y = start_y; @@ -183,6 +172,14 @@ static void walk_edges(SkEdge* prevHead, SkPath::FillType fillType, SkASSERT(currE); } + // was our right-edge culled away? + if (in_interval) { + int width = rightClip - left; + if (width > 0) { + blitter->blitH(left, curr_y, width); + } + } + if (proc) { proc(blitter, curr_y, PREPOST_END); // post-proc } @@ -430,13 +427,15 @@ static SkEdge* sort_edges(SkEdge* list[], int count, SkEdge** last) { // clipRect (if no null) has already been shifted up // void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitter, - int start_y, int stop_y, int shiftEdgesUp, - const SkRegion& clipRgn) { + int start_y, int stop_y, int shiftEdgesUp, const SkRegion& clipRgn) { SkASSERT(blitter); SkEdgeBuilder builder; - int count = builder.build(path, clipRect, shiftEdgesUp); + // If we're convex, then we need both edges, even the right edge is past the clip + const bool cullToTheRight = !path.isConvex(); + + int count = builder.build(path, clipRect, shiftEdgesUp, cullToTheRight); SkEdge** list = builder.edgeList(); if (count < 2) { @@ -503,7 +502,14 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte if (path.isConvex() && (NULL == proc)) { walk_convex_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, NULL); } else { - walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc); + int rightEdge; + if (clipRect) { + rightEdge = clipRect->right(); + } else { + rightEdge = SkScalarRoundToInt(path.getBounds().right()) << shiftEdgesUp; + } + + walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc, rightEdge); } } |