Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(259)

Unified Diff: src/gpu/GrShape.cpp

Issue 2056523002: Make GrShape capable of representing inverse filled rrects. (Closed) Base URL: https://chromium.googlesource.com/skia.git@faildashstrokeandfill
Patch Set: Fix windows warning Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrShape.h ('k') | tests/GrShapeTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrShape.cpp
diff --git a/src/gpu/GrShape.cpp b/src/gpu/GrShape.cpp
index 7605cbf1ffabebfc7ec3d12713cef8fa94150c96..d2bec72cbfea4a6f51377339532a2159e6f0c37a 100644
--- a/src/gpu/GrShape.cpp
+++ b/src/gpu/GrShape.cpp
@@ -24,6 +24,7 @@ GrShape& GrShape::operator=(const GrShape& that) {
fRRect = that.fRRect;
fRRectDir = that.fRRectDir;
fRRectStart = that.fRRectStart;
+ fRRectIsInverted = that.fRRectIsInverted;
break;
case Type::kPath:
if (wasPath) {
@@ -71,13 +72,14 @@ int GrShape::unstyledKeySize() const {
case Type::kRRect:
SkASSERT(!fInheritedKey.count());
SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
- // + 1 for the direction + start index.
+ // + 1 for the direction, start index, and inverseness.
return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1;
case Type::kPath:
if (fPath.get()->isVolatile()) {
return -1;
} else {
- return 1;
+ // The key is the path ID and fill type.
+ return 2;
}
}
SkFAIL("Should never get here.");
@@ -99,12 +101,16 @@ void GrShape::writeUnstyledKey(uint32_t* key) const {
fRRect.writeToMemory(key);
key += SkRRect::kSizeInMemory / sizeof(uint32_t);
*key = (fRRectDir == SkPath::kCCW_Direction) ? (1 << 31) : 0;
+ *key |= fRRectIsInverted ? (1 << 30) : 0;
*key++ |= fRRectStart;
SkASSERT(fRRectStart < 8);
break;
case Type::kPath:
SkASSERT(!fPath.get()->isVolatile());
*key++ = fPath.get()->getGenerationID();
+ // 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();
break;
}
}
@@ -163,6 +169,9 @@ GrShape::GrShape(const GrShape& that) : fType(that.fType), fStyle(that.fStyle) {
return;
case Type::kRRect:
fRRect = that.fRRect;
+ fRRectDir = that.fRRectDir;
+ fRRectStart = that.fRRectStart;
+ fRRectIsInverted = that.fRRectIsInverted;
return;
case Type::kPath:
fPath.set(*that.fPath.get());
@@ -230,15 +239,16 @@ GrShape::GrShape(const GrShape& parent, GrStyle::Apply apply, SkScalar scale) {
SkRRect rrect;
SkPath::Direction dir;
unsigned start;
+ bool inverted;
Type parentType = AttemptToReduceFromPathImpl(*fPath.get(), &rrect, &dir, &start,
- nullptr, strokeRec);
+ &inverted, nullptr, strokeRec);
switch (parentType) {
case Type::kEmpty:
tmpParent.init();
parentForKey = tmpParent.get();
break;
case Type::kRRect:
- tmpParent.init(rrect, dir, start, GrStyle(strokeRec, nullptr));
+ tmpParent.init(rrect, dir, start, inverted, GrStyle(strokeRec, nullptr));
parentForKey = tmpParent.get();
case Type::kPath:
break;
@@ -269,9 +279,25 @@ GrShape::GrShape(const GrShape& parent, GrStyle::Apply apply, SkScalar scale) {
this->setInheritedKey(*parentForKey, apply, scale);
}
+static inline bool rrect_path_is_inverse_filled(const SkPath& path, const SkStrokeRec& strokeRec,
+ const SkPathEffect* pe) {
+ // Dashing doesn't use the path fill type. Dashing only works with stroking
+ if (pe && pe->asADash(nullptr)) {
+ pe = nullptr;
+ }
+
+ SkStrokeRec::Style style = strokeRec.getStyle();
+ if (!pe && (SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style)) {
+ // stroking ignores the path fill rule.
+ return false;
+ }
+ return path.isInverseFillType();
+}
+
GrShape::Type GrShape::AttemptToReduceFromPathImpl(const SkPath& path, SkRRect* rrect,
SkPath::Direction* rrectDir,
unsigned* rrectStart,
+ bool* rrectIsInverted,
const SkPathEffect* pe,
const SkStrokeRec& strokeRec) {
if (path.isEmpty()) {
@@ -285,6 +311,7 @@ GrShape::Type GrShape::AttemptToReduceFromPathImpl(const SkPath& path, SkRRect*
if (!pe) {
*rrectStart = DefaultRRectDirAndStartIndex(*rrect, false, rrectDir);
}
+ *rrectIsInverted = rrect_path_is_inverse_filled(path, strokeRec, pe);
return Type::kRRect;
}
SkRect rect;
@@ -297,6 +324,7 @@ GrShape::Type GrShape::AttemptToReduceFromPathImpl(const SkPath& path, SkRRect*
// convert from oval indexing to rrect indexiing.
*rrectStart *= 2;
}
+ *rrectIsInverted = rrect_path_is_inverse_filled(path, strokeRec, pe);
return Type::kRRect;
}
// When there is a path effect we restrict rect detection to the narrower API that
@@ -310,6 +338,7 @@ GrShape::Type GrShape::AttemptToReduceFromPathImpl(const SkPath& path, SkRRect*
*rrectStart *= 2;
}
rrect->setRect(rect);
+ *rrectIsInverted = rrect_path_is_inverse_filled(path, strokeRec, pe);
return Type::kRRect;
}
if (!pe) {
@@ -320,6 +349,7 @@ GrShape::Type GrShape::AttemptToReduceFromPathImpl(const SkPath& path, SkRRect*
// Since there is no path effect the dir and start index is immaterial.
*rrectDir = kDefaultRRectDir;
*rrectStart = kDefaultRRectStart;
+ *rrectIsInverted = rrect_path_is_inverse_filled(path, strokeRec, pe);
return Type::kRRect;
}
}
« no previous file with comments | « src/gpu/GrShape.h ('k') | tests/GrShapeTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698