diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 999b806..d0e7843 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -163,12 +163,16 @@
       '<(skia_src_path)/gpu/GrResourceCache.h',
       '<(skia_src_path)/gpu/GrResourceProvider.cpp',
       '<(skia_src_path)/gpu/GrResourceProvider.h',
+      '<(skia_src_path)/gpu/GrShape.cpp',
+      '<(skia_src_path)/gpu/GrShape.h',
       '<(skia_src_path)/gpu/GrStencil.cpp',
       '<(skia_src_path)/gpu/GrStencil.h',
       '<(skia_src_path)/gpu/GrStencilAttachment.cpp',
       '<(skia_src_path)/gpu/GrStencilAttachment.h',
       '<(skia_src_path)/gpu/GrStrokeInfo.cpp',
       '<(skia_src_path)/gpu/GrStrokeInfo.h',
+      '<(skia_src_path)/gpu/GrStyle.cpp',
+      '<(skia_src_path)/gpu/GrStyle.h',
       '<(skia_src_path)/gpu/GrTessellator.cpp',
       '<(skia_src_path)/gpu/GrTessellator.h',
       '<(skia_src_path)/gpu/GrTraceMarker.cpp',
diff --git a/src/gpu/GrShape.cpp b/src/gpu/GrShape.cpp
new file mode 100644
index 0000000..27450cb
--- /dev/null
+++ b/src/gpu/GrShape.cpp
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrShape.h"
+
+GrShape& GrShape::operator=(const GrShape& that) {
+    bool wasPath = Type::kPath == fType;
+    fStyle = that.fStyle;
+    fType = that.fType;
+    switch (fType) {
+        case Type::kEmpty:
+            if (wasPath) {
+                fPath.reset();
+            }
+            break;
+        case Type::kRRect:
+            if (wasPath) {
+                fPath.reset();
+            }
+            fRRect = that.fRRect;
+            break;
+        case Type::kPath:
+            if (wasPath) {
+                *fPath.get() = *that.fPath.get();
+            } else {
+                fPath.set(*that.fPath.get());
+            }
+            break;
+    }
+    fInheritedKey.reset(that.fInheritedKey.count());
+    memcpy(fInheritedKey.get(), that.fInheritedKey.get(),
+           sizeof(uint32_t) * fInheritedKey.count());
+    return *this;
+}
+
+int GrShape::unstyledKeySize() const {
+    if (fInheritedKey.count()) {
+        return fInheritedKey.count();
+    }
+    switch (fType) {
+        case Type::kEmpty:
+            return 1;
+        case Type::kRRect:
+            SkASSERT(!fInheritedKey.count());
+            SkASSERT(0 == SkRRect::kSizeInMemory % sizeof(uint32_t));
+            return SkRRect::kSizeInMemory / sizeof(uint32_t);
+        case Type::kPath:
+            if (fPath.get()->isVolatile()) {
+                return -1;
+            } else {
+                return 1;
+            }
+    }
+    SkFAIL("Should never get here.");
+    return 0;
+}
+
+void GrShape::writeUnstyledKey(uint32_t* key) const {
+    SkASSERT(this->unstyledKeySize());
+    SkDEBUGCODE(uint32_t* origKey = key;)
+    if (fInheritedKey.count()) {
+        memcpy(key, fInheritedKey.get(), sizeof(uint32_t) * fInheritedKey.count());
+        SkDEBUGCODE(key += fInheritedKey.count();)
+    } else {
+        switch (fType) {
+            case Type::kEmpty:
+                *key++ = 1;
+                break;
+            case Type::kRRect:
+                fRRect.writeToMemory(key);
+                key += SkRRect::kSizeInMemory / sizeof(uint32_t);
+                break;
+            case Type::kPath:
+                SkASSERT(!fPath.get()->isVolatile());
+                *key++ = fPath.get()->getGenerationID();
+                break;
+        }
+    }
+    SkASSERT(key - origKey == this->unstyledKeySize());
+}
+
+int GrShape::StyleKeySize(const GrStyle& style, bool stopAfterPE) {
+    GR_STATIC_ASSERT(sizeof(uint32_t) == sizeof(SkScalar));
+    int size = 0;
+    if (style.isDashed()) {
+        // One scalar for dash phase and one for each dash value.
+        size += 1 + style.dashIntervalCnt();
+    } else if (style.pathEffect()) {
+        // No key for a generic path effect.
+        return -1;
+    }
+
+    if (stopAfterPE) {
+        return size;
+    }
+
+    if (style.strokeRec().needToApply()) {
+        // One for style/cap/join, 2 for miter and width.
+        size += 3;
+    }
+    return size;
+}
+
+void GrShape::StyleKey(uint32_t* key, const GrStyle& style, bool stopAfterPE) {
+    SkASSERT(key);
+    SkASSERT(StyleKeySize(style, stopAfterPE) >= 0);
+    GR_STATIC_ASSERT(sizeof(uint32_t) == sizeof(SkScalar));
+
+    int i = 0;
+    if (style.isDashed()) {
+        GR_STATIC_ASSERT(sizeof(style.dashPhase()) == sizeof(uint32_t));
+        SkScalar phase = style.dashPhase();
+        memcpy(&key[i++], &phase, sizeof(SkScalar));
+
+        int32_t count = style.dashIntervalCnt();
+        // Dash count should always be even.
+        SkASSERT(0 == (count & 0x1));
+        const SkScalar* intervals = style.dashIntervals();
+        int intervalByteCnt = count * sizeof(SkScalar);
+        memcpy(&key[i], intervals, intervalByteCnt);
+        SkDEBUGCODE(i += count);
+    } else {
+        SkASSERT(!style.pathEffect());
+    }
+
+    if (!stopAfterPE && style.strokeRec().needToApply()) {
+        enum {
+            kStyleBits = 2,
+            kJoinBits = 2,
+            kCapBits = 32 - kStyleBits - kJoinBits,
+
+            kJoinShift = kStyleBits,
+            kCapShift = kJoinShift + kJoinBits,
+        };
+        GR_STATIC_ASSERT(SkStrokeRec::kStyleCount <= (1 << kStyleBits));
+        GR_STATIC_ASSERT(SkPaint::kJoinCount <= (1 << kJoinBits));
+        GR_STATIC_ASSERT(SkPaint::kCapCount <= (1 << kCapBits));
+        key[i++]  = style.strokeRec().getStyle() |
+                    style.strokeRec().getJoin() << kJoinShift |
+                    style.strokeRec().getCap() << kCapShift;
+
+        SkScalar scalar;
+        // Miter limit only affects miter joins
+        scalar = SkPaint::kMiter_Join == style.strokeRec().getJoin()
+                 ? style.strokeRec().getMiter()
+                 : -1.f;
+        memcpy(&key[i++], &scalar, sizeof(scalar));
+
+        scalar = style.strokeRec().getWidth();
+        memcpy(&key[i++], &scalar, sizeof(scalar));
+    }
+    SkASSERT(StyleKeySize(style, stopAfterPE) == i);
+}
+
+void GrShape::setInheritedKey(const GrShape &parent, bool stopAfterPE){
+    SkASSERT(!fInheritedKey.count());
+    // If the output shape turns out to be simple, then we will just use its geometric key
+    if (Type::kPath == fType) {
+        // We want ApplyFullStyle(ApplyPathEffect(shape)) to have the same key as
+        // ApplyFullStyle(shape).
+        // The full key is structured as (geo,path_effect,stroke).
+        // If we do ApplyPathEffect we get get,path_effect as the inherited key. If we then
+        // do ApplyFullStyle we'll memcpy geo,path_effect into the new inherited key
+        // and then append the style key (which should now be stroke only) at the end.
+        int parentCnt = parent.fInheritedKey.count();
+        bool useParentGeoKey = !parentCnt;
+        if (useParentGeoKey) {
+            parentCnt = parent.unstyledKeySize();
+        }
+        int styleCnt = StyleKeySize(parent.fStyle, stopAfterPE);
+        if (styleCnt < 0) {
+            // The style doesn't allow a key, set the path to volatile so that we fail when
+            // we try to get a key for the shape.
+            fPath.get()->setIsVolatile(true);
+        } else {
+            fInheritedKey.reset(parentCnt + styleCnt);
+            if (useParentGeoKey) {
+                // This will be the geo key.
+                parent.writeUnstyledKey(fInheritedKey.get());
+            } else {
+                // This should be geo,path_effect
+                memcpy(fInheritedKey.get(), parent.fInheritedKey.get(),
+                       parentCnt * sizeof(uint32_t));
+            }
+            // Now turn (geo,path_effect) or (geo) into (geo,path_effect,stroke)
+            StyleKey(fInheritedKey.get() + parentCnt, parent.fStyle, stopAfterPE);
+        }
+    }
+}
+
+GrShape::GrShape(const GrShape& that) : fType(that.fType), fStyle(that.fStyle) {
+    switch (fType) {
+        case Type::kEmpty:
+            return;
+        case Type::kRRect:
+            fRRect = that.fRRect;
+            return;
+        case Type::kPath:
+            fPath.set(*that.fPath.get());
+            return;
+    }
+    fInheritedKey.reset(that.fInheritedKey.count());
+    memcpy(fInheritedKey.get(), that.fInheritedKey.get(),
+           sizeof(uint32_t) * fInheritedKey.count());
+}
+
+GrShape::GrShape(const GrShape& parent, bool stopAfterPE) {
+    fType = Type::kEmpty;
+    SkPathEffect* pe = parent.fStyle.pathEffect();
+    const SkPath* inPath;
+    SkStrokeRec strokeRec = parent.fStyle.strokeRec();
+    if (pe) {
+        fType = Type::kPath;
+        fPath.init();
+        if (parent.fType == Type::kPath) {
+            inPath = parent.fPath.get();
+        } else {
+            inPath = fPath.get();
+            parent.asPath(fPath.get());
+        }
+        // Should we consider bounds? Would have to include in key, but it'd be nice to know
+        // if the bounds actually modified anything before including in key.
+        if (!pe->filterPath(fPath.get(), *inPath, &strokeRec, nullptr)) {
+            // Make an empty unstyled shape if filtering fails.
+            fType = Type::kEmpty;
+            fStyle = GrStyle();
+            fPath.reset();
+            return;
+        }
+        inPath = fPath.get();
+    } else if (stopAfterPE || !strokeRec.needToApply()) {
+        *this = parent;
+        return;
+    } else {
+        fType = Type::kPath;
+        fPath.init();
+        if (parent.fType == Type::kPath) {
+            inPath = parent.fPath.get();
+        } else {
+            inPath = fPath.get();
+            parent.asPath(fPath.get());
+        }
+    }
+    if (!stopAfterPE) {
+        strokeRec.applyToPath(fPath.get(), *inPath);
+    } else {
+        fStyle = GrStyle(strokeRec, nullptr);
+    }
+    this->setInheritedKey(parent, stopAfterPE);
+}
diff --git a/src/gpu/GrShape.h b/src/gpu/GrShape.h
new file mode 100644
index 0000000..3c3f9ec
--- /dev/null
+++ b/src/gpu/GrShape.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrShape_DEFINED
+#define GrShape_DEFINED
+
+#include "GrStyle.h"
+#include "SkPath.h"
+#include "SkRRect.h"
+#include "SkTemplates.h"
+#include "SkTLazy.h"
+
+/**
+ * Represents a geometric shape (rrect or path) and the GrStyle that it should be rendered with.
+ * It is possible to apply the style to the GrShape to produce a new GrShape where the geometry
+ * reflects the styling information (e.g. is stroked). It is also possible to apply just the
+ * path effect from the style. In this case the resulting shape will include any remaining
+ * stroking information that is to be applied after the path effect.
+ *
+ * Shapes can produce keys that represent only the geometry information, not the style. Note that
+ * when styling information is applied to produce a new shape then the style has been converted
+ * to geometric information and is included in the new shape's key. When the same style is applied
+ * to two shapes that reflect the same underlying geometry the computed keys of the stylized shapes
+ * will be the same.
+ *
+ * Currently this can only be constructed from a rrect, though it can become a path by applying
+ * style to the geometry. The idea is to expand this to cover most or all of the geometries that
+ * have SkCanvas::draw APIs.
+ */
+class GrShape {
+public:
+    GrShape() : fType(Type::kEmpty) {}
+
+    explicit GrShape(const SkRRect& rrect) : fType(Type::kRRect), fRRect(rrect) {}
+    explicit GrShape(const SkRect& rect) : fType(Type::kRRect), fRRect(SkRRect::MakeRect(rect)) {}
+
+    GrShape(const SkRRect& rrect, const GrStyle& style)
+        : fType(Type::kRRect)
+        , fRRect(rrect)
+        , fStyle(style) {}
+
+    GrShape(const SkRect& rect, const GrStyle& style)
+        : fType(Type::kRRect)
+        , fRRect(SkRRect::MakeRect(rect))
+        , fStyle(style) {}
+
+    GrShape(const SkRRect& rrect, const SkPaint& paint)
+        : fType(Type::kRRect)
+        , fRRect(rrect)
+        , fStyle(paint) {}
+
+    GrShape(const SkRect& rect, const SkPaint& paint)
+        : fType(Type::kRRect)
+        , fRRect(SkRRect::MakeRect(rect))
+        , fStyle(paint) {}
+
+    GrShape(const GrShape&);
+    GrShape& operator=(const GrShape& that);
+
+    ~GrShape() {
+        if (Type::kPath == fType) {
+            fPath.reset();
+        }
+    }
+
+    const GrStyle& style() const { return fStyle; }
+
+    /**
+     * Returns a GrShape where the shape's geometry fully reflects the original shape's GrStyle.
+     * The GrStyle of the returned shape will either be fill or hairline.
+     */
+    GrShape applyFullStyle() { return GrShape(*this, false); }
+
+    /**
+     * Similar to above but applies only the path effect. Path effects take the original geometry
+     * and fill/stroking information and compute a new geometry and residual fill/stroking
+     * information to be applied. The path effect's output geometry and stroking will be captured
+     * in the returned GrShape.
+     */
+    GrShape applyPathEffect() { return GrShape(*this, true); }
+
+    bool asRRect(SkRRect* rrect) const {
+        if (Type::kRRect != fType) {
+            return false;
+        }
+        if (rrect) {
+            *rrect = fRRect;
+        }
+        return true;
+    }
+
+    void asPath(SkPath* out) const {
+        switch (fType) {
+            case Type::kRRect:
+                out->reset();
+                out->addRRect(fRRect);
+                break;
+            case Type::kPath:
+                *out = *fPath.get();
+                break;
+            case Type::kEmpty:
+                out->reset();
+                break;
+        }
+    }
+
+    /**
+     * Gets the size of the key for the shape represented by this GrShape (ignoring its styling).
+     * A negative value is returned if the shape has no key (shouldn't be cached).
+     */
+    int unstyledKeySize() const;
+
+    /**
+     * Writes unstyledKeySize() bytes into the provided pointer. Assumes that there is enough
+     * space allocated for the key and that unstyledKeySize() does not return a negative value
+     * for this shape.
+     */
+    void writeUnstyledKey(uint32_t* key) const;
+
+private:
+    /**
+     * Computes the key length for a GrStyle. The return will be negative if it cannot be turned
+     * into a key.
+     */
+    static int StyleKeySize(const GrStyle& , bool stopAfterPE);
+
+    /**
+     * Writes a unique key for the style into the provided buffer. This function assumes the buffer
+     * has room for at least StyleKeySize() values. It assumes that StyleKeySize() returns a
+     * positive value for the style and stopAfterPE param. This is written so that the key for just
+     * dash application followed by the key for the remaining SkStrokeRec is the same as the
+     * key for applying dashing and SkStrokeRec all at once.
+     */
+    static void StyleKey(uint32_t*, const GrStyle&, bool stopAfterPE);
+
+    /** Constructor used by Apply* functions */
+    GrShape(const GrShape& parentShape, bool stopAfterPE);
+
+    /**
+     * Determines the key we should inherit from the input shape's geometry and style when
+     * we are applying the style to create a new shape.
+     */
+    void setInheritedKey(const GrShape& parentShape, bool stopAfterPE);
+
+    enum class Type {
+        kEmpty,
+        kRRect,
+        kPath,
+    } fType;
+
+    SkRRect                     fRRect;
+    SkTLazy<SkPath>             fPath;
+    GrStyle                     fStyle;
+    SkAutoSTArray<8, uint32_t>  fInheritedKey;
+};
+#endif
diff --git a/src/gpu/GrStyle.cpp b/src/gpu/GrStyle.cpp
new file mode 100644
index 0000000..40a148b
--- /dev/null
+++ b/src/gpu/GrStyle.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrStyle.h"
+
+void GrStyle::initPathEffect(SkPathEffect* pe) {
+    if (!pe) {
+        fDashInfo.fType = SkPathEffect::kNone_DashType;
+        return;
+    }
+    SkPathEffect::DashInfo info;
+    if (SkPathEffect::kDash_DashType == pe->asADash(&info)) {
+        if (fStrokeRec.getStyle() == SkStrokeRec::kFill_Style) {
+            fPathEffect.reset(nullptr);
+        } else {
+            fPathEffect.reset(SkSafeRef(pe));
+            fDashInfo.fType = SkPathEffect::kDash_DashType;
+            fDashInfo.fIntervals.reset(info.fCount);
+            fDashInfo.fPhase = info.fPhase;
+            info.fIntervals = fDashInfo.fIntervals.get();
+            pe->asADash(&info);
+            return;
+        }
+    } else {
+        fPathEffect.reset(SkSafeRef(pe));
+    }
+    fDashInfo.fType = SkPathEffect::kNone_DashType;
+    fDashInfo.fIntervals.reset(0);
+}
diff --git a/src/gpu/GrStyle.h b/src/gpu/GrStyle.h
new file mode 100644
index 0000000..4eef252
--- /dev/null
+++ b/src/gpu/GrStyle.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef GrStyle_DEFINED
+#define GrStyle_DEFINED
+
+#include "GrTypes.h"
+#include "SkPathEffect.h"
+#include "SkStrokeRec.h"
+#include "SkTemplates.h"
+
+/**
+ * Represents the various ways that a GrShape can be styled. It has fill/stroking information
+ * as well as an optional path effect. If the path effect represents dashing, the dashing
+ * information is extracted from the path effect and stored explicitly.
+ *
+ * This object does not support stroke-and-fill styling. It is expected that stroking and filling
+ * is handled by drawing a stroke and a fill separately.
+ *
+ * This will replace GrStrokeInfo as GrShape is deployed.
+ */
+class GrStyle {
+public:
+    GrStyle() : fStrokeRec(SkStrokeRec::kFill_InitStyle) {
+        fDashInfo.fType = SkPathEffect::kNone_DashType;
+    }
+
+    GrStyle(const SkStrokeRec& strokeRec, SkPathEffect* pe) : fStrokeRec(strokeRec) {
+        SkASSERT(SkStrokeRec::kStrokeAndFill_Style != strokeRec.getStyle());
+        this->initPathEffect(pe);
+    }
+
+    GrStyle(const GrStyle& that) : fStrokeRec(SkStrokeRec::kFill_InitStyle) {
+        *this = that;
+    }
+
+    explicit GrStyle(const SkPaint& paint) : fStrokeRec(paint) {
+        SkASSERT(SkStrokeRec::kStrokeAndFill_Style != fStrokeRec.getStyle());
+        this->initPathEffect(paint.getPathEffect());
+    }
+
+    GrStyle& operator=(const GrStyle& that) {
+        fPathEffect = that.fPathEffect;
+        fDashInfo = that.fDashInfo;
+        fStrokeRec = that.fStrokeRec;
+        return *this;
+    }
+    SkPathEffect* pathEffect() const { return fPathEffect.get(); }
+
+    bool isDashed() const { return SkPathEffect::kDash_DashType == fDashInfo.fType; }
+    SkScalar dashPhase() const {
+        SkASSERT(this->isDashed());
+        return fDashInfo.fPhase;
+    }
+    int dashIntervalCnt() const {
+        SkASSERT(this->isDashed());
+        return fDashInfo.fIntervals.count();
+    }
+    const SkScalar* dashIntervals() const {
+        SkASSERT(this->isDashed());
+        return fDashInfo.fIntervals.get();
+    }
+
+    const SkStrokeRec& strokeRec() const { return fStrokeRec; }
+
+private:
+    void initPathEffect(SkPathEffect* pe);
+
+    struct DashInfo {
+        DashInfo& operator=(const DashInfo& that) {
+            fType = that.fType;
+            fPhase = that.fPhase;
+            fIntervals.reset(that.fIntervals.count());
+            memcpy(fIntervals.get(), that.fIntervals.get(),
+                   sizeof(SkScalar) * that.fIntervals.count());
+            return *this;
+        }
+        SkPathEffect::DashType      fType;
+        SkScalar                    fPhase;
+        SkAutoSTArray<4, SkScalar>  fIntervals;
+    };
+
+    SkStrokeRec         fStrokeRec;
+    sk_sp<SkPathEffect> fPathEffect;
+    DashInfo            fDashInfo;
+};
+
+#endif
diff --git a/tests/GrShapeTest.cpp b/tests/GrShapeTest.cpp
new file mode 100644
index 0000000..62440d4
--- /dev/null
+++ b/tests/GrShapeTest.cpp
@@ -0,0 +1,316 @@
+/*
+ * Copyright 2016 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <initializer_list>
+#include <functional>
+#include "Test.h"
+#if SK_SUPPORT_GPU
+#include "GrShape.h"
+#include "SkPath.h"
+#include "SkDashPathEffect.h"
+
+namespace {
+class TestCase {
+public:
+    TestCase(const SkRRect& rrect, const SkPaint& paint) : fBase(rrect, paint) {
+        this->init();
+    }
+
+    struct SelfExpectations {
+        bool fPEHasEffect;
+        bool fPEHasValidKey;
+        bool fStrokeApplies;
+    };
+
+    void testExpectations(skiatest::Reporter* reporter, SelfExpectations expectations) const;
+
+    enum ComparisonExpecation {
+        kAllDifferent_ComparisonExpecation,
+        kSameUpToPE_ComparisonExpecation,
+        kSameUpToStroke_ComparisonExpecation,
+        kAllSame_ComparisonExpecation,
+    };
+
+    void compare(skiatest::Reporter*, const TestCase& that, ComparisonExpecation) const;
+
+private:
+    void init() {
+        fAppliedPE           = fBase.applyPathEffect();
+        fAppliedPEThenStroke = fAppliedPE.applyFullStyle();
+        fAppliedFull         = fBase.applyFullStyle();
+
+        fBaseKeyIsValid                = MakeKey(&fBaseKey, fBase);
+        fAppliedPEKeyIsValid           = MakeKey(&fAppliedPEKey, fAppliedPE);
+        fAppliedPEThenStrokeKeyIsValid = MakeKey(&fAppliedPEThenStrokeKey, fAppliedPEThenStroke);
+        fAppliedFullKeyIsValid         = MakeKey(&fAppliedFullKey, fAppliedFull);
+    }
+
+    using Key = SkTArray<uint32_t>;
+
+    static bool MakeKey(Key* key, const GrShape& shape) {
+        int size = shape.unstyledKeySize();
+        if (size <= 0) {
+            return false;
+        }
+        key->reset(size);
+        shape.writeUnstyledKey(key->begin());
+        return true;
+    }
+
+    GrShape fBase;
+    GrShape fAppliedPE;
+    GrShape fAppliedPEThenStroke;
+    GrShape fAppliedFull;
+
+    Key fBaseKey;
+    Key fAppliedPEKey;
+    Key fAppliedPEThenStrokeKey;
+    Key fAppliedFullKey;
+
+    bool fBaseKeyIsValid;
+    bool fAppliedPEKeyIsValid;
+    bool fAppliedPEThenStrokeKeyIsValid;
+    bool fAppliedFullKeyIsValid;
+};
+
+void TestCase::testExpectations(skiatest::Reporter* reporter, SelfExpectations expectations) const {
+    // Applying the path effect and then the stroke should always be the same as applying
+    // both in one go.
+    REPORTER_ASSERT(reporter, fAppliedPEThenStrokeKey == fAppliedFullKey);
+    // The base's key should always be valid (unless the path is volatile)
+    REPORTER_ASSERT(reporter, fBaseKeyIsValid);
+    if (expectations.fPEHasEffect) {
+        REPORTER_ASSERT(reporter, fBaseKey != fAppliedPEKey);
+        REPORTER_ASSERT(reporter, expectations.fPEHasEffect == fAppliedPEKeyIsValid);
+        REPORTER_ASSERT(reporter, fBaseKey != fAppliedFullKey);
+        REPORTER_ASSERT(reporter, expectations.fPEHasEffect == fAppliedFullKeyIsValid);
+        if (expectations.fStrokeApplies && expectations.fPEHasValidKey) {
+            REPORTER_ASSERT(reporter, fAppliedPEKey != fAppliedFullKey);
+            REPORTER_ASSERT(reporter, expectations.fPEHasEffect == fAppliedFullKeyIsValid);
+        }
+    } else {
+        REPORTER_ASSERT(reporter, fBaseKey == fAppliedPEKey);
+        if (expectations.fStrokeApplies) {
+            REPORTER_ASSERT(reporter, fBaseKey != fAppliedFullKey);
+        } else {
+            REPORTER_ASSERT(reporter, fBaseKey == fAppliedFullKey);
+        }
+    }
+}
+
+void TestCase::compare(skiatest::Reporter* reporter, const TestCase& that,
+                       ComparisonExpecation expectation) const {
+    switch (expectation) {
+        case kAllDifferent_ComparisonExpecation:
+            REPORTER_ASSERT(reporter, fBaseKey != that.fBaseKey);
+            REPORTER_ASSERT(reporter, fAppliedPEKey != that.fAppliedPEKey);
+            REPORTER_ASSERT(reporter, fAppliedFullKey != that.fAppliedFullKey);
+            break;
+        case kSameUpToPE_ComparisonExpecation:
+            REPORTER_ASSERT(reporter, fBaseKey == that.fBaseKey);
+            REPORTER_ASSERT(reporter, fAppliedPEKey != that.fAppliedPEKey);
+            REPORTER_ASSERT(reporter, fAppliedFullKey != that.fAppliedFullKey);
+            break;
+        case kSameUpToStroke_ComparisonExpecation:
+            REPORTER_ASSERT(reporter, fBaseKey == that.fBaseKey);
+            REPORTER_ASSERT(reporter, fAppliedPEKey == that.fAppliedPEKey);
+            REPORTER_ASSERT(reporter, fAppliedFullKey != that.fAppliedFullKey);
+            break;
+        case kAllSame_ComparisonExpecation:
+            REPORTER_ASSERT(reporter, fBaseKey == that.fBaseKey);
+            REPORTER_ASSERT(reporter, fAppliedPEKey == that.fAppliedPEKey);
+            REPORTER_ASSERT(reporter, fAppliedFullKey == that.fAppliedFullKey);
+            break;
+    }
+}
+}  // namespace
+
+static sk_sp<SkPathEffect> make_dash() {
+    static const SkScalar kIntervals[] = { 0.25, 3.f, 0.5, 2.f };
+    static const SkScalar kPhase = 0.75;
+    return SkDashPathEffect::Make(kIntervals, SK_ARRAY_COUNT(kIntervals), kPhase);
+}
+
+static sk_sp<SkPathEffect> make_null_dash() {
+    static const SkScalar kNullIntervals[] = {0, 0, 0, 0, 0, 0};
+    return SkDashPathEffect::Make(kNullIntervals, SK_ARRAY_COUNT(kNullIntervals), 0.f);
+}
+
+static void test_basic(skiatest::Reporter* reporter, const SkRRect& rrect) {
+    sk_sp<SkPathEffect> dashPE = make_dash();
+
+    TestCase::SelfExpectations expectations;
+    SkPaint fill;
+
+    TestCase fillCase(rrect, fill);
+    expectations.fPEHasEffect = false;
+    expectations.fPEHasValidKey = false;
+    expectations.fStrokeApplies = false;
+    fillCase.testExpectations(reporter, expectations);
+    // Test that another GrShape instance built from the same primitive is the same.
+    TestCase(rrect, fill).compare(reporter, fillCase, TestCase::kAllSame_ComparisonExpecation);
+
+    SkPaint stroke2RoundBevel;
+    stroke2RoundBevel.setStyle(SkPaint::kStroke_Style);
+    stroke2RoundBevel.setStrokeCap(SkPaint::kRound_Cap);
+    stroke2RoundBevel.setStrokeJoin(SkPaint::kBevel_Join);
+    stroke2RoundBevel.setStrokeWidth(2.f);
+    TestCase stroke2RoundBevelCase(rrect, stroke2RoundBevel);
+    expectations.fPEHasValidKey = true;
+    expectations.fPEHasEffect = false;
+    expectations.fStrokeApplies = true;
+    stroke2RoundBevelCase.testExpectations(reporter, expectations);
+    TestCase(rrect, stroke2RoundBevel).compare(reporter, stroke2RoundBevelCase,
+                                               TestCase::kAllSame_ComparisonExpecation);
+
+    SkPaint stroke2RoundBevelDash = stroke2RoundBevel;
+    stroke2RoundBevelDash.setPathEffect(make_dash());
+    TestCase stroke2RoundBevelDashCase(rrect, stroke2RoundBevelDash);
+    expectations.fPEHasValidKey = true;
+    expectations.fPEHasEffect = true;
+    expectations.fStrokeApplies = true;
+    stroke2RoundBevelDashCase.testExpectations(reporter, expectations);
+    TestCase(rrect, stroke2RoundBevelDash).compare(reporter, stroke2RoundBevelDashCase,
+                                                   TestCase::kAllSame_ComparisonExpecation);
+
+    fillCase.compare(reporter, stroke2RoundBevelCase,
+                     TestCase::kSameUpToStroke_ComparisonExpecation);
+    fillCase.compare(reporter, stroke2RoundBevelDashCase,
+                     TestCase::kSameUpToPE_ComparisonExpecation);
+    stroke2RoundBevelCase.compare(reporter, stroke2RoundBevelDashCase,
+                                  TestCase::kSameUpToPE_ComparisonExpecation);
+}
+
+template <typename T>
+static void test_stroke_param(skiatest::Reporter* reporter, const SkRRect& rrect,
+                              std::function<void(SkPaint*, T)> setter, T a, T b) {
+    // Set the stroke width so that we don't get hairline. However, call the function second so that
+    // it can override.
+    SkPaint strokeA;
+    strokeA.setStyle(SkPaint::kStroke_Style);
+    strokeA.setStrokeWidth(2.f);
+    setter(&strokeA, a);
+    SkPaint strokeB;
+    strokeB.setStyle(SkPaint::kStroke_Style);
+    strokeB.setStrokeWidth(2.f);
+    setter(&strokeB, b);
+
+    TestCase strokeACase(rrect, strokeA);
+    TestCase strokeBCase(rrect, strokeB);
+    strokeACase.compare(reporter, strokeBCase, TestCase::kSameUpToStroke_ComparisonExpecation);
+
+    // Make sure stroking params don't affect fill style.
+    SkPaint fillA = strokeA, fillB = strokeB;
+    fillA.setStyle(SkPaint::kFill_Style);
+    fillB.setStyle(SkPaint::kFill_Style);
+    TestCase fillACase(rrect, fillA);
+    TestCase fillBCase(rrect, fillB);
+    fillACase.compare(reporter, fillBCase, TestCase::kAllSame_ComparisonExpecation);
+
+    // Make sure just applying the dash but not stroke gives the same key for both stroking
+    // variations.
+    SkPaint dashA = strokeA, dashB = strokeB;
+    dashA.setPathEffect(make_dash());
+    dashB.setPathEffect(make_dash());
+    TestCase dashACase(rrect, dashA);
+    TestCase dashBCase(rrect, dashB);
+    dashACase.compare(reporter, dashBCase, TestCase::kSameUpToStroke_ComparisonExpecation);
+}
+
+static void test_miter_limit(skiatest::Reporter* reporter, const SkRRect& rrect) {
+    // Miter limit should only matter when stroking with miter joins. It shouldn't affect other
+    // joins or fills.
+    SkPaint miterA;
+    miterA.setStyle(SkPaint::kStroke_Style);
+    miterA.setStrokeWidth(2.f);
+    miterA.setStrokeJoin(SkPaint::kMiter_Join);
+    miterA.setStrokeMiter(0.5f);
+    SkPaint miterB = miterA;
+    miterA.setStrokeMiter(0.6f);
+
+    TestCase miterACase(rrect, miterA);
+    TestCase miterBCase(rrect, miterB);
+    miterACase.compare(reporter, miterBCase, TestCase::kSameUpToStroke_ComparisonExpecation);
+
+    SkPaint noMiterA = miterA, noMiterB = miterB;
+    noMiterA.setStrokeJoin(SkPaint::kRound_Join);
+    noMiterB.setStrokeJoin(SkPaint::kRound_Join);
+    TestCase noMiterACase(rrect, noMiterA);
+    TestCase noMiterBCase(rrect, noMiterB);
+    noMiterACase.compare(reporter, noMiterBCase, TestCase::kAllSame_ComparisonExpecation);
+
+    SkPaint fillA = miterA, fillB = miterB;
+    fillA.setStyle(SkPaint::kFill_Style);
+    fillB.setStyle(SkPaint::kFill_Style);
+    TestCase fillACase(rrect, fillA);
+    TestCase fillBCase(rrect, fillB);
+    fillACase.compare(reporter, fillBCase, TestCase::kAllSame_ComparisonExpecation);
+}
+
+static void test_dash_fill(skiatest::Reporter* reporter, const SkRRect& rrect) {
+    // A dash with no stroke should have no effect
+    using DashFactoryFn = sk_sp<SkPathEffect>(*)();
+    for (DashFactoryFn md : {&make_dash, &make_null_dash}) {
+        SkPaint dashFill;
+        dashFill.setPathEffect((*md)());
+        TestCase dashFillCase(rrect, dashFill);
+
+        TestCase fillCase(rrect, SkPaint());
+        dashFillCase.compare(reporter, fillCase, TestCase::kAllSame_ComparisonExpecation);
+    }
+}
+
+void test_null_dash(skiatest::Reporter* reporter, const SkRRect& rrect) {
+    SkPaint fill;
+    SkPaint stroke;
+    stroke.setStyle(SkPaint::kStroke_Style);
+    stroke.setStrokeWidth(1.f);
+    SkPaint dash;
+    dash.setStyle(SkPaint::kStroke_Style);
+    dash.setStrokeWidth(1.f);
+    dash.setPathEffect(make_dash());
+    SkPaint nullDash;
+    nullDash.setStyle(SkPaint::kStroke_Style);
+    nullDash.setStrokeWidth(1.f);
+    nullDash.setPathEffect(make_null_dash());
+
+    TestCase fillCase(rrect, fill);
+    TestCase strokeCase(rrect, stroke);
+    TestCase dashCase(rrect, dash);
+    TestCase nullDashCase(rrect, nullDash);
+
+    nullDashCase.compare(reporter, fillCase, TestCase::kSameUpToStroke_ComparisonExpecation);
+    nullDashCase.compare(reporter, strokeCase, TestCase::kAllSame_ComparisonExpecation);
+    nullDashCase.compare(reporter, dashCase, TestCase::kSameUpToPE_ComparisonExpecation);
+}
+
+DEF_TEST(GrShape, reporter) {
+    sk_sp<SkPathEffect> dashPE = make_dash();
+
+    for (auto rr : { SkRRect::MakeRect(SkRect::MakeWH(10, 10)),
+                     SkRRect::MakeRectXY(SkRect::MakeWH(10, 10), 3, 4)}) {
+        test_basic(reporter, rr);
+        test_dash_fill(reporter, rr);
+        test_null_dash(reporter, rr);
+        // Test modifying various stroke params.
+        test_stroke_param<SkScalar>(
+                          reporter, rr,
+                          [](SkPaint* p, SkScalar w) { p->setStrokeWidth(w);},
+                          SkIntToScalar(2), SkIntToScalar(4));
+        test_stroke_param<SkPaint::Cap>(
+                          reporter, rr,
+                          [](SkPaint* p, SkPaint::Cap c) { p->setStrokeCap(c);},
+                          SkPaint::kButt_Cap, SkPaint::kRound_Cap);
+        test_stroke_param<SkPaint::Join>(
+                          reporter, rr,
+                          [](SkPaint* p, SkPaint::Join j) { p->setStrokeJoin(j);},
+                          SkPaint::kMiter_Join, SkPaint::kRound_Join);
+        test_miter_limit(reporter, rr);
+    }
+}
+
+#endif
