aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed <reed@google.com>2015-02-07 12:18:41 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2015-02-07 12:18:41 -0800
commit01d3319b67b1ad404006a0026803efc1573f4570 (patch)
treec350a7e529a518fa74befb485332bb767257bf35
parent5cc0f6c1ac6636efaf4da775f464a0288fef04e7 (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
-rw-r--r--src/core/SkEdgeBuilder.cpp14
-rw-r--r--src/core/SkEdgeBuilder.h8
-rw-r--r--src/core/SkLineClipper.cpp10
-rw-r--r--src/core/SkLineClipper.h2
-rw-r--r--src/core/SkScan_Path.cpp62
5 files changed, 55 insertions, 41 deletions
diff --git a/src/core/SkEdgeBuilder.cpp b/src/core/SkEdgeBuilder.cpp
index 8dcc47a6ce..00811203b4 100644
--- a/src/core/SkEdgeBuilder.cpp
+++ b/src/core/SkEdgeBuilder.cpp
@@ -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]);
}
diff --git a/src/core/SkEdgeBuilder.h b/src/core/SkEdgeBuilder.h
index f9e5976e17..625465b8a6 100644
--- a/src/core/SkEdgeBuilder.h
+++ b/src/core/SkEdgeBuilder.h
@@ -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
diff --git a/src/core/SkLineClipper.cpp b/src/core/SkLineClipper.cpp
index 1645917d70..3ff8948913 100644
--- a/src/core/SkLineClipper.cpp
+++ b/src/core/SkLineClipper.cpp
@@ -173,7 +173,12 @@ 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) {
+#if 1
+ // Disable this while we investigate layouttest failures
+ canClipToTheRight = false;
+#endif
+
#ifdef SK_DEBUG
{
static bool gOnce;
@@ -241,6 +246,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;
diff --git a/src/core/SkLineClipper.h b/src/core/SkLineClipper.h
index 8026890b8d..d966dbc74c 100644
--- a/src/core/SkLineClipper.h
+++ b/src/core/SkLineClipper.h
@@ -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,
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);
}
}