Revert of faster edge re-sort, drop trailing edges (patchset #4 id:60001 of https...
authorreed <reed@chromium.org>
Sat, 7 Feb 2015 02:07:39 +0000 (18:07 -0800)
committerCommit bot <commit-bot@chromium.org>
Sat, 7 Feb 2015 02:07:39 +0000 (18:07 -0800)
Reason for revert:
may be breaking layouttests...

Original issue's description:
> faster edge re-sort, drop trailing edges
>
> 1. drop edges that are wholly on the right (in the non-convex walker)
> 2. scan and swap once, instead of swapping as we go during re-sort
>
> BUG=skia:
>
> Committed: https://skia.googlesource.com/skia/+/38f1c00772539dcbeccbfa3c45d94bdc4acf3518

TBR=caryclark@google.com,reed@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=skia:

Review URL: https://codereview.chromium.org/910493002

src/core/SkEdgeBuilder.cpp
src/core/SkEdgeBuilder.h
src/core/SkLineClipper.cpp
src/core/SkLineClipper.h
src/core/SkScan_Path.cpp

index 00811203b4edd24ccbf39b19113d912a43c79c53..8dcc47a6ce2ccf87a0ce34e5e969817e76c68dad 100644 (file)
@@ -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,
-                             bool clipToTheRight) {
+int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip,
+                             int shiftUp) {
     SkPath::Iter    iter(path, true);
     SkPoint         pts[4];
     SkPath::Verb    verb;
@@ -115,7 +115,7 @@ int SkEdgeBuilder::buildPoly(const SkPath& path, const SkIRect* iclip, int shift
                     break;
                 case SkPath::kLine_Verb: {
                     SkPoint lines[SkLineClipper::kMaxPoints];
-                    int lineCount = SkLineClipper::ClipLine(pts, clip, lines, clipToTheRight);
+                    int lineCount = SkLineClipper::ClipLine(pts, clip, lines);
                     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,
-                         bool clipToTheRight) {
+int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip,
+                         int shiftUp) {
     fAlloc.reset();
     fList.reset();
     fShiftUp = shiftUp;
 
     if (SkPath::kLine_SegmentMask == path.getSegmentMasks()) {
-        return this->buildPoly(path, iclip, shiftUp, clipToTheRight);
+        return this->buildPoly(path, iclip, shiftUp);
     }
 
     SkAutoConicToQuads quadder;
@@ -192,7 +192,7 @@ int SkEdgeBuilder::build(const SkPath& path, const SkIRect* iclip, int shiftUp,
                     break;
                 case SkPath::kLine_Verb: {
                     SkPoint lines[SkLineClipper::kMaxPoints];
-                    int lineCount = SkLineClipper::ClipLine(pts, clip, lines, clipToTheRight);
+                    int lineCount = SkLineClipper::ClipLine(pts, clip, lines);
                     for (int i = 0; i < lineCount; i++) {
                         this->addLine(&lines[i]);
                     }
index 625465b8a6b28357ede6e6524d7a52ca14c5291e..f9e5976e17f6cbb6b0f09cad9ad77eb487ef29f5 100644 (file)
@@ -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, bool clipToTheRight);
+    int build(const SkPath& path, const SkIRect* clip, int shiftUp);
 
     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, bool clipToTheRight);
+    int buildPoly(const SkPath& path, const SkIRect* clip, int shiftUp);
 };
 
 #endif
index 9d72ea513af26546effb630908285521129a7d72..1645917d70f5d60ba9722ef2301f12aa6530355d 100644 (file)
@@ -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[], bool canClipToTheRight) {
+                            SkPoint lines[]) {
 #ifdef SK_DEBUG
     {
         static bool gOnce;
@@ -241,9 +241,6 @@ 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;
index d966dbc74cb1ba10631dd181039dad8ce62e6dfe..8026890b8d0a6f38cf3363a07af70f1701b0bb16 100644 (file)
@@ -30,7 +30,7 @@ public:
             3rd segment: lines[2]..lines[3]
      */
     static int ClipLine(const SkPoint pts[2], const SkRect& clip,
-                        SkPoint lines[kMaxPoints], bool canClipToTheRight);
+                        SkPoint lines[kMaxPoints]);
 
     /*  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,
index bf56aca3f1a71c8916f5d236706ad60e202a25d3..5d9e0ca2a658ae58d81e84d5ba51edc5bfde00cc 100644 (file)
@@ -45,23 +45,34 @@ static inline void remove_edge(SkEdge* edge) {
     edge->fNext->fPrev = edge->fPrev;
 }
 
-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 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 void backward_insert_edge_based_on_x(SkEdge* edge SkDECLAREPARAM(int, curr_y)) {
     SkFixed x = edge->fX;
 
-    SkEdge* prev = edge->fPrev;
-    while (prev->fX > x) {
-        prev = prev->fPrev;
-    }
-    if (prev->fNext != edge) {
-        remove_edge(edge);
-        insert_edge_after(edge, prev);
+    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);
     }
 }
 
@@ -102,7 +113,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, int rightClip) {
+                       PrePostProc proc) {
     validate_sort(prevHead->fNext);
 
     int curr_y = start_y;
@@ -172,14 +183,6 @@ 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
         }
@@ -433,10 +436,7 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
 
     SkEdgeBuilder   builder;
 
-    // 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);
+    int count = builder.build(path, clipRect, shiftEdgesUp);
     SkEdge**    list = builder.edgeList();
 
     if (count < 2) {
@@ -500,17 +500,10 @@ void sk_fill_path(const SkPath& path, const SkIRect* clipRect, SkBlitter* blitte
         proc = PrePostInverseBlitterProc;
     }
 
-    int rightEdge;
-    if (clipRect) {
-        rightEdge = clipRect->right();
-    } else {
-        rightEdge = SkScalarRoundToInt(path.getBounds().right());
-    }
-
     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, rightEdge);
+        walk_edges(&headEdge, path.getFillType(), blitter, start_y, stop_y, proc);
     }
 }