| Index: src/gpu/GrShape.cpp
 | 
| diff --git a/src/gpu/GrShape.cpp b/src/gpu/GrShape.cpp
 | 
| index 5ffd32d46de2f36b61f8093d614e8e408624f49d..45ddb777789214c95714a2e75cd7fc20d329b519 100644
 | 
| --- a/src/gpu/GrShape.cpp
 | 
| +++ b/src/gpu/GrShape.cpp
 | 
| @@ -14,10 +14,10 @@
 | 
|          case Type::kEmpty:
 | 
|              break;
 | 
|          case Type::kRRect:
 | 
| -            fRRectData = that.fRRectData;
 | 
| -            break;
 | 
| -        case Type::kLine:
 | 
| -            fLineData = that.fLineData;
 | 
| +            fRRectData.fRRect = that.fRRectData.fRRect;
 | 
| +            fRRectData.fDir = that.fRRectData.fDir;
 | 
| +            fRRectData.fStart = that.fRRectData.fStart;
 | 
| +            fRRectData.fInverted = that.fRRectData.fInverted;
 | 
|              break;
 | 
|          case Type::kPath:
 | 
|              fPathData.fGenID = that.fPathData.fGenID;
 | 
| @@ -29,29 +29,11 @@
 | 
|      return *this;
 | 
|  }
 | 
|  
 | 
| -SkRect GrShape::bounds() const {
 | 
| +const SkRect& GrShape::bounds() const {
 | 
|      static constexpr SkRect kEmpty = SkRect::MakeEmpty();
 | 
|      switch (fType) {
 | 
|          case Type::kEmpty:
 | 
|              return kEmpty;
 | 
| -        case Type::kLine: {
 | 
| -            SkRect bounds;
 | 
| -            if (fLineData.fPts[0].fX < fLineData.fPts[1].fX) {
 | 
| -                bounds.fLeft = fLineData.fPts[0].fX;
 | 
| -                bounds.fRight = fLineData.fPts[1].fX;
 | 
| -            } else {
 | 
| -                bounds.fLeft = fLineData.fPts[1].fX;
 | 
| -                bounds.fRight = fLineData.fPts[0].fX;
 | 
| -            }
 | 
| -            if (fLineData.fPts[0].fY < fLineData.fPts[1].fY) {
 | 
| -                bounds.fTop = fLineData.fPts[0].fY;
 | 
| -                bounds.fBottom = fLineData.fPts[1].fY;
 | 
| -            } else {
 | 
| -                bounds.fTop = fLineData.fPts[1].fY;
 | 
| -                bounds.fBottom = fLineData.fPts[0].fY;
 | 
| -            }
 | 
| -            return bounds;
 | 
| -        }
 | 
|          case Type::kRRect:
 | 
|              return fRRectData.fRRect.getBounds();
 | 
|          case Type::kPath:
 | 
| @@ -61,13 +43,12 @@
 | 
|      return kEmpty;
 | 
|  }
 | 
|  
 | 
| -SkRect GrShape::styledBounds() const {
 | 
| +void GrShape::styledBounds(SkRect* bounds) const {
 | 
|      if (Type::kEmpty == fType && !fStyle.hasNonDashPathEffect()) {
 | 
| -        return SkRect::MakeEmpty();
 | 
| -    }
 | 
| -    SkRect bounds;
 | 
| -    fStyle.adjustBounds(&bounds, this->bounds());
 | 
| -    return bounds;
 | 
| +        *bounds = SkRect::MakeEmpty();
 | 
| +    } else {
 | 
| +        fStyle.adjustBounds(bounds, this->bounds());
 | 
| +    }
 | 
|  }
 | 
|  
 | 
|  int GrShape::unstyledKeySize() const {
 | 
| @@ -82,10 +63,6 @@
 | 
|              SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
 | 
|              // + 1 for the direction, start index, and inverseness.
 | 
|              return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1;
 | 
| -        case Type::kLine:
 | 
| -            GR_STATIC_ASSERT(2 * sizeof(uint32_t) == sizeof(SkPoint));
 | 
| -            // 4 for the end points and 1 for the inverseness
 | 
| -            return 5;
 | 
|          case Type::kPath:
 | 
|              if (0 == fPathData.fGenID) {
 | 
|                  return -1;
 | 
| @@ -117,11 +94,6 @@
 | 
|                  *key++ |= fRRectData.fStart;
 | 
|                  SkASSERT(fRRectData.fStart < 8);
 | 
|                  break;
 | 
| -            case Type::kLine:
 | 
| -                memcpy(key, fLineData.fPts, 2 * sizeof(SkPoint));
 | 
| -                key += 4;
 | 
| -                *key++ = fLineData.fInverted ? 1 : 0;
 | 
| -                break;
 | 
|              case Type::kPath:
 | 
|                  SkASSERT(fPathData.fGenID);
 | 
|                  *key++ = fPathData.fGenID;
 | 
| @@ -187,10 +159,10 @@
 | 
|          case Type::kEmpty:
 | 
|              break;
 | 
|          case Type::kRRect:
 | 
| -            fRRectData = that.fRRectData;
 | 
| -            break;
 | 
| -        case Type::kLine:
 | 
| -            fLineData = that.fLineData;
 | 
| +            fRRectData.fRRect = that.fRRectData.fRRect;
 | 
| +            fRRectData.fDir = that.fRRectData.fDir;
 | 
| +            fRRectData.fStart = that.fRRectData.fStart;
 | 
| +            fRRectData.fInverted = that.fRRectData.fInverted;
 | 
|              break;
 | 
|          case Type::kPath:
 | 
|              fPathData.fGenID = that.fPathData.fGenID;
 | 
| @@ -294,14 +266,8 @@
 | 
|      SkPath::Direction rrectDir;
 | 
|      unsigned rrectStart;
 | 
|      bool inverted = this->path().isInverseFillType();
 | 
| -    SkPoint pts[2];
 | 
|      if (this->path().isEmpty()) {
 | 
|          this->changeType(Type::kEmpty);
 | 
| -    } else if (this->path().isLine(pts)) {
 | 
| -        this->changeType(Type::kLine);
 | 
| -        fLineData.fPts[0] = pts[0];
 | 
| -        fLineData.fPts[1] = pts[1];
 | 
| -        fLineData.fInverted = inverted;
 | 
|      } else if (this->path().isRRect(&rrect, &rrectDir, &rrectStart)) {
 | 
|          this->changeType(Type::kRRect);
 | 
|          fRRectData.fRRect = rrect;
 | 
| @@ -347,8 +313,6 @@
 | 
|          fInheritedKey.reset(0);
 | 
|          if (Type::kRRect == fType) {
 | 
|              this->attemptToSimplifyRRect();
 | 
| -        } else if (Type::kLine == fType) {
 | 
| -            this->attemptToSimplifyLine();
 | 
|          }
 | 
|      } else {
 | 
|          if (fInheritedKey.count() || this->path().isVolatile()) {
 | 
| @@ -357,8 +321,13 @@
 | 
|              fPathData.fGenID = this->path().getGenerationID();
 | 
|          }
 | 
|          if (this->style().isSimpleFill()) {
 | 
| -            this->path().close();
 | 
| -            this->path().setIsVolatile(true);
 | 
| +            // Filled paths are treated as though all their contours were closed.
 | 
| +            // Since SkPath doesn't track individual contours, this will only close the last. :(
 | 
| +            // There is no point in closing lines, though, since they loose their line-ness.
 | 
| +            if (!this->path().isLine(nullptr)) {
 | 
| +                this->path().close();
 | 
| +                this->path().setIsVolatile(true);
 | 
| +            }
 | 
|          }
 | 
|          if (!this->style().hasNonDashPathEffect()) {
 | 
|              if (this->style().strokeRec().getStyle() == SkStrokeRec::kStroke_Style ||
 | 
| @@ -399,21 +368,3 @@
 | 
|          fRRectData.fInverted = false;
 | 
|      }
 | 
|  }
 | 
| -
 | 
| -void GrShape::attemptToSimplifyLine() {
 | 
| -    if (fStyle.isSimpleFill() && !fLineData.fInverted) {
 | 
| -        this->changeType(Type::kEmpty);
 | 
| -    } else {
 | 
| -        // Only path effects could care about the order of the points. Otherwise canonicalize
 | 
| -        // the point order
 | 
| -        if (!fStyle.hasPathEffect()) {
 | 
| -            SkPoint* pts = fLineData.fPts;
 | 
| -            if (pts[1].fY < pts[0].fY || (pts[1].fY == pts[0].fY && pts[1].fX < pts[0].fX)) {
 | 
| -                SkTSwap(pts[0], pts[1]);
 | 
| -            }
 | 
| -        } else if (fStyle.isDashed()) {
 | 
| -            // Dashing ignores inverseness.
 | 
| -            fLineData.fInverted = false;
 | 
| -        }
 | 
| -    }
 | 
| -}
 | 
| 
 |