diff options
author | 2016-06-20 12:28:17 -0700 | |
---|---|---|
committer | 2016-06-20 12:28:17 -0700 | |
commit | 1b28c1adc1e156831d5332546e942b63fd29075b (patch) | |
tree | 35371fb05ace084a934a607c8518ce344079a8d7 /src | |
parent | d7ec12e41cce090ec0b2e68e995ea511d33c9967 (diff) |
Some simplifications of GrShape reductions/canonicalizations
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2064113004
Review-Url: https://codereview.chromium.org/2064113004
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrShape.cpp | 175 | ||||
-rw-r--r-- | src/gpu/GrShape.h | 49 |
2 files changed, 88 insertions, 136 deletions
diff --git a/src/gpu/GrShape.cpp b/src/gpu/GrShape.cpp index 7be7e7ad04..395089cf49 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; } diff --git a/src/gpu/GrShape.h b/src/gpu/GrShape.h index 6da1a41acb..6086537a99 100644 --- a/src/gpu/GrShape.h +++ b/src/gpu/GrShape.h @@ -39,7 +39,7 @@ public: explicit GrShape(const SkPath& path) : fType(Type::kPath) , fPath(&path) { - this->attemptToReduceFromPath(); + this->attemptToSimplifyPath(); } explicit GrShape(const SkRRect& rrect) @@ -47,7 +47,7 @@ public: , fRRect(rrect) , fRRectIsInverted(false) { fRRectStart = DefaultRRectDirAndStartIndex(rrect, false, &fRRectDir); - this->attemptToReduceFromRRect(); + this->attemptToSimplifyRRect(); } explicit GrShape(const SkRect& rect) @@ -55,14 +55,14 @@ public: , fRRect(SkRRect::MakeRect(rect)) , fRRectIsInverted(false) { fRRectStart = DefaultRectDirAndStartIndex(rect, false, &fRRectDir); - this->attemptToReduceFromRRect(); + this->attemptToSimplifyRRect(); } GrShape(const SkPath& path, const GrStyle& style) : fType(Type::kPath) , fPath(&path) , fStyle(style) { - this->attemptToReduceFromPath(); + this->attemptToSimplifyPath(); } GrShape(const SkRRect& rrect, const GrStyle& style) @@ -71,7 +71,7 @@ public: , fRRectIsInverted(false) , fStyle(style) { fRRectStart = DefaultRRectDirAndStartIndex(rrect, style.hasPathEffect(), &fRRectDir); - this->attemptToReduceFromRRect(); + this->attemptToSimplifyRRect(); } GrShape(const SkRRect& rrect, SkPath::Direction dir, unsigned start, bool inverted, @@ -91,7 +91,7 @@ public: } else { fRRectStart = DefaultRRectDirAndStartIndex(rrect, false, &fRRectDir); } - this->attemptToReduceFromRRect(); + this->attemptToSimplifyRRect(); } GrShape(const SkRect& rect, const GrStyle& style) @@ -100,14 +100,14 @@ public: , fRRectIsInverted(false) , fStyle(style) { fRRectStart = DefaultRectDirAndStartIndex(rect, style.hasPathEffect(), &fRRectDir); - this->attemptToReduceFromRRect(); + this->attemptToSimplifyRRect(); } GrShape(const SkPath& path, const SkPaint& paint) : fType(Type::kPath) , fPath(&path) , fStyle(paint) { - this->attemptToReduceFromPath(); + this->attemptToSimplifyPath(); } GrShape(const SkRRect& rrect, const SkPaint& paint) @@ -116,7 +116,7 @@ public: , fRRectIsInverted(false) , fStyle(paint) { fRRectStart = DefaultRRectDirAndStartIndex(rrect, fStyle.hasPathEffect(), &fRRectDir); - this->attemptToReduceFromRRect(); + this->attemptToSimplifyRRect(); } GrShape(const SkRect& rect, const SkPaint& paint) @@ -125,7 +125,7 @@ public: , fRRectIsInverted(false) , fStyle(paint) { fRRectStart = DefaultRectDirAndStartIndex(rect, fStyle.hasPathEffect(), &fRRectDir); - this->attemptToReduceFromRRect(); + this->attemptToSimplifyRRect(); } GrShape(const GrShape&); @@ -278,34 +278,9 @@ private: */ void setInheritedKey(const GrShape& parentShape, GrStyle::Apply, SkScalar scale); - void attemptToReduceFromPath() { - SkASSERT(Type::kPath == fType); - fType = AttemptToReduceFromPathImpl(*fPath.get(), &fRRect, &fRRectDir, &fRRectStart, - &fRRectIsInverted, fStyle.pathEffect(), - fStyle.strokeRec()); - if (Type::kPath != fType) { - fPath.reset(); - fInheritedKey.reset(0); - } - } - - void attemptToReduceFromRRect() { - SkASSERT(Type::kRRect == fType); - SkASSERT(!fInheritedKey.count()); - if (fRRectIsInverted) { - if (fStyle.isDashed()) { - // Dashing ignores the inverseness (currently). skbug.com/5421 - fRRectIsInverted = false; - } - } else if (fRRect.isEmpty()) { - fType = Type::kEmpty; - } - } + void attemptToSimplifyPath(); - static Type AttemptToReduceFromPathImpl(const SkPath& path, SkRRect* rrect, - SkPath::Direction* rrectDir, unsigned* rrectStart, - bool* rrectIsInverted, const SkPathEffect* pe, - const SkStrokeRec& strokeRec); + void attemptToSimplifyRRect(); static constexpr SkPath::Direction kDefaultRRectDir = SkPath::kCW_Direction; static constexpr unsigned kDefaultRRectStart = 0; |