| Index: src/gpu/GrShape.h
|
| diff --git a/src/gpu/GrShape.h b/src/gpu/GrShape.h
|
| index 139b6ed60b9efe4942046ba1c3dfdaedc6f9811f..87ee26e17333a50b7df08cb0bde4b19d51835ced 100644
|
| --- a/src/gpu/GrShape.h
|
| +++ b/src/gpu/GrShape.h
|
| @@ -34,108 +34,88 @@
|
| */
|
| class GrShape {
|
| public:
|
| - GrShape() : fType(Type::kEmpty) {}
|
| + GrShape() { this->initType(Type::kEmpty); }
|
|
|
| - explicit GrShape(const SkPath& path)
|
| - : fType(Type::kPath)
|
| - , fPath(&path) {
|
| - this->attemptToSimplifyPath();
|
| - }
|
| + explicit GrShape(const SkPath& path) : GrShape(path, GrStyle::SimpleFill()) {}
|
|
|
| - explicit GrShape(const SkRRect& rrect)
|
| - : fType(Type::kRRect)
|
| - , fRRect(rrect)
|
| - , fRRectIsInverted(false) {
|
| - fRRectStart = DefaultRRectDirAndStartIndex(rrect, false, &fRRectDir);
|
| - this->attemptToSimplifyRRect();
|
| - }
|
| + explicit GrShape(const SkRRect& rrect) : GrShape(rrect, GrStyle::SimpleFill()) {}
|
|
|
| - explicit GrShape(const SkRect& rect)
|
| - : fType(Type::kRRect)
|
| - , fRRect(SkRRect::MakeRect(rect))
|
| - , fRRectIsInverted(false) {
|
| - fRRectStart = DefaultRectDirAndStartIndex(rect, false, &fRRectDir);
|
| - this->attemptToSimplifyRRect();
|
| - }
|
| + explicit GrShape(const SkRect& rect) : GrShape(rect, GrStyle::SimpleFill()) {}
|
|
|
| - GrShape(const SkPath& path, const GrStyle& style)
|
| - : fType(Type::kPath)
|
| - , fPath(&path)
|
| - , fStyle(style) {
|
| + GrShape(const SkPath& path, const GrStyle& style) : fStyle(style) {
|
| + this->initType(Type::kPath, &path);
|
| this->attemptToSimplifyPath();
|
| }
|
|
|
| GrShape(const SkRRect& rrect, const GrStyle& style)
|
| - : fType(Type::kRRect)
|
| - , fRRect(rrect)
|
| - , fRRectIsInverted(false)
|
| - , fStyle(style) {
|
| - fRRectStart = DefaultRRectDirAndStartIndex(rrect, style.hasPathEffect(), &fRRectDir);
|
| + : fStyle(style) {
|
| + this->initType(Type::kRRect);
|
| + fRRectData.fRRect = rrect;
|
| + fRRectData.fInverted = false;
|
| + fRRectData.fStart = DefaultRRectDirAndStartIndex(rrect, style.hasPathEffect(),
|
| + &fRRectData.fDir);
|
| this->attemptToSimplifyRRect();
|
| }
|
|
|
| GrShape(const SkRRect& rrect, SkPath::Direction dir, unsigned start, bool inverted,
|
| const GrStyle& style)
|
| - : fType(Type::kRRect)
|
| - , fRRect(rrect)
|
| - , fRRectIsInverted(inverted)
|
| - , fStyle(style) {
|
| + : fStyle(style) {
|
| + this->initType(Type::kRRect);
|
| + fRRectData.fRRect = rrect;
|
| + fRRectData.fInverted = inverted;
|
| if (style.pathEffect()) {
|
| - fRRectDir = dir;
|
| - fRRectStart = start;
|
| - if (fRRect.getType() == SkRRect::kRect_Type) {
|
| - fRRectStart = (fRRectStart + 1) & 0b110;
|
| - } else if (fRRect.getType() == SkRRect::kOval_Type) {
|
| - fRRectStart &= 0b110;
|
| + fRRectData.fDir = dir;
|
| + fRRectData.fStart = start;
|
| + if (fRRectData.fRRect.getType() == SkRRect::kRect_Type) {
|
| + fRRectData.fStart = (fRRectData.fStart + 1) & 0b110;
|
| + } else if (fRRectData.fRRect.getType() == SkRRect::kOval_Type) {
|
| + fRRectData.fStart &= 0b110;
|
| }
|
| } else {
|
| - fRRectStart = DefaultRRectDirAndStartIndex(rrect, false, &fRRectDir);
|
| + fRRectData.fStart = DefaultRRectDirAndStartIndex(rrect, false, &fRRectData.fDir);
|
| }
|
| this->attemptToSimplifyRRect();
|
| }
|
|
|
| GrShape(const SkRect& rect, const GrStyle& style)
|
| - : fType(Type::kRRect)
|
| - , fRRect(SkRRect::MakeRect(rect))
|
| - , fRRectIsInverted(false)
|
| - , fStyle(style) {
|
| - fRRectStart = DefaultRectDirAndStartIndex(rect, style.hasPathEffect(), &fRRectDir);
|
| + : fStyle(style) {
|
| + this->initType(Type::kRRect);
|
| + fRRectData.fRRect = SkRRect::MakeRect(rect);
|
| + fRRectData.fInverted = false;
|
| + fRRectData.fStart = DefaultRectDirAndStartIndex(rect, style.hasPathEffect(),
|
| + &fRRectData.fDir);
|
| this->attemptToSimplifyRRect();
|
| }
|
|
|
| - GrShape(const SkPath& path, const SkPaint& paint)
|
| - : fType(Type::kPath)
|
| - , fPath(&path)
|
| - , fStyle(paint) {
|
| + GrShape(const SkPath& path, const SkPaint& paint) : fStyle(paint) {
|
| + this->initType(Type::kPath, &path);
|
| this->attemptToSimplifyPath();
|
| }
|
|
|
| GrShape(const SkRRect& rrect, const SkPaint& paint)
|
| - : fType(Type::kRRect)
|
| - , fRRect(rrect)
|
| - , fRRectIsInverted(false)
|
| - , fStyle(paint) {
|
| - fRRectStart = DefaultRRectDirAndStartIndex(rrect, fStyle.hasPathEffect(), &fRRectDir);
|
| + : fStyle(paint) {
|
| + this->initType(Type::kRRect);
|
| + fRRectData.fRRect = rrect;
|
| + fRRectData.fInverted = false;
|
| + fRRectData.fStart = DefaultRRectDirAndStartIndex(rrect, fStyle.hasPathEffect(),
|
| + &fRRectData.fDir);
|
| this->attemptToSimplifyRRect();
|
| }
|
|
|
| GrShape(const SkRect& rect, const SkPaint& paint)
|
| - : fType(Type::kRRect)
|
| - , fRRect(SkRRect::MakeRect(rect))
|
| - , fRRectIsInverted(false)
|
| - , fStyle(paint) {
|
| - fRRectStart = DefaultRectDirAndStartIndex(rect, fStyle.hasPathEffect(), &fRRectDir);
|
| + : fStyle(paint) {
|
| + this->initType(Type::kRRect);
|
| + fRRectData.fRRect = SkRRect::MakeRect(rect);
|
| + fRRectData.fInverted = false;
|
| + fRRectData.fStart = DefaultRectDirAndStartIndex(rect, fStyle.hasPathEffect(),
|
| + &fRRectData.fDir);
|
| this->attemptToSimplifyRRect();
|
| }
|
|
|
| GrShape(const GrShape&);
|
| GrShape& operator=(const GrShape& that);
|
|
|
| - ~GrShape() {
|
| - if (Type::kPath == fType) {
|
| - fPath.reset();
|
| - }
|
| - }
|
| + ~GrShape() { this->changeType(Type::kEmpty); }
|
|
|
| const GrStyle& style() const { return fStyle; }
|
|
|
| @@ -154,16 +134,16 @@ public:
|
| return false;
|
| }
|
| if (rrect) {
|
| - *rrect = fRRect;
|
| + *rrect = fRRectData.fRRect;
|
| }
|
| if (dir) {
|
| - *dir = fRRectDir;
|
| + *dir = fRRectData.fDir;
|
| }
|
| if (start) {
|
| - *start = fRRectStart;
|
| + *start = fRRectData.fStart;
|
| }
|
| if (inverted) {
|
| - *inverted = fRRectIsInverted;
|
| + *inverted = fRRectData.fInverted;
|
| }
|
| return true;
|
| }
|
| @@ -176,7 +156,7 @@ public:
|
| if (fType != Type::kPath) {
|
| return false;
|
| }
|
| - return fPath.get()->isLine(pts);
|
| + return this->path().isLine(pts);
|
| }
|
|
|
| /** Returns the unstyled geometry as a path. */
|
| @@ -187,16 +167,16 @@ public:
|
| break;
|
| case Type::kRRect:
|
| out->reset();
|
| - out->addRRect(fRRect, fRRectDir, fRRectStart);
|
| + out->addRRect(fRRectData.fRRect, fRRectData.fDir, fRRectData.fStart);
|
| // Below matches the fill type that attemptToSimplifyPath uses.
|
| - if (fRRectIsInverted) {
|
| + if (fRRectData.fInverted) {
|
| out->setFillType(kDefaultPathInverseFillType);
|
| } else {
|
| out->setFillType(kDefaultPathFillType);
|
| }
|
| break;
|
| case Type::kPath:
|
| - *out = *fPath.get();
|
| + *out = this->path();
|
| break;
|
| }
|
| }
|
| @@ -235,8 +215,8 @@ public:
|
| // thus doesn't give the correct answer for stroked paths, hence we also check
|
| // whether the path is either filled or closed. Convex paths may only have one
|
| // contour hence isLastContourClosed() is a sufficient for a convex path.
|
| - return (this->style().isSimpleFill() || fPath.get()->isLastContourClosed()) &&
|
| - fPath.get()->isConvex();
|
| + return (this->style().isSimpleFill() || this->path().isLastContourClosed()) &&
|
| + this->path().isConvex();
|
| }
|
| return false;
|
| }
|
| @@ -249,10 +229,10 @@ public:
|
| ret = false;
|
| break;
|
| case Type::kRRect:
|
| - ret = fRRectIsInverted;
|
| + ret = fRRectData.fInverted;
|
| break;
|
| case Type::kPath:
|
| - ret = this->fPath.get()->isInverseFillType();
|
| + ret = this->path().isInverseFillType();
|
| break;
|
| }
|
| // Dashing ignores inverseness. We should have caught this earlier. skbug.com/5421
|
| @@ -286,7 +266,7 @@ public:
|
| return true;
|
| case Type::kPath:
|
| // SkPath doesn't keep track of the closed status of each contour.
|
| - return SkPathPriv::IsClosedSingleContour(*fPath.get());
|
| + return SkPathPriv::IsClosedSingleContour(this->path());
|
| }
|
| return false;
|
| }
|
| @@ -296,14 +276,14 @@ public:
|
| case Type::kEmpty:
|
| return 0;
|
| case Type::kRRect:
|
| - if (fRRect.getType() == SkRRect::kOval_Type) {
|
| + if (fRRectData.fRRect.getType() == SkRRect::kOval_Type) {
|
| return SkPath::kConic_SegmentMask;
|
| - } else if (fRRect.getType() == SkRRect::kRect_Type) {
|
| + } else if (fRRectData.fRRect.getType() == SkRRect::kRect_Type) {
|
| return SkPath::kLine_SegmentMask;
|
| }
|
| return SkPath::kLine_SegmentMask | SkPath::kConic_SegmentMask;
|
| case Type::kPath:
|
| - return fPath.get()->getSegmentMasks();
|
| + return this->path().getSegmentMasks();
|
| }
|
| return 0;
|
| }
|
| @@ -330,6 +310,41 @@ private:
|
| kPath,
|
| };
|
|
|
| + void initType(Type type, const SkPath* path = nullptr) {
|
| + fType = Type::kEmpty;
|
| + this->changeType(type, path);
|
| + }
|
| +
|
| + void changeType(Type type, const SkPath* path = nullptr) {
|
| + bool wasPath = Type::kPath == fType;
|
| + fType = type;
|
| + bool isPath = Type::kPath == type;
|
| + SkASSERT(!path || isPath);
|
| + if (wasPath && !isPath) {
|
| + fPathData.fPath.~SkPath();
|
| + } else if (!wasPath && isPath) {
|
| + if (path) {
|
| + new (&fPathData.fPath) SkPath(*path);
|
| + } else {
|
| + new (&fPathData.fPath) SkPath();
|
| + }
|
| + } else if (isPath && path) {
|
| + fPathData.fPath = *path;
|
| + }
|
| + // Whether or not we use the path's gen ID is decided in attemptToSimplifyPath.
|
| + fPathData.fGenID = 0;
|
| + }
|
| +
|
| + SkPath& path() {
|
| + SkASSERT(Type::kPath == fType);
|
| + return fPathData.fPath;
|
| + }
|
| +
|
| + const SkPath& path() const {
|
| + SkASSERT(Type::kPath == fType);
|
| + return fPathData.fPath;
|
| + }
|
| +
|
| /** Constructor used by the applyStyle() function */
|
| GrShape(const GrShape& parentShape, GrStyle::Apply, SkScalar scale);
|
|
|
| @@ -393,13 +408,19 @@ private:
|
| }
|
|
|
| Type fType;
|
| - SkRRect fRRect;
|
| - SkPath::Direction fRRectDir;
|
| - unsigned fRRectStart;
|
| - bool fRRectIsInverted;
|
| - SkTLazy<SkPath> fPath;
|
| - // Gen ID of the original path (fPath may be modified)
|
| - int32_t fPathGenID = 0;
|
| + union {
|
| + struct {
|
| + SkRRect fRRect;
|
| + SkPath::Direction fDir;
|
| + unsigned fStart;
|
| + bool fInverted;
|
| + } fRRectData;
|
| + struct {
|
| + SkPath fPath;
|
| + // Gen ID of the original path (fPath may be modified)
|
| + int32_t fGenID;
|
| + } fPathData;
|
| + };
|
| GrStyle fStyle;
|
| SkAutoSTArray<8, uint32_t> fInheritedKey;
|
| };
|
|
|