Index: src/gpu/GrShape.cpp |
diff --git a/src/gpu/GrShape.cpp b/src/gpu/GrShape.cpp |
index 395089cf49bc8412aa63b6f9cbf3438c20092a65..0fb339555ecf0dc4f6609c012adbbcaf33517f02 100644 |
--- a/src/gpu/GrShape.cpp |
+++ b/src/gpu/GrShape.cpp |
@@ -32,6 +32,7 @@ GrShape& GrShape::operator=(const GrShape& that) { |
} else { |
fPath.set(*that.fPath.get()); |
} |
+ fPathGenID = that.fPathGenID; |
break; |
} |
fInheritedKey.reset(that.fInheritedKey.count()); |
@@ -75,7 +76,7 @@ int GrShape::unstyledKeySize() const { |
// + 1 for the direction, start index, and inverseness. |
return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1; |
case Type::kPath: |
- if (fPath.get()->isVolatile()) { |
+ if (0 == fPathGenID) { |
return -1; |
} else { |
// The key is the path ID and fill type. |
@@ -106,8 +107,8 @@ void GrShape::writeUnstyledKey(uint32_t* key) const { |
SkASSERT(fRRectStart < 8); |
break; |
case Type::kPath: |
- SkASSERT(!fPath.get()->isVolatile()); |
- *key++ = fPath.get()->getGenerationID(); |
+ SkASSERT(fPathGenID); |
+ *key++ = fPathGenID; |
// We could canonicalize the fill rule for paths that don't differentiate between |
// even/odd or winding fill (e.g. convex). |
*key++ = fPath.get()->getFillType(); |
@@ -133,7 +134,7 @@ void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca |
parentCnt = parent.unstyledKeySize(); |
if (parentCnt < 0) { |
// The parent's geometry has no key so we will have no key. |
- fPath.get()->setIsVolatile(true); |
+ fPathGenID = 0; |
return; |
} |
} |
@@ -143,9 +144,9 @@ void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca |
} |
int styleCnt = GrStyle::KeySize(parent.fStyle, apply, styleKeyFlags); |
if (styleCnt < 0) { |
- // The style doesn't allow a key, set the path to volatile so that we fail when |
+ // The style doesn't allow a key, set the path gen ID to 0 so that we fail when |
// we try to get a key for the shape. |
- fPath.get()->setIsVolatile(true); |
+ fPathGenID = 0; |
return; |
} |
fInheritedKey.reset(parentCnt + styleCnt); |
@@ -166,20 +167,21 @@ void GrShape::setInheritedKey(const GrShape &parent, GrStyle::Apply apply, SkSca |
GrShape::GrShape(const GrShape& that) : fType(that.fType), fStyle(that.fStyle) { |
switch (fType) { |
case Type::kEmpty: |
- return; |
+ break; |
case Type::kRRect: |
fRRect = that.fRRect; |
fRRectDir = that.fRRectDir; |
fRRectStart = that.fRRectStart; |
fRRectIsInverted = that.fRRectIsInverted; |
- return; |
+ break; |
case Type::kPath: |
fPath.set(*that.fPath.get()); |
- return; |
+ fPathGenID = that.fPathGenID; |
+ break; |
} |
fInheritedKey.reset(that.fInheritedKey.count()); |
- memcpy(fInheritedKey.get(), that.fInheritedKey.get(), |
- sizeof(uint32_t) * fInheritedKey.count()); |
+ sk_careful_memcpy(fInheritedKey.get(), that.fInheritedKey.get(), |
+ sizeof(uint32_t) * fInheritedKey.count()); |
} |
GrShape::GrShape(const GrShape& parent, GrStyle::Apply apply, SkScalar scale) { |
@@ -315,6 +317,44 @@ void GrShape::attemptToSimplifyPath() { |
if (Type::kRRect == fType) { |
this->attemptToSimplifyRRect(); |
} |
+ } else { |
+ if (fInheritedKey.count() || fPath.get()->isVolatile()) { |
+ fPathGenID = 0; |
+ } else { |
+ fPathGenID = fPath.get()->getGenerationID(); |
+ } |
+ if (this->style().isSimpleFill()) { |
+ // 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. |
bsalomon
2016/06/20 20:18:58
In the future we'll extract the line during simpli
|
+ if (!fPath.get()->isLine(nullptr)) { |
+ fPath.get()->close(); |
+ fPath.get()->setIsVolatile(true); |
+ } |
+ } |
+ if (fPath.get()->isConvex()) { |
+ // There is no distinction between even/odd and non-zero winding count for convex |
+ // paths. |
+ if (fPath.get()->isInverseFillType()) { |
+ fPath.get()->setFillType(SkPath::kInverseEvenOdd_FillType); |
+ } else { |
+ fPath.get()->setFillType(SkPath::kEvenOdd_FillType); |
+ } |
+ } |
+ if (this->style().isDashed()) { |
+ // Dashing ignores inverseness (skbug.com/5421) |
+ switch (fPath.get()->getFillType()) { |
+ case SkPath::kWinding_FillType: |
+ case SkPath::kEvenOdd_FillType: |
+ break; |
+ case SkPath::kInverseWinding_FillType: |
+ fPath.get()->setFillType(SkPath::kWinding_FillType); |
+ break; |
+ case SkPath::kInverseEvenOdd_FillType: |
+ fPath.get()->setFillType(SkPath::kEvenOdd_FillType); |
+ break; |
+ } |
+ } |
} |
} |