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

Unified Diff: src/gpu/GrShape.cpp

Issue 2064113004: Some simplifications of GrShape reductions/canonicalizations (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: 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 7be7e7ad041931a04316b5aeaa2a0d77986a4f4d..395089cf49bc8412aa63b6f9cbf3438c20092a65 100644
--- a/src/gpu/GrShape.cpp
+++ b/src/gpu/GrShape.cpp
@@ -227,36 +227,25 @@ GrShape::GrShape(const GrShape& parent, GrStyle::Apply apply, SkScalar scale) {
// A path effect has access to change the res scale but we aren't expecting it to and it
// would mess up our key computation.
SkASSERT(scale == strokeRec.getResScale());
- if (GrStyle::Apply::kPathEffectAndStrokeRec == apply) {
- if (strokeRec.needToApply()) {
- // The intermediate shape may not be a general path. If we we're just applying
- // the path effect then attemptToReduceFromPath would catch it. This means that
- // when we subsequently applied the remaining strokeRec we would have a non-path
- // parent shape that would be used to determine the the stroked path's key.
- // We detect that case here and change parentForKey to a temporary that represents
- // the simpler shape so that applying both path effect and the strokerec all at
- // once produces the same key.
- SkRRect rrect;
- SkPath::Direction dir;
- unsigned start;
- bool inverted;
- Type parentType = AttemptToReduceFromPathImpl(*fPath.get(), &rrect, &dir, &start,
- &inverted, nullptr, strokeRec);
- switch (parentType) {
- case Type::kEmpty:
- tmpParent.init();
- parentForKey = tmpParent.get();
- break;
- case Type::kRRect:
- tmpParent.init(rrect, dir, start, inverted, GrStyle(strokeRec, nullptr));
- parentForKey = tmpParent.get();
- case Type::kPath:
- break;
- }
- SkAssertResult(strokeRec.applyToPath(fPath.get(), *fPath.get()));
- } else {
- fStyle = GrStyle(strokeRec, nullptr);
+ if (GrStyle::Apply::kPathEffectAndStrokeRec == apply && strokeRec.needToApply()) {
+ // The intermediate shape may not be a general path. If we we're just applying
+ // the path effect then attemptToReduceFromPath would catch it. This means that
+ // when we subsequently applied the remaining strokeRec we would have a non-path
+ // parent shape that would be used to determine the the stroked path's key.
+ // We detect that case here and change parentForKey to a temporary that represents
+ // the simpler shape so that applying both path effect and the strokerec all at
+ // once produces the same key.
+ tmpParent.init(*fPath.get(), GrStyle(strokeRec, nullptr));
+ tmpParent.get()->setInheritedKey(parent, GrStyle::Apply::kPathEffectOnly, scale);
+ if (!tmpPath.isValid()) {
+ tmpPath.init();
}
+ tmpParent.get()->asPath(tmpPath.get());
+ SkStrokeRec::InitStyle fillOrHairline;
+ SkAssertResult(tmpParent.get()->style().applyToPath(fPath.get(), &fillOrHairline,
+ *tmpPath.get(), scale));
+ fStyle.resetToInitStyle(fillOrHairline);
+ parentForKey = tmpParent.get();
} else {
fStyle = GrStyle(strokeRec, nullptr);
}
@@ -275,84 +264,72 @@ GrShape::GrShape(const GrShape& parent, GrStyle::Apply apply, SkScalar scale) {
scale));
fStyle.resetToInitStyle(fillOrHairline);
}
- this->attemptToReduceFromPath();
+ this->attemptToSimplifyPath();
this->setInheritedKey(*parentForKey, apply, scale);
}
-static inline bool rrect_path_is_inverse_filled(const SkPath& path, const SkStrokeRec& strokeRec,
- const SkPathEffect* pe) {
- // This is currently imitating the questionable behavior of the sw-rasterizer. Inverseness is
- // respected for stroking but not dashing + stroking. (We make no assumptions about arbitrary
- // path effects and preserve the path's inverseness.)
- // skbug.com/5421
- if (pe && pe->asADash(nullptr)) {
- SkDEBUGCODE(SkStrokeRec::Style style = strokeRec.getStyle();)
- SkASSERT(SkStrokeRec::kStroke_Style == style || SkStrokeRec::kHairline_Style == style);
- 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()) {
- return Type::kEmpty;
- }
- if (path.isRRect(rrect, rrectDir, rrectStart)) {
+void GrShape::attemptToSimplifyPath() {
+ SkASSERT(Type::kPath == fType);
+ SkRect rect;
+ if (fPath.get()->isEmpty()) {
+ fType = Type::kEmpty;
+ } else if (fPath.get()->isRRect(&fRRect, &fRRectDir, &fRRectStart)) {
// Currently SkPath does not acknowledge that empty, rect, or oval subtypes as rrects.
- SkASSERT(!rrect->isEmpty());
- SkASSERT(rrect->getType() != SkRRect::kRect_Type);
- SkASSERT(rrect->getType() != SkRRect::kOval_Type);
- if (!pe) {
- *rrectStart = DefaultRRectDirAndStartIndex(*rrect, false, rrectDir);
+ SkASSERT(!fRRect.isEmpty());
+ SkASSERT(fRRect.getType() != SkRRect::kRect_Type);
+ SkASSERT(fRRect.getType() != SkRRect::kOval_Type);
+ fRRectIsInverted = fPath.get()->isInverseFillType();
+ fType = Type::kRRect;
+ } else if (fPath.get()->isOval(&rect, &fRRectDir, &fRRectStart)) {
+ fRRect.setOval(rect);
+ fRRectIsInverted = fPath.get()->isInverseFillType();
+ // convert from oval indexing to rrect indexiing.
+ fRRectStart *= 2;
+ fType = Type::kRRect;
+ } else if (SkPathPriv::IsSimpleClosedRect(*fPath.get(), &rect, &fRRectDir, &fRRectStart)) {
+ // When there is a path effect we restrict rect detection to the narrower API that
+ // gives us the starting position. Otherwise, we will retry with the more aggressive
+ // isRect().
+ fRRect.setRect(rect);
+ fRRectIsInverted = fPath.get()->isInverseFillType();
+ // convert from rect indexing to rrect indexiing.
+ fRRectStart *= 2;
+ fType = Type::kRRect;
+ } else if (!this->style().hasPathEffect()) {
+ bool closed;
+ if (fPath.get()->isRect(&rect, &closed, nullptr)) {
+ if (closed || this->style().isSimpleFill()) {
+ fRRect.setRect(rect);
+ // Since there is no path effect the dir and start index is immaterial.
+ fRRectDir = kDefaultRRectDir;
+ fRRectStart = kDefaultRRectStart;
+ // There isn't dashing so we will have to preserver inverseness.
+ fRRectIsInverted = fPath.get()->isInverseFillType();
+ fType = Type::kRRect;
+ }
}
- *rrectIsInverted = rrect_path_is_inverse_filled(path, strokeRec, pe);
- return Type::kRRect;
}
- SkRect rect;
- if (path.isOval(&rect, rrectDir, rrectStart)) {
- rrect->setOval(rect);
- if (!pe) {
- *rrectDir = kDefaultRRectDir;
- *rrectStart = kDefaultRRectStart;
- } else {
- // convert from oval indexing to rrect indexiing.
- *rrectStart *= 2;
+ if (Type::kPath != fType) {
+ fPath.reset();
+ fInheritedKey.reset(0);
+ if (Type::kRRect == fType) {
+ this->attemptToSimplifyRRect();
}
- *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
- // gives us the starting position. Otherwise, we will retry with the more aggressive isRect().
- if (SkPathPriv::IsSimpleClosedRect(path, &rect, rrectDir, rrectStart)) {
- if (!pe) {
- *rrectDir = kDefaultRRectDir;
- *rrectStart = kDefaultRRectStart;
- } else {
- // convert from rect indexing to rrect indexiing.
- *rrectStart *= 2;
- }
- rrect->setRect(rect);
- *rrectIsInverted = rrect_path_is_inverse_filled(path, strokeRec, pe);
- return Type::kRRect;
+}
+
+void GrShape::attemptToSimplifyRRect() {
+ SkASSERT(Type::kRRect == fType);
+ SkASSERT(!fInheritedKey.count());
+ if (fRRect.isEmpty()) {
+ fType = Type::kEmpty;
+ return;
}
- if (!pe) {
- bool closed;
- if (path.isRect(&rect, &closed, nullptr)) {
- if (closed || strokeRec.isFillStyle()) {
- rrect->setRect(rect);
- // 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;
- }
- }
+ if (!this->style().hasPathEffect()) {
+ fRRectDir = kDefaultRRectDir;
+ fRRectStart = kDefaultRRectStart;
+ } else if (fStyle.isDashed()) {
+ // Dashing ignores the inverseness (currently). skbug.com/5421
+ fRRectIsInverted = false;
}
- return Type::kPath;
}
« 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