Faster edge re-sort, drop trailing edges
(patchset #4 id:60001 of https://codereview.chromium.org/891613003/)"
This reverts commit c319d075ea
.
BUG=skia:
TBR=
Review URL: https://codereview.chromium.org/907623002
This commit is contained in:
parent
c319d075ea
commit
2322115952
@ -79,8 +79,8 @@ static void setShiftedClip(SkRect* dst, const SkIRect& src, int shift) {
|
||||
SkIntToScalar(src.fBottom >> shift));
|
||||
}
|
||||
|
||||
int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip,
|
||||
int shiftUp) {
|
||||
int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shiftUp,
|
||||
bool clipToTheRight) {
|
||||
SkPath::Iter iter(path, true);
|
||||
SkPoint pts[4];
|
||||
SkPath::Verb verb;
|
||||
@ -115,7 +115,7 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip,
|
||||
break;
|
||||
case SkPath::kLine_Verb: {
|
||||
SkPoint lines[SkLineClipper::kMaxPoints];
|
||||
int lineCount = SkLineClipper::ClipLine(pts, clip, lines);
|
||||
int lineCount = SkLineClipper::ClipLine(pts, clip, lines, clipToTheRight);
|
||||
SkASSERT(lineCount <= SkLineClipper::kMaxClippedLineSegments);
|
||||
for (int i = 0; i < lineCount; i++) {
|
||||
if (edge->setLine(lines[i], lines[i + 1], shiftUp)) {
|
||||
@ -161,14 +161,14 @@ static void handle_quad(SkEdgeBuilder* builder, const SkPoint pts[3]) {
|
||||
}
|
||||
}
|
||||
|
||||
int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip,
|
||||
int shiftUp) {
|
||||
int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
|
||||
bool clipToTheRight) {
|
||||
fAlloc.reset();
|
||||
fList.reset();
|
||||
fShiftUp = shiftUp;
|
||||
|
||||
if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) {
|
||||
return this->buildPoly(path, iclip, shiftUp);
|
||||
return this->buildPoly(path, iclip, shiftUp, clipToTheRight);
|
||||
}
|
||||
|
||||
SkAutoConicToQuads quadder;
|
||||
@ -192,7 +192,7 @@ int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip,
|
||||
break;
|
||||
case SkPath::kLine_Verb: {
|
||||
SkPoint lines[SkLineClipper::kMaxPoints];
|
||||
int lineCount = SkLineClipper::ClipLine(pts, clip, lines);
|
||||
int lineCount = SkLineClipper::ClipLine(pts, clip, lines, clipToTheRight);
|
||||
for (int i = 0; i < lineCount; i++) {
|
||||
this->addLine(&lines[i]);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
|
||||
// returns the number of built edges. The array of those edge pointers
|
||||
// is returned from edgeList().
|
||||
int build(const SkPath& path, const SkIRect* clip, int shiftUp);
|
||||
int build(const SkPath& path, const SkIRect* clip, int shiftUp, bool clipToTheRight);
|
||||
|
||||
SkEdge** edgeList() { return fEdgeList; }
|
||||
|
||||
@ -36,9 +36,9 @@ private:
|
||||
* empty, as we will have preallocated room for the pointers in fAlloc's
|
||||
* block, and fEdgeList will point into that.
|
||||
*/
|
||||
SkEdge** fEdgeList;
|
||||
SkEdge** fEdgeList;
|
||||
|
||||
int fShiftUp;
|
||||
int fShiftUp;
|
||||
|
||||
public:
|
||||
void addLine(const SkPoint pts[]);
|
||||
@ -46,7 +46,7 @@ public:
|
||||
void addCubic(const SkPoint pts[]);
|
||||
void addClipper(SkEdgeClipper*);
|
||||
|
||||
int buildPoly(const SkPath& path, const SkIRect* clip, int shiftUp);
|
||||
int buildPoly(const SkPath& path, const SkIRect* clip, int shiftUp, bool clipToTheRight);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -173,7 +173,7 @@ static void sect_with_horizontal_test_for_pin_results() {
|
||||
#endif
|
||||
|
||||
int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
|
||||
SkPoint lines[]) {
|
||||
SkPoint lines[], bool canClipToTheRight) {
|
||||
#ifdef SK_DEBUG
|
||||
{
|
||||
static bool gOnce;
|
||||
@ -241,6 +241,9 @@ int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip,
|
||||
result = tmp;
|
||||
reverse = false;
|
||||
} else if (tmp[index0].fX >= clip.fRight) { // wholly to the right
|
||||
if (canClipToTheRight) {
|
||||
return 0;
|
||||
}
|
||||
tmp[0].fX = tmp[1].fX = clip.fRight;
|
||||
result = tmp;
|
||||
reverse = false;
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
3rd segment: lines[2]..lines[3]
|
||||
*/
|
||||
static int ClipLine(const SkPoint pts[2], const SkRect& clip,
|
||||
SkPoint lines[kMaxPoints]);
|
||||
SkPoint lines[kMaxPoints], bool canClipToTheRight);
|
||||
|
||||
/* Intersect the line segment against the rect. If there is a non-empty
|
||||
resulting segment, return true and set dst[] to that segment. If not,
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user