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

Unified Diff: src/gpu/GrShape.cpp

Issue 2042813002: Make GrShape track the winding direction and starting point for rrect types. (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: Fix more MSVS warnings 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') | src/gpu/GrStyle.h » ('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 e0ddc55e028e2a1b1ce24be5bd831dc9ea4d0620..9fcc6ee91158aca88bcea7366a9fadbf31936b3f 100644
--- a/src/gpu/GrShape.cpp
+++ b/src/gpu/GrShape.cpp
@@ -22,6 +22,8 @@ GrShape& GrShape::operator=(const GrShape& that) {
fPath.reset();
}
fRRect = that.fRRect;
+ fRRectDir = that.fRRectDir;
+ fRRectStart = that.fRRectStart;
break;
case Type::kPath:
if (wasPath) {
@@ -69,7 +71,8 @@ int GrShape::unstyledKeySize() const {
case Type::kRRect:
SkASSERT(!fInheritedKey.count());
SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
- return SkRRect::kSizeInMemory / sizeof(uint32_t);
+ // + 1 for the direction + start index.
+ return SkRRect::kSizeInMemory / sizeof(uint32_t) + 1;
case Type::kPath:
if (fPath.get()->isVolatile()) {
return -1;
@@ -95,6 +98,9 @@ void GrShape::writeUnstyledKey(uint32_t* key) const {
case Type::kRRect:
fRRect.writeToMemory(key);
key += SkRRect::kSizeInMemory / sizeof(uint32_t);
+ *key = (fRRectDir == SkPath::kCCW_Direction) ? (1 << 31) : 0;
+ *key++ |= fRRectStart;
+ SkASSERT(fRRectStart < 8);
break;
case Type::kPath:
SkASSERT(!fPath.get()->isVolatile());
@@ -217,15 +223,17 @@ GrShape::GrShape(const GrShape& parent, GrStyle::Apply apply, SkScalar scale) {
// the simpler shape so that applying both path effect and the strokerec all at
// once produces the same key.
SkRRect rrect;
- Type parentType = AttemptToReduceFromPathImpl(*fPath.get(), &rrect, nullptr,
- strokeRec);
+ SkPath::Direction dir;
+ unsigned start;
+ Type parentType = AttemptToReduceFromPathImpl(*fPath.get(), &rrect, &dir, &start,
+ nullptr, strokeRec);
switch (parentType) {
case Type::kEmpty:
tmpParent.init();
parentForKey = tmpParent.get();
break;
case Type::kRRect:
- tmpParent.init(rrect, GrStyle(strokeRec, nullptr));
+ tmpParent.init(rrect, dir, start, GrStyle(strokeRec, nullptr));
parentForKey = tmpParent.get();
case Type::kPath:
break;
@@ -255,3 +263,61 @@ GrShape::GrShape(const GrShape& parent, GrStyle::Apply apply, SkScalar scale) {
this->attemptToReduceFromPath();
this->setInheritedKey(*parentForKey, apply, scale);
}
+
+GrShape::Type GrShape::AttemptToReduceFromPathImpl(const SkPath& path, SkRRect* rrect,
+ SkPath::Direction* rrectDir,
+ unsigned* rrectStart,
+ const SkPathEffect* pe,
+ const SkStrokeRec& strokeRec) {
+ if (path.isEmpty()) {
+ return Type::kEmpty;
+ }
+ if (path.isRRect(rrect, rrectDir, rrectStart)) {
+ // 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);
+ }
+ 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;
+ }
+ 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);
+ return Type::kRRect;
+ }
+ 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;
+ return Type::kRRect;
+ }
+ }
+ }
+ return Type::kPath;
+}
« no previous file with comments | « src/gpu/GrShape.h ('k') | src/gpu/GrStyle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698