Roll external/skia 82727ad0e..b3067e8e1 (6 commits)

https://skia.googlesource.com/skia.git/+log/82727ad0e..b3067e8e1

2018-10-15 egdaniel@google.com Revert "Have GrAtlasManager use legacy behavior"
2018-10-15 herb@google.com Have GrAtlasManager use legacy behavior
2018-10-15 reed@google.com remove noisy gm
2018-10-15 brianosman@google.com Revert "Preserve pixel config in makeColorSpace of GPU backed images"
2018-10-15 brianosman@google.com Revert "Fix bug with makeColorSpace of GPU images with non-renderable configs"
2018-10-15 ethannicholas@google.com Revert "converted AARectEffect to new FP system"

The AutoRoll server is located here: https://autoroll-internal.skia.org/r/android-master-autoroll

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+/master/autoroll/README.md

If the roll is causing failures, please contact the current sheriff, who should
be CC'd on the roll, and stop the roller if necessary.

Test: Presubmit checks will test this change.
Change-Id: I19e5911a54b9b200760e9e047630282f48cc7fdf
Exempt-From-Owner-Approval: The autoroll bot does not require owner approval.
diff --git a/Android.bp b/Android.bp
index 112fe0b..4a8fe4a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -453,6 +453,7 @@
         "src/gpu/ccpr/GrCCStrokeGeometry.cpp",
         "src/gpu/ccpr/GrCCStroker.cpp",
         "src/gpu/ccpr/GrCoverageCountingPathRenderer.cpp",
+        "src/gpu/effects/GrAARectEffect.cpp",
         "src/gpu/effects/GrAlphaThresholdFragmentProcessor.cpp",
         "src/gpu/effects/GrBezierEffect.cpp",
         "src/gpu/effects/GrBicubicEffect.cpp",
diff --git a/gm/bigrrectaaeffect.cpp b/gm/bigrrectaaeffect.cpp
index 5802eaf..f3f10ae 100644
--- a/gm/bigrrectaaeffect.cpp
+++ b/gm/bigrrectaaeffect.cpp
@@ -7,6 +7,7 @@
 
 #include "gm.h"
 #include "sk_tool_utils.h"
+#include "GrCaps.h"
 #include "GrContext.h"
 #include "GrRenderTargetContextPriv.h"
 #include "SkRRect.h"
@@ -81,7 +82,8 @@
 
                 SkRRect rrect = fRRect;
                 rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap));
-                auto fp = GrRRectEffect::Make(edgeType, rrect, context);
+                const auto& caps = *renderTargetContext->caps()->shaderCaps();
+                auto fp = GrRRectEffect::Make(edgeType, rrect, caps);
                 SkASSERT(fp);
                 if (fp) {
                     GrPaint grPaint;
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 4e237d8..7854bff 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -205,9 +205,7 @@
                 path->transform(m, &p);
 
                 GrClipEdgeType edgeType = (GrClipEdgeType) et;
-                std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(
-                                                                           edgeType, p,
-                                                                           canvas->getGrContext()));
+                std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, p));
                 if (!fp) {
                     continue;
                 }
@@ -247,9 +245,7 @@
                 SkRect rect = *iter.get();
                 rect.offset(x, y);
                 GrClipEdgeType edgeType = (GrClipEdgeType) et;
-                std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(
-                                                                           edgeType, rect,
-                                                                           canvas->getGrContext()));
+                std::unique_ptr<GrFragmentProcessor> fp(GrConvexPolyEffect::Make(edgeType, rect));
                 if (!fp) {
                     continue;
                 }
diff --git a/gm/gradients.cpp b/gm/gradients.cpp
index 28a9a83..1a3a9fd 100644
--- a/gm/gradients.cpp
+++ b/gm/gradients.cpp
@@ -914,19 +914,6 @@
     draw_many_stops(canvas);
 }
 
-static void draw_subpixel_gradient(SkCanvas* canvas) {
-    const SkPoint pts[] = { {50, 50}, {50.1f, 50.1f}};
-    SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE };
-    SkPaint p;
-    p.setShader(SkGradientShader::MakeLinear(
-        pts, colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kRepeat_TileMode));
-    canvas->drawRect(SkRect::MakeXYWH(0, 0, 500, 500), p);
-}
-
-DEF_SIMPLE_GM(gradient_subpixel, canvas, 500, 500) {
-    draw_subpixel_gradient(canvas);
-}
-
 #include "SkPictureRecorder.h"
 
 static void draw_circle_shader(SkCanvas* canvas, SkScalar cx, SkScalar cy, SkScalar r,
diff --git a/gm/rrects.cpp b/gm/rrects.cpp
index 4e5fce1..2fbd3b9 100644
--- a/gm/rrects.cpp
+++ b/gm/rrects.cpp
@@ -105,7 +105,8 @@
                         SkRRect rrect = fRRects[curRRect];
                         rrect.offset(SkIntToScalar(x), SkIntToScalar(y));
                         GrClipEdgeType edgeType = (GrClipEdgeType) et;
-                        auto fp = GrRRectEffect::Make(edgeType, rrect, context);
+                        const auto& caps = *renderTargetContext->caps()->shaderCaps();
+                        auto fp = GrRRectEffect::Make(edgeType, rrect, caps);
                         if (fp) {
                             GrPaint grPaint;
                             grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
diff --git a/gm/windowrectangles.cpp b/gm/windowrectangles.cpp
index 57744d9..14d10e2 100644
--- a/gm/windowrectangles.cpp
+++ b/gm/windowrectangles.cpp
@@ -179,7 +179,7 @@
         return;
     }
 
-    const GrReducedClip reducedClip(stack, SkRect::Make(kCoverRect), ctx, kNumWindows);
+    const GrReducedClip reducedClip(stack, SkRect::Make(kCoverRect), rtc->caps(), kNumWindows);
 
     GrPaint paint;
     if (GrFSAAType::kNone == rtc->fsaaType()) {
@@ -231,7 +231,7 @@
     // Draw a checker pattern into the stencil buffer so we can visualize the regions left untouched
     // by the clip mask generation.
     this->stencilCheckerboard(rtc, false);
-    reducedClip.drawStencilClipMask(rtc);
+    reducedClip.drawStencilClipMask(ctx, rtc);
 
     // Now visualize the stencil mask by covering the entire render target. The regions inside
     // window rectangles or outside the scissor should still have the initial checkerboard intact.
diff --git a/gn/gpu.gni b/gn/gpu.gni
index d272708..daf14d2 100644
--- a/gn/gpu.gni
+++ b/gn/gpu.gni
@@ -283,6 +283,8 @@
   "$_src/gpu/ops/GrTextureOp.cpp",
   "$_src/gpu/ops/GrTextureOp.h",
 
+  "$_src/gpu/effects/GrAARectEffect.cpp",
+  "$_src/gpu/effects/GrAARectEffect.h",
   "$_src/gpu/effects/GrAlphaThresholdFragmentProcessor.cpp",
   "$_src/gpu/effects/GrAlphaThresholdFragmentProcessor.h",
   "$_src/gpu/effects/GrBlurredEdgeFragmentProcessor.cpp",
diff --git a/gn/sksl.gni b/gn/sksl.gni
index 3543896..7497a64 100644
--- a/gn/sksl.gni
+++ b/gn/sksl.gni
@@ -30,6 +30,7 @@
 ]
 
 skia_gpu_processor_sources = [
+  "$_src/gpu/effects/GrAARectEffect.fp",
   "$_src/gpu/effects/GrAlphaThresholdFragmentProcessor.fp",
   "$_src/gpu/effects/GrBlurredEdgeFragmentProcessor.fp",
   "$_src/gpu/effects/GrCircleBlurFragmentProcessor.fp",
diff --git a/src/effects/SkOverdrawColorFilter.cpp b/src/effects/SkOverdrawColorFilter.cpp
index 35ef587..12c9921 100644
--- a/src/effects/SkOverdrawColorFilter.cpp
+++ b/src/effects/SkOverdrawColorFilter.cpp
@@ -91,7 +91,8 @@
 std::unique_ptr<GrFragmentProcessor> SkOverdrawColorFilter::asFragmentProcessor(
         GrContext* context, const GrColorSpaceInfo&) const {
     static int overdrawIndex = GrSkSLFP::NewIndex();
-    return GrSkSLFP::Make(context, overdrawIndex, "Overdraw", SKSL_OVERDRAW_SRC, fColors);
+    return GrSkSLFP::Make(context, overdrawIndex, "Overdraw", SKSL_OVERDRAW_SRC, fColors,
+                          sizeof(fColors));
 }
 
 #endif
diff --git a/src/effects/imagefilters/SkArithmeticImageFilter.cpp b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
index c1663c0..bd72e3a 100644
--- a/src/effects/imagefilters/SkArithmeticImageFilter.cpp
+++ b/src/effects/imagefilters/SkArithmeticImageFilter.cpp
@@ -344,7 +344,8 @@
                                                                      arithmeticIndex,
                                                                      "Arithmetic",
                                                                      SKSL_ARITHMETIC_SRC,
-                                                                     inputs);
+                                                                     &inputs,
+                                                                     sizeof(inputs));
         if (xferFP) {
             ((GrSkSLFP&) *xferFP).addChild(std::move(bgFP));
             paint.addColorFragmentProcessor(std::move(xferFP));
diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp
index 5c429e0..92af020 100644
--- a/src/gpu/GrClipStackClip.cpp
+++ b/src/gpu/GrClipStackClip.cpp
@@ -211,8 +211,8 @@
     }
     auto* ccpr = context->contextPriv().drawingManager()->getCoverageCountingPathRenderer();
 
-    GrReducedClip reducedClip(*fStack, devBounds, context, maxWindowRectangles, maxAnalyticFPs,
-                              ccpr ? maxAnalyticFPs : 0);
+    GrReducedClip reducedClip(*fStack, devBounds, context->contextPriv().caps(),
+                              maxWindowRectangles, maxAnalyticFPs, ccpr ? maxAnalyticFPs : 0);
     if (InitialState::kAllOut == reducedClip.initialState() &&
         reducedClip.maskElements().isEmpty()) {
         return false;
@@ -291,7 +291,7 @@
     // after clipping is overhauled.
     if (renderTargetContext->priv().mustRenderClip(reducedClip.maskGenID(), reducedClip.scissor(),
                                                    reducedClip.numAnalyticFPs())) {
-        reducedClip.drawStencilClipMask(renderTargetContext);
+        reducedClip.drawStencilClipMask(context, renderTargetContext);
         renderTargetContext->priv().setLastClip(reducedClip.maskGenID(), reducedClip.scissor(),
                                                 reducedClip.numAnalyticFPs());
     }
diff --git a/src/gpu/GrMemoryPool.cpp b/src/gpu/GrMemoryPool.cpp
index 7d085ea..89e8f01 100644
--- a/src/gpu/GrMemoryPool.cpp
+++ b/src/gpu/GrMemoryPool.cpp
@@ -11,7 +11,6 @@
 #include "SkAtomics.h"
 #endif
 #include "ops/GrOp.h"
-#include "effects/GrSkSLFP.h"
 
 #ifdef SK_DEBUG
     #define VALIDATE this->validate()
@@ -19,13 +18,6 @@
     #define VALIDATE
 #endif
 
-enum {
-    // We assume this alignment is good enough for everybody.
-    kAlignment    = alignof(GrSkSLFP),
-    kHeaderSize   = GR_CT_ALIGN_UP(GrMemoryPool::kBlockHeaderSize, kAlignment),
-    kPerAllocPad  = GR_CT_ALIGN_UP(GrMemoryPool::kAllocHeaderSize, kAlignment),
-};
-
 void GrOpMemoryPool::release(std::unique_ptr<GrOp> op) {
     GrOp* tmp = op.release();
     SkASSERT(tmp);
diff --git a/src/gpu/GrMemoryPool.h b/src/gpu/GrMemoryPool.h
index 316deae..15399b6 100644
--- a/src/gpu/GrMemoryPool.h
+++ b/src/gpu/GrMemoryPool.h
@@ -115,10 +115,13 @@
     SkTHashSet<int32_t>               fAllocatedIDs;
 #endif
 
-public:
-    constexpr static size_t kBlockHeaderSize = sizeof(BlockHeader);
-
-    constexpr static size_t kAllocHeaderSize = sizeof(AllocHeader);
+protected:
+    enum {
+        // We assume this alignment is good enough for everybody.
+        kAlignment    = 8,
+        kHeaderSize   = GR_CT_ALIGN_UP(sizeof(BlockHeader), kAlignment),
+        kPerAllocPad  = GR_CT_ALIGN_UP(sizeof(AllocHeader), kAlignment),
+    };
 };
 
 class GrOp;
diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp
index 078cfbdf..aafe1d8 100644
--- a/src/gpu/GrProcessor.cpp
+++ b/src/gpu/GrProcessor.cpp
@@ -57,7 +57,7 @@
  * we verify the count is as expected.  If a new factory is added, then these numbers must be
  * manually adjusted.
  */
-static const int kFPFactoryCount = 35;
+static const int kFPFactoryCount = 36;
 static const int kGPFactoryCount = 14;
 static const int kXPFactoryCount = 4;
 
diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp
index 111ef7f..4cf3477 100644
--- a/src/gpu/GrReducedClip.cpp
+++ b/src/gpu/GrReducedClip.cpp
@@ -22,6 +22,7 @@
 #include "GrUserStencilSettings.h"
 #include "SkClipOpPriv.h"
 #include "ccpr/GrCoverageCountingPathRenderer.h"
+#include "effects/GrAARectEffect.h"
 #include "effects/GrConvexPolyEffect.h"
 #include "effects/GrRRectEffect.h"
 
@@ -33,9 +34,9 @@
  * take a rect in case the caller knows a bound on what is to be drawn through this clip.
  */
 GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds,
-                             GrContext* context, int maxWindowRectangles,
-                             int maxAnalyticFPs, int maxCCPRClipPaths)
-        : fContext(context)
+                             const GrCaps* caps, int maxWindowRectangles, int maxAnalyticFPs,
+                             int maxCCPRClipPaths)
+        : fCaps(caps)
         , fMaxWindowRectangles(maxWindowRectangles)
         , fMaxAnalyticFPs(maxAnalyticFPs)
         , fMaxCCPRClipPaths(maxCCPRClipPaths) {
@@ -611,14 +612,13 @@
     }
 }
 
-GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const SkRect& deviceSpaceRect, Invert invert,
-                                                       GrAA aa) {
+GrReducedClip::ClipResult GrReducedClip::addAnalyticFP(const SkRect& deviceSpaceRect,
+                                                       Invert invert, GrAA aa) {
     if (this->numAnalyticFPs() >= fMaxAnalyticFPs) {
         return ClipResult::kNotClipped;
     }
 
-    fAnalyticFPs.push_back(GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRect,
-                                                    fContext));
+    fAnalyticFPs.push_back(GrAARectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRect));
     SkASSERT(fAnalyticFPs.back());
 
     return ClipResult::kClipped;
@@ -630,7 +630,8 @@
         return ClipResult::kNotClipped;
     }
 
-    if (auto fp = GrRRectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRRect, fContext)) {
+    if (auto fp = GrRRectEffect::Make(GetClipEdgeType(invert, aa), deviceSpaceRRect,
+                                      *fCaps->shaderCaps())) {
         fAnalyticFPs.push_back(std::move(fp));
         return ClipResult::kClipped;
     }
@@ -647,8 +648,7 @@
         return ClipResult::kNotClipped;
     }
 
-    if (auto fp = GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpacePath,
-                                           fContext)) {
+    if (auto fp = GrConvexPolyEffect::Make(GetClipEdgeType(invert, aa), deviceSpacePath)) {
         fAnalyticFPs.push_back(std::move(fp));
         return ClipResult::kClipped;
     }
@@ -805,7 +805,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Create a 1-bit clip mask in the stencil buffer.
 
-bool GrReducedClip::drawStencilClipMask(GrRenderTargetContext* renderTargetContext) const {
+bool GrReducedClip::drawStencilClipMask(GrContext* context,
+                                        GrRenderTargetContext* renderTargetContext) const {
     // We set the current clip to the bounds so that our recursive draws are scissored to them.
     GrStencilClip stencilClip(fScissor, this->maskGenID());
 
@@ -847,14 +848,14 @@
 
             GrShape shape(clipPath, GrStyle::SimpleFill());
             GrPathRenderer::CanDrawPathArgs canDrawArgs;
-            canDrawArgs.fCaps = fContext->contextPriv().caps();
+            canDrawArgs.fCaps = context->contextPriv().caps();
             canDrawArgs.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
             canDrawArgs.fViewMatrix = &SkMatrix::I();
             canDrawArgs.fShape = &shape;
             canDrawArgs.fAAType = aaType;
             canDrawArgs.fHasUserStencilSettings = false;
 
-            GrDrawingManager* dm = fContext->contextPriv().drawingManager();
+            GrDrawingManager* dm = context->contextPriv().drawingManager();
             pr = dm->getPathRenderer(canDrawArgs, false, GrPathRendererChain::DrawType::kStencil,
                                      &stencilSupport);
             if (!pr) {
@@ -894,7 +895,7 @@
                         GrPaint paint;
                         paint.setXPFactory(GrDisableColorXPFactory::Get());
 
-                        GrPathRenderer::DrawPathArgs args{fContext,
+                        GrPathRenderer::DrawPathArgs args{context,
                                                           std::move(paint),
                                                           &kDrawToStencil,
                                                           renderTargetContext,
@@ -907,7 +908,7 @@
                         pr->drawPath(args);
                     } else {
                         GrPathRenderer::StencilPathArgs args;
-                        args.fContext = fContext;
+                        args.fContext = context;
                         args.fRenderTargetContext = renderTargetContext;
                         args.fClip = &stencilClip.fixedClip();
                         args.fClipConservativeBounds = &stencilClip.fixedClip().scissorRect();
@@ -932,7 +933,7 @@
                     GrShape shape(clipPath, GrStyle::SimpleFill());
                     GrPaint paint;
                     paint.setXPFactory(GrDisableColorXPFactory::Get());
-                    GrPathRenderer::DrawPathArgs args{fContext,
+                    GrPathRenderer::DrawPathArgs args{context,
                                                       std::move(paint),
                                                       *pass,
                                                       renderTargetContext,
@@ -966,7 +967,7 @@
             SkASSERT(ccpr);
             SkASSERT(fHasScissor);
             auto fp = ccpr->makeClipProcessor(opListID, ccprClipPath, fScissor, rtWidth, rtHeight,
-                                              *fContext->contextPriv().caps());
+                                              *fCaps);
             fAnalyticFPs.push_back(std::move(fp));
         }
         fCCPRClipPaths.reset();
diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h
index 6a8bc9e..fcdc66c 100644
--- a/src/gpu/GrReducedClip.h
+++ b/src/gpu/GrReducedClip.h
@@ -26,9 +26,8 @@
     using Element = SkClipStack::Element;
     using ElementList = SkTLList<SkClipStack::Element, 16>;
 
-    GrReducedClip(const SkClipStack&, const SkRect& queryBounds, GrContext* context,
-                  int maxWindowRectangles = 0, int maxAnalyticFPs = 0,
-                  int maxCCPRClipPaths = 0);
+    GrReducedClip(const SkClipStack&, const SkRect& queryBounds, const GrCaps* caps,
+                  int maxWindowRectangles = 0, int maxAnalyticFPs = 0, int maxCCPRClipPaths = 0);
 
     enum class InitialState : bool {
         kAllIn,
@@ -84,7 +83,7 @@
     bool maskRequiresAA() const { SkASSERT(!fMaskElements.isEmpty()); return fMaskRequiresAA; }
 
     bool drawAlphaClipMask(GrRenderTargetContext*) const;
-    bool drawStencilClipMask(GrRenderTargetContext*) const;
+    bool drawStencilClipMask(GrContext*, GrRenderTargetContext*) const;
 
     int numAnalyticFPs() const { return fAnalyticFPs.count() + fCCPRClipPaths.count(); }
 
@@ -132,7 +131,7 @@
 
     void makeEmpty();
 
-    GrContext* fContext;
+    const GrCaps* fCaps;
     const int fMaxWindowRectangles;
     const int fMaxAnalyticFPs;
     const int fMaxCCPRClipPaths;
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 369eee8..6b9e3d1 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1253,13 +1253,14 @@
         inverseVM.reset();
     }
 
+    const auto& caps = *this->caps()->shaderCaps();
     // TODO these need to be a geometry processors
-    auto innerEffect = GrRRectEffect::Make(innerEdgeType, *inner, fContext);
+    auto innerEffect = GrRRectEffect::Make(innerEdgeType, *inner, caps);
     if (!innerEffect) {
         return false;
     }
 
-    auto outerEffect = GrRRectEffect::Make(outerEdgeType, *outer, fContext);
+    auto outerEffect = GrRRectEffect::Make(outerEdgeType, *outer, caps);
     if (!outerEffect) {
         return false;
     }
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 9f348c2..f78ef18 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -490,7 +490,7 @@
         if (ditherRange >= 0) {
             static int ditherIndex = GrSkSLFP::NewIndex();
             auto ditherFP = GrSkSLFP::Make(context, ditherIndex, "Dither", SKSL_DITHER_SRC,
-                                           ditherRange);
+                                           &ditherRange, sizeof(ditherRange));
             if (ditherFP) {
                 grPaint->addColorFragmentProcessor(std::move(ditherFP));
             }
diff --git a/src/gpu/effects/GrAARectEffect.cpp b/src/gpu/effects/GrAARectEffect.cpp
new file mode 100644
index 0000000..9ee0ad5
--- /dev/null
+++ b/src/gpu/effects/GrAARectEffect.cpp
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrAARectEffect.fp; do not modify.
+ **************************************************************************************************/
+#include "GrAARectEffect.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
+#include "glsl/GrGLSLFragmentShaderBuilder.h"
+#include "glsl/GrGLSLProgramBuilder.h"
+#include "GrTexture.h"
+#include "SkSLCPP.h"
+#include "SkSLUtil.h"
+class GrGLSLAARectEffect : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLAARectEffect() {}
+    void emitCode(EmitArgs& args) override {
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        const GrAARectEffect& _outer = args.fFp.cast<GrAARectEffect>();
+        (void)_outer;
+        auto edgeType = _outer.edgeType();
+        (void)edgeType;
+        auto rect = _outer.rect();
+        (void)rect;
+        prevRect = float4(-1.0);
+        fRectUniformVar = args.fUniformHandler->addUniform(
+                kFragment_GrShaderFlag, kFloat4_GrSLType, kDefault_GrSLPrecision, "rectUniform");
+        fragBuilder->codeAppendf(
+                "float4 prevRect = float4(%f, %f, %f, %f);\nhalf alpha;\n@switch (%d) {\n    case "
+                "0:\n    case 2:\n        alpha = half(all(greaterThan(float4(sk_FragCoord.xy, "
+                "%s.zw), float4(%s.xy, sk_FragCoord.xy))) ? 1 : 0);\n        break;\n    "
+                "default:\n        half xSub, ySub;\n        xSub = half(min(sk_FragCoord.x - "
+                "%s.x, 0.0));\n        xSub += half(min(%s.z - sk_FragCoord.x, 0.0));\n        "
+                "ySub = half(min(sk_FragCoord.y - %s.y, 0.0));\n        ySub += half(min(%s.w - "
+                "sk_FragCoord.y, 0.0));\n        alpha = half((1",
+                prevRect.left(),
+                prevRect.top(),
+                prevRect.right(),
+                prevRect.bottom(),
+                (int)_outer.edgeType(),
+                args.fUniformHandler->getUniformCStr(fRectUniformVar),
+                args.fUniformHandler->getUniformCStr(fRectUniformVar),
+                args.fUniformHandler->getUniformCStr(fRectUniformVar),
+                args.fUniformHandler->getUniformCStr(fRectUniformVar),
+                args.fUniformHandler->getUniformCStr(fRectUniformVar),
+                args.fUniformHandler->getUniformCStr(fRectUniformVar));
+        fragBuilder->codeAppendf(
+                ".0 + max(float(xSub), -1.0)) * (1.0 + max(float(ySub), -1.0)));\n}\n@if (%d == 2 "
+                "|| %d == 3) {\n    alpha = half(1.0 - float(alpha));\n}\n%s = %s * alpha;\n",
+                (int)_outer.edgeType(),
+                (int)_outer.edgeType(),
+                args.fOutputColor,
+                args.fInputColor);
+    }
+
+private:
+    void onSetData(const GrGLSLProgramDataManager& pdman,
+                   const GrFragmentProcessor& _proc) override {
+        const GrAARectEffect& _outer = _proc.cast<GrAARectEffect>();
+        auto edgeType = _outer.edgeType();
+        (void)edgeType;
+        auto rect = _outer.rect();
+        (void)rect;
+        UniformHandle& rectUniform = fRectUniformVar;
+        (void)rectUniform;
+
+        const SkRect& newRect = GrProcessorEdgeTypeIsAA(edgeType) ? rect.makeInset(.5f, .5f) : rect;
+        if (newRect != prevRect) {
+            pdman.set4f(rectUniform, newRect.fLeft, newRect.fTop, newRect.fRight, newRect.fBottom);
+            prevRect = newRect;
+        }
+    }
+    SkRect prevRect = float4(0);
+    UniformHandle fRectUniformVar;
+};
+GrGLSLFragmentProcessor* GrAARectEffect::onCreateGLSLInstance() const {
+    return new GrGLSLAARectEffect();
+}
+void GrAARectEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
+                                           GrProcessorKeyBuilder* b) const {
+    b->add32((int32_t)fEdgeType);
+}
+bool GrAARectEffect::onIsEqual(const GrFragmentProcessor& other) const {
+    const GrAARectEffect& that = other.cast<GrAARectEffect>();
+    (void)that;
+    if (fEdgeType != that.fEdgeType) return false;
+    if (fRect != that.fRect) return false;
+    return true;
+}
+GrAARectEffect::GrAARectEffect(const GrAARectEffect& src)
+        : INHERITED(kGrAARectEffect_ClassID, src.optimizationFlags())
+        , fEdgeType(src.fEdgeType)
+        , fRect(src.fRect) {}
+std::unique_ptr<GrFragmentProcessor> GrAARectEffect::clone() const {
+    return std::unique_ptr<GrFragmentProcessor>(new GrAARectEffect(*this));
+}
+GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrAARectEffect);
+#if GR_TEST_UTILS
+std::unique_ptr<GrFragmentProcessor> GrAARectEffect::TestCreate(GrProcessorTestData* d) {
+    SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
+                                   d->fRandom->nextSScalar1(),
+                                   d->fRandom->nextSScalar1(),
+                                   d->fRandom->nextSScalar1());
+    std::unique_ptr<GrFragmentProcessor> fp;
+    do {
+        GrClipEdgeType edgeType =
+                static_cast<GrClipEdgeType>(d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
+
+        fp = GrAARectEffect::Make(edgeType, rect);
+    } while (nullptr == fp);
+    return fp;
+}
+#endif
diff --git a/src/gpu/effects/GrAARectEffect.fp b/src/gpu/effects/GrAARectEffect.fp
new file mode 100644
index 0000000..95064dd
--- /dev/null
+++ b/src/gpu/effects/GrAARectEffect.fp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+layout(key) in GrClipEdgeType edgeType;
+layout(ctype=SkRect) in float4 rect;
+layout(ctype=SkRect) float4 prevRect = float4(-1);
+uniform float4 rectUniform;
+
+@optimizationFlags { kCompatibleWithCoverageAsAlpha_OptimizationFlag }
+
+void main() {
+    half alpha;
+    @switch (edgeType) {
+        case GrClipEdgeType::kFillBW: // fall through
+        case GrClipEdgeType::kInverseFillBW:
+            // non-AA
+            alpha = all(greaterThan(float4(sk_FragCoord.xy, rectUniform.zw),
+                                    float4(rectUniform.xy, sk_FragCoord.xy))) ? 1 : 0;
+            break;
+        default:
+            // The amount of coverage removed in x and y by the edges is computed as a pair of
+            // negative numbers, xSub and ySub.
+            half xSub, ySub;
+            xSub = min(sk_FragCoord.x - rectUniform.x, 0.0);
+            xSub += min(rectUniform.z - sk_FragCoord.x, 0.0);
+            ySub = min(sk_FragCoord.y - rectUniform.y, 0.0);
+            ySub += min(rectUniform.w - sk_FragCoord.y, 0.0);
+            // Now compute coverage in x and y and multiply them to get the fraction of the pixel
+            // covered.
+            alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));
+    }
+
+    @if (edgeType == GrClipEdgeType::kInverseFillBW || edgeType == GrClipEdgeType::kInverseFillAA) {
+        alpha = 1.0 - alpha;
+    }
+    sk_OutColor = sk_InColor * alpha;
+}
+
+@setData(pdman) {
+    const SkRect& newRect = GrProcessorEdgeTypeIsAA(edgeType) ?
+                            rect.makeInset(.5f, .5f) : rect;
+    if (newRect != prevRect) {
+        pdman.set4f(rectUniform, newRect.fLeft, newRect.fTop, newRect.fRight, newRect.fBottom);
+        prevRect = newRect;
+    }
+}
+
+@test(d) {
+    SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
+                                   d->fRandom->nextSScalar1(),
+                                   d->fRandom->nextSScalar1(),
+                                   d->fRandom->nextSScalar1());
+    std::unique_ptr<GrFragmentProcessor> fp;
+    do {
+        GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(
+                d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
+
+        fp = GrAARectEffect::Make(edgeType, rect);
+    } while (nullptr == fp);
+    return fp;
+}
diff --git a/src/gpu/effects/GrAARectEffect.h b/src/gpu/effects/GrAARectEffect.h
new file mode 100644
index 0000000..94974e2
--- /dev/null
+++ b/src/gpu/effects/GrAARectEffect.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**************************************************************************************************
+ *** This file was autogenerated from GrAARectEffect.fp; do not modify.
+ **************************************************************************************************/
+#ifndef GrAARectEffect_DEFINED
+#define GrAARectEffect_DEFINED
+#include "SkTypes.h"
+#include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
+class GrAARectEffect : public GrFragmentProcessor {
+public:
+    const GrClipEdgeType& edgeType() const { return fEdgeType; }
+    const SkRect& rect() const { return fRect; }
+    static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, SkRect rect) {
+        return std::unique_ptr<GrFragmentProcessor>(new GrAARectEffect(edgeType, rect));
+    }
+    GrAARectEffect(const GrAARectEffect& src);
+    std::unique_ptr<GrFragmentProcessor> clone() const override;
+    const char* name() const override { return "AARectEffect"; }
+
+private:
+    GrAARectEffect(GrClipEdgeType edgeType, SkRect rect)
+            : INHERITED(kGrAARectEffect_ClassID,
+                        (OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
+            , fEdgeType(edgeType)
+            , fRect(rect) {}
+    GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
+    void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override;
+    bool onIsEqual(const GrFragmentProcessor&) const override;
+    GR_DECLARE_FRAGMENT_PROCESSOR_TEST
+    GrClipEdgeType fEdgeType;
+    SkRect fRect;
+    typedef GrFragmentProcessor INHERITED;
+};
+#endif
diff --git a/src/gpu/effects/GrConvexPolyEffect.cpp b/src/gpu/effects/GrConvexPolyEffect.cpp
index a0440f0..4751fec 100644
--- a/src/gpu/effects/GrConvexPolyEffect.cpp
+++ b/src/gpu/effects/GrConvexPolyEffect.cpp
@@ -7,52 +7,13 @@
 
 #include "GrConvexPolyEffect.h"
 #include "SkPathPriv.h"
+#include "effects/GrAARectEffect.h"
 #include "effects/GrConstColorProcessor.h"
-#include "effects/GrSkSLFP.h"
 #include "glsl/GrGLSLFragmentProcessor.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLProgramDataManager.h"
 #include "glsl/GrGLSLUniformHandler.h"
 
-GR_FP_SRC_STRING SKSL_AARECT_SRC = R"(
-layout(key) in GrClipEdgeType edgeType;
-layout(ctype=SkRect) in float4 rect;
-uniform float4 rectUniform;
-
-void main(int x, int y, inout half4 color) {
-    half alpha;
-    @switch (edgeType) {
-        case GrClipEdgeType::kFillBW: // fall through
-        case GrClipEdgeType::kInverseFillBW:
-            // non-AA
-            alpha = all(greaterThan(float4(x, y, rectUniform.zw),
-                                    float4(rectUniform.xy, x, y))) ? 1 : 0;
-            break;
-        default:
-            // The amount of coverage removed in x and y by the edges is computed as a pair of
-            // negative numbers, xSub and ySub.
-            half xSub, ySub;
-            xSub = min(x - rectUniform.x, 0.0);
-            xSub += min(rectUniform.z - x, 0.0);
-            ySub = min(y - rectUniform.y, 0.0);
-            ySub += min(rectUniform.w - y, 0.0);
-            // Now compute coverage in x and y and multiply them to get the fraction of the pixel
-            // covered.
-            alpha = (1.0 + max(xSub, -1.0)) * (1.0 + max(ySub, -1.0));
-    }
-
-    @if (edgeType == GrClipEdgeType::kInverseFillBW || edgeType == GrClipEdgeType::kInverseFillAA) {
-        alpha = 1.0 - alpha;
-    }
-    color *= alpha;
-}
-)";
-
-struct AARectInputs {
-    GrClipEdgeType fEdgeType;
-    SkRect fRect;
-};
-
 //////////////////////////////////////////////////////////////////////////////
 
 class GrGLConvexPolyEffect : public GrGLSLFragmentProcessor {
@@ -127,8 +88,7 @@
 //////////////////////////////////////////////////////////////////////////////
 
 std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType type,
-                                                              const SkPath& path,
-                                                              GrContext* context) {
+                                                              const SkPath& path) {
     if (GrClipEdgeType::kHairlineAA == type) {
         return nullptr;
     }
@@ -198,34 +158,12 @@
     return Make(type, n, edges);
 }
 
-static void aa_rect_set_data_hook(const GrGLSLProgramDataManager& pdman,
-                                  const GrGLSLSkSLFP& glslProc,
-                                  const AARectInputs& inputs,
-                                  SkRect* prevRect) {
-    if (inputs.fRect != *prevRect) {
-        const SkRect& newRect = GrProcessorEdgeTypeIsAA(inputs.fEdgeType) ?
-                                inputs.fRect.makeInset(.5f, .5f) : inputs.fRect;
-        pdman.set4f(glslProc.uniformHandle(0), newRect.fLeft, newRect.fTop, newRect.fRight,
-                    newRect.fBottom);
-        *prevRect = inputs.fRect;
-    }
-}
-
 std::unique_ptr<GrFragmentProcessor> GrConvexPolyEffect::Make(GrClipEdgeType edgeType,
-                                                              const SkRect& rect,
-                                                              GrContext* context) {
+                                                              const SkRect& rect) {
     if (GrClipEdgeType::kHairlineAA == edgeType){
         return nullptr;
     }
-    static int aaRectIndex = GrSkSLFP::NewIndex();
-    AARectInputs inputs;
-    inputs.fEdgeType = edgeType;
-    inputs.fRect = rect;
-    std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(context, aaRectIndex, "AARect",
-                                                      SKSL_AARECT_SRC, inputs,
-                                                      SkRect::MakeXYWH(-1, -1, -1, -1),
-                                                      aa_rect_set_data_hook);
-    return std::unique_ptr<GrFragmentProcessor>(result.release());
+    return GrAARectEffect::Make(edgeType, rect);
 }
 
 GrConvexPolyEffect::~GrConvexPolyEffect() {}
diff --git a/src/gpu/effects/GrConvexPolyEffect.h b/src/gpu/effects/GrConvexPolyEffect.h
index 886fed4..d2ab4c9 100644
--- a/src/gpu/effects/GrConvexPolyEffect.h
+++ b/src/gpu/effects/GrConvexPolyEffect.h
@@ -50,14 +50,12 @@
      * Creates an effect that clips against the path. If the path is not a convex polygon, is
      * inverse filled, or has too many edges, this will return nullptr.
      */
-    static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkPath&,
-                                                     GrContext* context);
+    static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkPath&);
 
     /**
-     * Creates an effect that fills inside the rect with AA edges.
+     * Creates an effect that fills inside the rect with AA edges..
      */
-    static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRect&,
-                                                     GrContext* context);
+    static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRect&);
 
     ~GrConvexPolyEffect() override;
 
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 0666089..6478306 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -7,8 +7,6 @@
 
 #include "GrRRectEffect.h"
 
-#include "GrContext.h"
-#include "GrContextPriv.h"
 #include "GrConvexPolyEffect.h"
 #include "GrFragmentProcessor.h"
 #include "GrOvalEffect.h"
@@ -124,7 +122,7 @@
     do {
         GrClipEdgeType et =
                 (GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
-        fp = GrRRectEffect::Make(et, rrect, d->context());
+        fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps());
     } while (nullptr == fp);
     return fp;
 }
@@ -473,7 +471,7 @@
     std::unique_ptr<GrFragmentProcessor> fp;
     do {
         GrClipEdgeType et = (GrClipEdgeType)d->fRandom->nextULessThan(kGrClipEdgeTypeCnt);
-        fp = GrRRectEffect::Make(et, rrect, d->context());
+        fp = GrRRectEffect::Make(et, rrect, *d->caps()->shaderCaps());
     } while (nullptr == fp);
     return fp;
 }
@@ -672,14 +670,13 @@
 
 std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType,
                                                          const SkRRect& rrect,
-                                                         GrContext* context) {
+                                                         const GrShaderCaps& caps) {
     if (rrect.isRect()) {
-        return GrConvexPolyEffect::Make(edgeType, rrect.getBounds(), context);
+        return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
     }
 
     if (rrect.isOval()) {
-        return GrOvalEffect::Make(edgeType, rrect.getBounds(),
-                                  *context->contextPriv().caps()->shaderCaps());
+        return GrOvalEffect::Make(edgeType, rrect.getBounds(), caps);
     }
 
     if (rrect.isSimple()) {
@@ -687,7 +684,7 @@
             SkRRectPriv::GetSimpleRadii(rrect).fY < kRadiusMin) {
             // In this case the corners are extremely close to rectangular and we collapse the
             // clip to a rectangular clip.
-            return GrConvexPolyEffect::Make(edgeType, rrect.getBounds(), context);
+            return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
         }
         if (SkRRectPriv::GetSimpleRadii(rrect).fX == SkRRectPriv::GetSimpleRadii(rrect).fY) {
             return CircularRRectEffect::Make(edgeType, CircularRRectEffect::kAll_CornerFlags,
@@ -752,7 +749,7 @@
                 return CircularRRectEffect::Make(edgeType, cornerFlags, *rr);
             }
             case CircularRRectEffect::kNone_CornerFlags:
-                return GrConvexPolyEffect::Make(edgeType, rrect.getBounds(), context);
+                return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
             default: {
                 if (squashedRadii) {
                     // If we got here then we squashed some but not all the radii to zero. (If all
diff --git a/src/gpu/effects/GrRRectEffect.h b/src/gpu/effects/GrRRectEffect.h
index f44de74..55ef535 100644
--- a/src/gpu/effects/GrRRectEffect.h
+++ b/src/gpu/effects/GrRRectEffect.h
@@ -12,7 +12,6 @@
 #include "GrTypesPriv.h"
 #include "SkRefCnt.h"
 
-class GrContext;
 class GrFragmentProcessor;
 class GrShaderCaps;
 class GrProcessor;
@@ -24,7 +23,7 @@
  * Creates an effect that performs anti-aliased clipping against a SkRRect. It doesn't support
  * all varieties of SkRRect so the caller must check for a nullptr return.
  */
-std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRRect&, GrContext*);
+std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType, const SkRRect&, const GrShaderCaps&);
 };
 
 #endif
diff --git a/src/gpu/effects/GrSkSLFP.cpp b/src/gpu/effects/GrSkSLFP.cpp
index 3174d40..aa81ea5 100644
--- a/src/gpu/effects/GrSkSLFP.cpp
+++ b/src/gpu/effects/GrSkSLFP.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "GrSkSLFP.h"
+#include "glsl/GrGLSLFragmentProcessor.h"
 #include "glsl/GrGLSLFragmentShaderBuilder.h"
 #include "glsl/GrGLSLProgramBuilder.h"
 #include "GrContext.h"
@@ -33,9 +34,6 @@
                 if (var.fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
                     fInputVars.push_back(&var);
                 }
-                if (var.fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
-                    fUniformVars.push_back(&var);
-                }
                 if (var.fModifiers.fLayout.fKey) {
                     fKeyVars.push_back(&var);
                 }
@@ -55,8 +53,7 @@
     size_t offset = 0;
     for (const auto& v : fInputVars) {
         SkSL::String name(v->fName);
-        if (v->fType.kind() == SkSL::Type::kEnum_Kind ||
-            &v->fType == fCompiler.context().fInt_Type.get()) {
+        if (&v->fType == fCompiler.context().fInt_Type.get()) {
             offset = SkAlign4(offset);
             int32_t v = *(int32_t*) (((uint8_t*) inputs) + offset);
             inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v)));
@@ -83,172 +80,178 @@
     return result;
 }
 
-GrGLSLSkSLFP::GrGLSLSkSLFP(SkSL::Context* context,
-                           const std::vector<const SkSL::Variable*>* uniformVars,
-                           SkSL::String glsl,
-                           std::vector<SkSL::Compiler::FormatArg> formatArgs,
-                           void* extraData)
-        : fContext(*context)
-        , fUniformVars(*uniformVars)
-        , fGLSL(glsl)
-        , fFormatArgs(formatArgs)
-        , fExtraData(extraData) {}
+class GrGLSLSkSLFP : public GrGLSLFragmentProcessor {
+public:
+    GrGLSLSkSLFP(const SkSL::Context* context, const std::vector<const SkSL::Variable*>* inputVars,
+                 SkSL::String glsl, std::vector<SkSL::Compiler::FormatArg> formatArgs)
+            : fContext(*context)
+            , fInputVars(*inputVars)
+            , fGLSL(glsl)
+            , fFormatArgs(formatArgs) {}
 
-GrSLType GrGLSLSkSLFP::uniformType(const SkSL::Type& type) {
-    if (type == *fContext.fFloat_Type) {
+    GrSLType uniformType(const SkSL::Type& type) {
+        if (type == *fContext.fFloat_Type) {
+            return kFloat_GrSLType;
+        } else if (type == *fContext.fHalf_Type) {
+            return kHalf_GrSLType;
+        } else if (type == *fContext.fFloat2_Type) {
+            return kFloat2_GrSLType;
+        } else if (type == *fContext.fHalf2_Type) {
+            return kHalf2_GrSLType;
+        } else if (type == *fContext.fFloat4_Type) {
+            return kFloat4_GrSLType;
+        } else if (type == *fContext.fHalf4_Type) {
+            return kHalf4_GrSLType;
+        } else if (type == *fContext.fFloat4x4_Type) {
+            return kFloat4x4_GrSLType;
+        } else if (type == *fContext.fHalf4x4_Type) {
+            return kHalf4x4_GrSLType;
+        } else if (type == *fContext.fBool_Type) {
+            return kBool_GrSLType;
+        } else if (type == *fContext.fInt_Type) {
+            return kInt_GrSLType;
+        }
+        printf("%s\n", SkSL::String(type.fName).c_str());
+        SK_ABORT("unsupported uniform type");
         return kFloat_GrSLType;
-    } else if (type == *fContext.fHalf_Type) {
-        return kHalf_GrSLType;
-    } else if (type == *fContext.fFloat2_Type) {
-        return kFloat2_GrSLType;
-    } else if (type == *fContext.fHalf2_Type) {
-        return kHalf2_GrSLType;
-    } else if (type == *fContext.fFloat4_Type) {
-        return kFloat4_GrSLType;
-    } else if (type == *fContext.fHalf4_Type) {
-        return kHalf4_GrSLType;
-    } else if (type == *fContext.fFloat4x4_Type) {
-        return kFloat4x4_GrSLType;
-    } else if (type == *fContext.fHalf4x4_Type) {
-        return kHalf4x4_GrSLType;
-    } else if (type == *fContext.fBool_Type) {
-        return kBool_GrSLType;
-    } else if (type == *fContext.fInt_Type) {
-        return kInt_GrSLType;
     }
-    SK_ABORT("unsupported uniform type");
-    return kFloat_GrSLType;
-}
 
-void* GrGLSLSkSLFP::extraData() const {
-    return fExtraData;
-}
-
-void GrGLSLSkSLFP::emitCode(EmitArgs& args) {
-    for (const auto& v : fUniformVars) {
-        if (v->fType != *fContext.fFragmentProcessor_Type) {
-            fUniformHandles.push_back(args.fUniformHandler->addUniform(
-                                                               kFragment_GrShaderFlag,
-                                                               this->uniformType(v->fType),
-                                                               kDefault_GrSLPrecision,
-                                                               SkSL::String(v->fName).c_str()));
+    void emitCode(EmitArgs& args) override {
+        for (const auto& v : fInputVars) {
+            if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag && v->fType !=
+                                                                *fContext.fFragmentProcessor_Type) {
+                fUniformHandles.push_back(args.fUniformHandler->addUniform(
+                                                                   kFragment_GrShaderFlag,
+                                                                   this->uniformType(v->fType),
+                                                                   kDefault_GrSLPrecision,
+                                                                   SkSL::String(v->fName).c_str()));
+            }
         }
-    }
-    std::vector<SkString> childNames;
-    for (int i = 0; i < this->numChildProcessors(); ++i) {
-        childNames.push_back(SkStringPrintf("_child%d", i));
-        this->emitChild(i, &childNames[i], args);
-    }
-    GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
-    int substringStartIndex = 0;
-    int formatArgIndex = 0;
-    for (size_t i = 0; i < fGLSL.length(); ++i) {
-        char c = fGLSL[i];
-        if (c == '%') {
-            fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
-                                    i - substringStartIndex);
-            ++i;
-            c = fGLSL[i];
-            switch (c) {
-                case 's': {
-                    SkSL::Compiler::FormatArg& arg = fFormatArgs[formatArgIndex++];
-                    switch (arg.fKind) {
-                        case SkSL::Compiler::FormatArg::Kind::kInput:
-                            fragBuilder->codeAppend(args.fInputColor);
-                            break;
-                        case SkSL::Compiler::FormatArg::Kind::kOutput:
-                            fragBuilder->codeAppend(args.fOutputColor);
-                            break;
-                        case SkSL::Compiler::FormatArg::Kind::kUniform:
-                            fragBuilder->codeAppend(args.fUniformHandler->getUniformCStr(
-                                                                  fUniformHandles[arg.fIndex]));
-                            break;
-                        case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
-                            fragBuilder->codeAppend(childNames[arg.fIndex].c_str());
-                            break;
+        std::vector<SkString> childNames;
+        for (int i = 0; i < this->numChildProcessors(); ++i) {
+            childNames.push_back(SkStringPrintf("_child%d", i));
+            this->emitChild(i, &childNames[i], args);
+        }
+        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
+        int substringStartIndex = 0;
+        int formatArgIndex = 0;
+        for (size_t i = 0; i < fGLSL.length(); ++i) {
+            char c = fGLSL[i];
+            if (c == '%') {
+                fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
+                                        i - substringStartIndex);
+                ++i;
+                c = fGLSL[i];
+                switch (c) {
+                    case 's': {
+                        SkSL::Compiler::FormatArg& arg = fFormatArgs[formatArgIndex++];
+                        switch (arg.fKind) {
+                            case SkSL::Compiler::FormatArg::Kind::kInput:
+                                fragBuilder->codeAppend(args.fInputColor);
+                                break;
+                            case SkSL::Compiler::FormatArg::Kind::kOutput:
+                                fragBuilder->codeAppend(args.fOutputColor);
+                                break;
+                            case SkSL::Compiler::FormatArg::Kind::kUniform:
+                                fragBuilder->codeAppend(args.fUniformHandler->getUniformCStr(
+                                                                      fUniformHandles[arg.fIndex]));
+                                break;
+                            case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
+                                fragBuilder->codeAppend(childNames[arg.fIndex].c_str());
+                                break;
+                        }
+                        break;
                     }
-                    break;
+                    default:
+                        fragBuilder->codeAppendf("%c", c);
                 }
-                default:
-                    fragBuilder->codeAppendf("%c", c);
+                substringStartIndex = i + 1;
             }
-            substringStartIndex = i + 1;
         }
+        fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
+                                fGLSL.length() - substringStartIndex);
     }
-    fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
-                            fGLSL.length() - substringStartIndex);
-}
 
-void GrGLSLSkSLFP::onSetData(const GrGLSLProgramDataManager& pdman,
-                             const GrFragmentProcessor& _proc) {
-    size_t uniformIndex = 0;
-    size_t offset = 0;
-    const GrSkSLFP& outer = _proc.cast<GrSkSLFP>();
-    uint8_t* inputs = (uint8_t*) outer.fInputs;
-    const SkSL::Context& context = outer.fFactory->fCompiler.context();
-    for (const auto& v : outer.fFactory->fInputVars) {
-        if (&v->fType == context.fFloat4_Type.get() ||
-            &v->fType == context.fHalf4_Type.get()) {
-            float f1, f2, f3, f4;
-            switch (v->fModifiers.fLayout.fCType) {
-                case SkSL::Layout::CType::kSkPMColor:
-                    f1 = inputs[offset++] / 255.0;
-                    f2 = inputs[offset++] / 255.0;
-                    f3 = inputs[offset++] / 255.0;
-                    f4 = inputs[offset++] / 255.0;
-                    break;
-                case SkSL::Layout::CType::kSkRect: // fall through
-                case SkSL::Layout::CType::kDefault:
-                    offset = SkAlign4(offset);
-                    f1 = *(float*) (inputs + offset);
-                    offset += sizeof(float);
-                    f2 = *(float*) (inputs + offset);
-                    offset += sizeof(float);
-                    f3 = *(float*) (inputs + offset);
-                    offset += sizeof(float);
-                    f4 = *(float*) (inputs + offset);
-                    offset += sizeof(float);
-                    break;
-                default:
-                    SK_ABORT("unsupported uniform ctype");
+    void onSetData(const GrGLSLProgramDataManager& pdman,
+                   const GrFragmentProcessor& _proc) override {
+        size_t uniformIndex = 0;
+        size_t offset = 0;
+        const GrSkSLFP& outer = _proc.cast<GrSkSLFP>();
+        char* inputs = (char*) outer.fInputs.get();
+        const SkSL::Context& context = outer.fFactory->fCompiler.context();
+        for (const auto& v : outer.fFactory->fInputVars) {
+            if (&v->fType == context.fFloat4_Type.get() ||
+                &v->fType == context.fHalf4_Type.get()) {
+                float f1, f2, f3, f4;
+                switch (v->fModifiers.fLayout.fCType) {
+                    case SkSL::Layout::CType::kSkPMColor:
+                        f1 = ((uint8_t*) inputs)[offset++] / 255.0;
+                        f2 = ((uint8_t*) inputs)[offset++] / 255.0;
+                        f3 = ((uint8_t*) inputs)[offset++] / 255.0;
+                        f4 = ((uint8_t*) inputs)[offset++] / 255.0;
+                        break;
+                    case SkSL::Layout::CType::kSkRect: // fall through
+                    case SkSL::Layout::CType::kDefault:
+                        offset = SkAlign4(offset);
+                        f1 = *(float*) (inputs + offset);
+                        offset += sizeof(float);
+                        f2 = *(float*) (inputs + offset);
+                        offset += sizeof(float);
+                        f3 = *(float*) (inputs + offset);
+                        offset += sizeof(float);
+                        f4 = *(float*) (inputs + offset);
+                        offset += sizeof(float);
+                        break;
+                    default:
+                        SK_ABORT("unsupported uniform ctype");
+                }
+                if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
+                    pdman.set4f(fUniformHandles[uniformIndex++], f1, f2, f3, f4);
+                }
+            } else if (&v->fType == context.fInt_Type.get()) {
+                int32_t i = *(int*) (inputs + offset);
+                offset += sizeof(int32_t);
+                if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
+                    pdman.set1i(fUniformHandles[uniformIndex++], i);
+                }
+            } else if (&v->fType == context.fBool_Type.get()) {
+                SkASSERT(!(v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag));
+                ++offset;
+            } else {
+                SkASSERT(&v->fType == context.fFragmentProcessor_Type.get());
             }
-            if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
-                pdman.set4f(fUniformHandles[uniformIndex++], f1, f2, f3, f4);
-            }
-        } else if (v->fType.kind() == SkSL::Type::kEnum_Kind ||
-                   &v->fType == context.fInt_Type.get()) {
-            int32_t i = *(int*) (inputs + offset);
-            offset += sizeof(int32_t);
-            if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
-                pdman.set1i(fUniformHandles[uniformIndex++], i);
-            }
-        } else if (&v->fType == context.fBool_Type.get()) {
-            SkASSERT(!(v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag));
-            ++offset;
-        } else {
-            SkASSERT(&v->fType == context.fFragmentProcessor_Type.get());
         }
     }
-    if (fUniformHandles.size() && outer.fSetDataHook) {
-        outer.fSetDataHook(pdman, *this, outer.fInputs, fExtraData);
-    }
+
+    const SkSL::Context& fContext;
+    const std::vector<const SkSL::Variable*>& fInputVars;
+    // nearly-finished GLSL; still contains printf-style "%s" format tokens
+    const SkSL::String fGLSL;
+    std::vector<SkSL::Compiler::FormatArg> fFormatArgs;
+    std::vector<UniformHandle> fUniformHandles;
+};
+
+std::unique_ptr<GrSkSLFP> GrSkSLFP::Make(GrContext* context, int index, const char* name,
+                                         const char* sksl, const void* inputs,
+                                         size_t inputSize) {
+    return std::unique_ptr<GrSkSLFP>(new GrSkSLFP(context->contextPriv().getFPFactoryCache(),
+                                                  context->contextPriv().caps()->shaderCaps(),
+                                                  index, name, sksl, inputs, inputSize));
 }
 
 GrSkSLFP::GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps,
                    int index, const char* name, const char* sksl, const void* inputs,
-                   size_t inputSize, const void* extraData, size_t extraDataSize,
-                   UntypedDataHookFn setDataHook)
+                   size_t inputSize)
         : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
         , fFactoryCache(factoryCache)
         , fShaderCaps(sk_ref_sp(shaderCaps))
         , fIndex(index)
         , fName(name)
         , fSkSL(sksl)
-        , fInputs(inputs)
-        , fInputSize(inputSize)
-        , fExtraData(extraData)
-        , fExtraDataSize(extraDataSize)
-        , fSetDataHook(setDataHook) {}
+        , fInputs(new int8_t[inputSize])
+        , fInputSize(inputSize) {
+    memcpy(fInputs.get(), inputs, inputSize);
+}
 
 GrSkSLFP::GrSkSLFP(const GrSkSLFP& other)
         : INHERITED(kGrSkSLFP_ClassID, kNone_OptimizationFlags)
@@ -258,11 +261,10 @@
         , fIndex(other.fIndex)
         , fName(other.fName)
         , fSkSL(other.fSkSL)
-        , fInputs(other.fInputs)
-        , fInputSize(other.fInputSize)
-        , fExtraData(other.fExtraData)
-        , fExtraDataSize(other.fExtraDataSize)
-        , fSetDataHook(other.fSetDataHook) {}
+        , fInputs(new int8_t[other.fInputSize])
+        , fInputSize(other.fInputSize) {
+    memcpy(fInputs.get(), other.fInputs.get(), fInputSize);
+}
 
 const char* GrSkSLFP::name() const {
     return fName;
@@ -284,30 +286,24 @@
 
 GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
     this->createFactory();
-    const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs, fInputSize);
+    const SkSL::Program* specialized = fFactory->getSpecialization(fKey, fInputs.get(), fInputSize);
     SkSL::String glsl;
     std::vector<SkSL::Compiler::FormatArg> formatArgs;
     if (!fFactory->fCompiler.toPipelineStage(*specialized, &glsl, &formatArgs)) {
         printf("%s\n", fFactory->fCompiler.errorText().c_str());
         SkASSERT(false);
     }
-    void* result = ::operator new(sizeof(GrGLSLSkSLFP) + fExtraDataSize);
-    void* extraDataBytes = ((uint8_t*) result) + sizeof(GrGLSLSkSLFP);
-    if (fExtraDataSize) {
-        memcpy(extraDataBytes, fExtraData, fExtraDataSize);
-    }
-    return new (result) GrGLSLSkSLFP(specialized->fContext.get(), &fFactory->fUniformVars, glsl,
-                                     formatArgs, extraDataBytes);
+    return new GrGLSLSkSLFP(specialized->fContext.get(), &fFactory->fInputVars, glsl, formatArgs);
 }
 
 void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
                                      GrProcessorKeyBuilder* b) const {
     this->createFactory();
     size_t offset = 0;
-    uint8_t* inputs = (uint8_t*) fInputs;
+    char* inputs = (char*) fInputs.get();
     const SkSL::Context& context = fFactory->fCompiler.context();
     for (const auto& v : fFactory->fInputVars) {
-        if (v->fType.kind() == SkSL::Type::kEnum_Kind || &v->fType == context.fInt_Type.get()) {
+        if (&v->fType == context.fInt_Type.get()) {
             offset = SkAlign4(offset);
             if (v->fModifiers.fLayout.fKey) {
                 fKey += inputs[offset + 0];
@@ -354,20 +350,11 @@
     const GrSkSLFP& sk = other.cast<GrSkSLFP>();
     SkASSERT(fIndex != sk.fIndex || fInputSize == sk.fInputSize);
     return fIndex == sk.fIndex &&
-            !memcmp(fInputs, sk.fInputs, fInputSize);
+            !memcmp(fInputs.get(), sk.fInputs.get(), fInputSize);
 }
 
 std::unique_ptr<GrFragmentProcessor> GrSkSLFP::clone() const {
-    void* placement = GrSkSLFP::operator new(sizeof(GrSkSLFP) + fInputSize + fExtraDataSize);
-    std::unique_ptr<GrSkSLFP> result(new (placement) GrSkSLFP(*this));
-    void* inputsTarget = ((int8_t*) placement) + sizeof(GrSkSLFP);
-    memcpy(inputsTarget, fInputs, fInputSize);
-    result->fInputs = inputsTarget;
-    if (fExtraData) {
-        void* extraDataTarget = ((int8_t*) placement) + sizeof(GrSkSLFP) + fInputSize;
-        memcpy(extraDataTarget, fExtraData, fExtraDataSize);
-        result->fExtraData = extraDataTarget;
-    }
+    std::unique_ptr<GrSkSLFP> result(new GrSkSLFP(*this));
     for (int i = 0; i < this->numChildProcessors(); ++i) {
         result->registerChildProcessor(this->childProcessor(i).clone());
     }
@@ -411,7 +398,6 @@
 
 #include "GrConstColorProcessor.h"
 #include "SkArithmeticImageFilter.h"
-#include "effects/GrConvexPolyEffect.h"
 
 extern const char* SKSL_ARITHMETIC_SRC;
 extern const char* SKSL_DITHER_SRC;
@@ -420,13 +406,14 @@
 using Value = SkSL::Program::Settings::Value;
 
 std::unique_ptr<GrFragmentProcessor> GrSkSLFP::TestCreate(GrProcessorTestData* d) {
-    int type = d->fRandom->nextULessThan(4);
+    int type = d->fRandom->nextULessThan(3);
     switch (type) {
         case 0: {
             static int ditherIndex = NewIndex();
             int rangeType = d->fRandom->nextULessThan(3);
             std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), ditherIndex, "Dither",
-                                                              SKSL_DITHER_SRC, rangeType);
+                                                              SKSL_DITHER_SRC, &rangeType,
+                                                              sizeof(rangeType));
             return std::unique_ptr<GrFragmentProcessor>(result.release());
         }
         case 1: {
@@ -439,7 +426,7 @@
             inputs.enforcePMColor = d->fRandom->nextBool();
             std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), arithmeticIndex,
                                                               "Arithmetic", SKSL_ARITHMETIC_SRC,
-                                                              inputs);
+                                                              &inputs, sizeof(inputs));
             result->addChild(GrConstColorProcessor::Make(
                                                         SK_PMColor4fWHITE,
                                                         GrConstColorProcessor::InputMode::kIgnore));
@@ -453,23 +440,9 @@
             }
             std::unique_ptr<GrSkSLFP> result = GrSkSLFP::Make(d->context(), overdrawIndex,
                                                               "Overdraw", SKSL_OVERDRAW_SRC,
-                                                              inputs);
+                                                              &inputs, sizeof(inputs));
             return std::unique_ptr<GrFragmentProcessor>(result.release());
         }
-        case 3: {
-            SkRect rect = SkRect::MakeLTRB(d->fRandom->nextSScalar1(),
-                                           d->fRandom->nextSScalar1(),
-                                           d->fRandom->nextSScalar1(),
-                                           d->fRandom->nextSScalar1());
-            std::unique_ptr<GrFragmentProcessor> fp;
-            do {
-                GrClipEdgeType edgeType = static_cast<GrClipEdgeType>(
-                        d->fRandom->nextULessThan(kGrClipEdgeTypeCnt));
-
-                fp = GrConvexPolyEffect::Make(edgeType, rect, d->context());
-            } while (nullptr == fp);
-            return fp;
-        }
     }
     SK_ABORT("unreachable");
     return nullptr;
diff --git a/src/gpu/effects/GrSkSLFP.h b/src/gpu/effects/GrSkSLFP.h
index ae9be33..c4acfd0 100644
--- a/src/gpu/effects/GrSkSLFP.h
+++ b/src/gpu/effects/GrSkSLFP.h
@@ -9,17 +9,12 @@
 #define GrSkSLFP_DEFINED
 
 #include "GrCaps.h"
-#include "GrContext.h"
-#include "GrContextPriv.h"
-#include "GrCoordTransform.h"
 #include "GrFragmentProcessor.h"
+#include "GrCoordTransform.h"
 #include "GrShaderCaps.h"
 #include "SkSLCompiler.h"
 #include "SkSLPipelineStageCodeGenerator.h"
 #include "SkRefCnt.h"
-#include "glsl/GrGLSLFragmentProcessor.h"
-#include "glsl/GrGLSLProgramDataManager.h"
-#include "glsl/GrGLSLUniformHandler.h"
 #include "../private/GrSkSLFPFactoryCache.h"
 
 #if GR_TEST_UTILS
@@ -30,16 +25,9 @@
 
 class GrContext;
 class GrSkSLFPFactory;
-class GrGLSLSkSLFP;
 
 class GrSkSLFP : public GrFragmentProcessor {
 public:
-    using UniformHandle = GrGLSLUniformHandler::UniformHandle;
-
-    template<typename Inputs, typename ExtraData>
-    using DataHookFn = void(const GrGLSLProgramDataManager& pdman, const GrGLSLSkSLFP& glslProc,
-                            const Inputs& inputs, ExtraData* extraData);
-
     /**
      * Returns a new unique identifier. Each different SkSL fragment processor should call
      * NewIndex once, statically, and use this index for all calls to Make.
@@ -78,72 +66,23 @@
      * 'NewIndex()'. Each given SkSL string should have a single, statically defined index
      * associated with it.
      */
-    template<typename Inputs>
-    static std::unique_ptr<GrSkSLFP> Make(GrContext* context, int index, const char* name,
-                                          const char* sksl, const Inputs& inputs) {
-        void* resultBytes = GrSkSLFP::operator new(sizeof(GrSkSLFP) + sizeof(Inputs));
-        void* inputBytes = (int8_t*) resultBytes + sizeof(GrSkSLFP);
-        memcpy(inputBytes, &inputs, sizeof(Inputs));
-        GrSkSLFP* result = new (resultBytes) GrSkSLFP(context->contextPriv().getFPFactoryCache(),
-                                                      context->contextPriv().caps()->shaderCaps(),
-                                                      index, name, sksl, inputBytes,
-                                                      sizeof(Inputs), nullptr, 0, nullptr);
-        return std::unique_ptr<GrSkSLFP>(result);
-    }
-
-    /**
-     * As the above overload of Make, but also tracks an additional extraData struct which is shared
-     * between all instances of the FP. The extraData struct is copied into the GrGLSLSkSLFP and is
-     * passed as an argument to the setDataHook function. setDataHook is called after the automatic
-     * handling of 'in uniform' variables is completed and is responsible for providing values for
-     * all non-'in' uniform variables.
-     */
-    template<typename Inputs, typename ExtraData>
-    static std::unique_ptr<GrSkSLFP> Make(GrContext* context, int index, const char* name,
-                                          const char* sksl, const Inputs& inputs,
-                                          const ExtraData& extraData,
-                                          DataHookFn<Inputs, ExtraData>* setDataHook) {
-        void* resultBytes = GrSkSLFP::operator new(sizeof(GrSkSLFP) + sizeof(Inputs) +
-                                                   sizeof(ExtraData));
-        void* inputBytes = (int8_t*) resultBytes + sizeof(GrSkSLFP);
-        memcpy(inputBytes, &inputs, sizeof(Inputs));
-        void* extraDataBytes = (int8_t*) resultBytes + sizeof(GrSkSLFP) + sizeof(Inputs);
-        memcpy(extraDataBytes, &extraData, sizeof(ExtraData));
-        auto genericFn = [setDataHook] (const GrGLSLProgramDataManager& pdman,
-                                        const GrGLSLSkSLFP& glslProc,
-                                        const void* inputs,
-                                        void* extraData) {
-            (*setDataHook)(pdman, glslProc, *reinterpret_cast<const Inputs*>(inputs),
-                           reinterpret_cast<ExtraData*>(extraData));
-        };
-        return std::unique_ptr<GrSkSLFP>(new (resultBytes) GrSkSLFP(
-                                                        context->contextPriv().getFPFactoryCache(),
-                                                        context->contextPriv().caps()->shaderCaps(),
-                                                        index, name, sksl, inputBytes,
-                                                        sizeof(Inputs), extraDataBytes,
-                                                        sizeof(ExtraData), genericFn));
-    }
+    static std::unique_ptr<GrSkSLFP> Make(
+                   GrContext* context,
+                   int index,
+                   const char* name,
+                   const char* sksl,
+                   const void* inputs,
+                   size_t inputSize);
 
     const char* name() const override;
 
     void addChild(std::unique_ptr<GrFragmentProcessor> child);
 
-    void setSetDataHook(void (*hook)(const GrGLSLProgramDataManager& pdman,
-                                     const GrGLSLSkSLFP& glslProc,
-                                     const GrSkSLFP& proc));
-
-    const void* inputs() const { return fInputs; }
-
     std::unique_ptr<GrFragmentProcessor> clone() const override;
 
 private:
-    using UntypedDataHookFn = std::function<void(const GrGLSLProgramDataManager&,
-                                                 const GrGLSLSkSLFP&,
-                                                 const void*,
-                                                 void*)>;
     GrSkSLFP(sk_sp<GrSkSLFPFactoryCache> factoryCache, const GrShaderCaps* shaderCaps, int fIndex,
-             const char* name, const char* sksl, const void* inputs, size_t inputSize,
-             const void* extraData, size_t extraDataSize, UntypedDataHookFn setDataHook);
+             const char* name, const char* sksl, const void* inputs, size_t inputSize);
 
     GrSkSLFP(const GrSkSLFP& other);
 
@@ -167,16 +106,10 @@
 
     const char* fSkSL;
 
-    const void* fInputs;
+    const std::unique_ptr<int8_t[]> fInputs;
 
     size_t fInputSize;
 
-    const void* fExtraData;
-
-    size_t fExtraDataSize;
-
-    UntypedDataHookFn fSetDataHook;
-
     mutable SkSL::String fKey;
 
     GR_DECLARE_FRAGMENT_PROCESSOR_TEST
@@ -188,41 +121,6 @@
     friend class GrSkSLFPFactory;
 };
 
-class GrGLSLSkSLFP : public GrGLSLFragmentProcessor {
-public:
-    GrGLSLSkSLFP(SkSL::Context* context, const std::vector<const SkSL::Variable*>* uniformVars,
-                 SkSL::String glsl, std::vector<SkSL::Compiler::FormatArg> formatArgs,
-                 void* extraData);
-
-    GrSLType uniformType(const SkSL::Type& type);
-
-    /**
-     * Returns the extraData pointer.
-     */
-    void* extraData() const;
-
-    void emitCode(EmitArgs& args) override;
-
-    void onSetData(const GrGLSLProgramDataManager& pdman,
-                   const GrFragmentProcessor& _proc) override;
-
-    UniformHandle uniformHandle(int index) const { return fUniformHandles[index]; }
-
-private:
-    const SkSL::Context& fContext;
-
-    const std::vector<const SkSL::Variable*>& fUniformVars;
-
-    // nearly-finished GLSL; still contains printf-style "%s" format tokens
-    const SkSL::String fGLSL;
-
-    std::vector<SkSL::Compiler::FormatArg> fFormatArgs;
-
-    std::vector<UniformHandle> fUniformHandles;
-
-    void* fExtraData;
-};
-
 /**
  * Produces GrFragmentProcessors from SkSL code. As the shader code produced from the SkSL depends
  * upon the inputs to the SkSL (static if's, etc.) we first create a factory for a given SkSL
@@ -249,8 +147,6 @@
 
     std::vector<const SkSL::Variable*> fInputVars;
 
-    std::vector<const SkSL::Variable*> fUniformVars;
-
     std::vector<const SkSL::Variable*> fKeyVars;
 
     std::unordered_map<SkSL::String, std::unique_ptr<const SkSL::Program>> fSpecializations;
diff --git a/src/image/SkImage_GpuBase.cpp b/src/image/SkImage_GpuBase.cpp
index 27bb2d8..66f91e3 100644
--- a/src/image/SkImage_GpuBase.cpp
+++ b/src/image/SkImage_GpuBase.cpp
@@ -260,18 +260,17 @@
         return sk_ref_sp(const_cast<SkImage_GpuBase*>(this));
     }
 
-    sk_sp<GrTextureProxy> proxy = this->asTextureProxyRef();
-
     sk_sp<GrRenderTargetContext> renderTargetContext(
-        fContext->contextPriv().makeDeferredRenderTargetContextWithFallback(
-            SkBackingFit::kExact, this->width(), this->height(), proxy->config(), nullptr));
+        fContext->contextPriv().makeDeferredRenderTargetContext(
+            SkBackingFit::kExact, this->width(), this->height(),
+            kRGBA_8888_GrPixelConfig, nullptr));
     if (!renderTargetContext) {
         return nullptr;
     }
 
     GrPaint paint;
     paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
-    paint.addColorTextureProcessor(std::move(proxy), SkMatrix::I());
+    paint.addColorTextureProcessor(this->asTextureProxyRef(), SkMatrix::I());
     paint.addColorFragmentProcessor(std::move(xform));
 
     const SkRect rect = SkRect::MakeIWH(this->width(), this->height());
diff --git a/src/sksl/SkSLCFGGenerator.cpp b/src/sksl/SkSLCFGGenerator.cpp
index f7492eb..c267058 100644
--- a/src/sksl/SkSLCFGGenerator.cpp
+++ b/src/sksl/SkSLCFGGenerator.cpp
@@ -596,11 +596,6 @@
         case Statement::kSwitch_Kind: {
             SwitchStatement& ss = (SwitchStatement&) **s;
             this->addExpression(cfg, &ss.fValue, true);
-            for (const auto& c : ss.fCases) {
-                if (c->fValue) {
-                    this->addExpression(cfg, &c->fValue, true);
-                }
-            }
             cfg.fBlocks[cfg.fCurrent].fNodes.push_back({ BasicBlock::Node::kStatement_Kind, false,
                                                          nullptr, s });
             BlockId start = cfg.fCurrent;
@@ -609,6 +604,11 @@
             for (const auto& c : ss.fCases) {
                 cfg.newBlock();
                 cfg.addExit(start, cfg.fCurrent);
+                if (c->fValue) {
+                    // technically this should go in the start block, but it doesn't actually matter
+                    // because it must be constant. Not worth running two loops for.
+                    this->addExpression(cfg, &c->fValue, true);
+                }
                 for (auto& caseStatement : c->fStatements) {
                     this->addStatement(cfg, &caseStatement);
                 }
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 09af06b..41ff5cc 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -57,7 +57,6 @@
 ;
 
 static const char* SKSL_PIPELINE_STAGE_INCLUDE =
-#include "sksl_enums.inc"
 #include "sksl_pipeline.inc"
 ;
 
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index 5f79896..bf9e5e1 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -933,13 +933,14 @@
     ASTType enumType(e.fOffset, e.fTypeName, ASTType::kIdentifier_Kind, {});
     const Type* type = this->convertType(enumType);
     Modifiers modifiers(layout, Modifiers::kConst_Flag);
-    AutoSymbolTable s(this);
-    std::shared_ptr<SymbolTable> symbols = fSymbolTable;
+    std::shared_ptr<SymbolTable> symbols(new SymbolTable(fSymbolTable, &fErrors));
+    fSymbolTable = symbols;
     for (size_t i = 0; i < e.fNames.size(); i++) {
         std::unique_ptr<Expression> value;
         if (e.fValues[i]) {
             value = this->convertExpression(*e.fValues[i]);
             if (!value) {
+                fSymbolTable = symbols->fParent;
                 return;
             }
             this->getConstantInt(*value, &currentValue);
@@ -955,6 +956,7 @@
     }
     fProgramElements->push_back(std::unique_ptr<ProgramElement>(new Enum(e.fOffset, e.fTypeName,
                                                                          symbols)));
+    fSymbolTable = symbols->fParent;
 }
 
 const Type* IRGenerator::convertType(const ASTType& type) {
diff --git a/src/sksl/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
index 694b368..4ca839d 100644
--- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
@@ -146,7 +146,8 @@
                                 found = true;
                                 break;
                             }
-                            if (var.fModifiers.fFlags & Modifiers::kUniform_Flag) {
+                            if (var.fModifiers.fFlags & (Modifiers::kIn_Flag |
+                                                         Modifiers::kUniform_Flag)) {
                                 ++index;
                             }
                         }
diff --git a/src/sksl/ir/SkSLProgram.h b/src/sksl/ir/SkSLProgram.h
index 719767d..4cbde55 100644
--- a/src/sksl/ir/SkSLProgram.h
+++ b/src/sksl/ir/SkSLProgram.h
@@ -223,14 +223,6 @@
     , fInheritedElements(inheritedElements)
     , fElements(std::move(elements)) {}
 
-    ~Program() {
-        // destroy elements in reverse order, so references to variables are destroyed before the
-        // variables themselves
-        while (fElements.size()) {
-            fElements.pop_back();
-        }
-    }
-
     iterator begin() {
         if (fInheritedElements) {
             return iterator(fInheritedElements->begin(), fInheritedElements->end(),
diff --git a/tests/ClipStackTest.cpp b/tests/ClipStackTest.cpp
index 0f1966b..2cfeaae 100644
--- a/tests/ClipStackTest.cpp
+++ b/tests/ClipStackTest.cpp
@@ -1041,6 +1041,7 @@
         }
 
         auto context = GrContext::MakeMock(nullptr);
+        const GrCaps* caps = context->contextPriv().caps();
 
         // Zero the memory we will new the GrReducedClip into. This ensures the elements gen ID
         // will be kInvalidGenID if left uninitialized.
@@ -1051,8 +1052,7 @@
         // Get the reduced version of the stack.
         SkRect queryBounds = kBounds;
         queryBounds.outset(kBounds.width() / 2, kBounds.height() / 2);
-        const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, queryBounds,
-                                                                         context.get());
+        const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, queryBounds, caps);
 
         REPORTER_ASSERT(reporter,
                         reduced->maskElements().isEmpty() ||
@@ -1112,12 +1112,12 @@
         SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
 
         auto context = GrContext::MakeMock(nullptr);
+        const GrCaps* caps = context->contextPriv().caps();
 
         SkAlignedSTStorage<1, GrReducedClip> storage;
         memset(storage.get(), 0, sizeof(GrReducedClip));
         GR_STATIC_ASSERT(0 == SkClipStack::kInvalidGenID);
-        const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, bounds,
-                                                                         context.get());
+        const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, bounds, caps);
 
         REPORTER_ASSERT(reporter, reduced->maskElements().count() == 1);
         // Clips will be cached based on the generation id. Make sure the gen id is valid.
@@ -1201,9 +1201,10 @@
 #undef XYWH
 #undef IXYWH
         auto context = GrContext::MakeMock(nullptr);
+        const GrCaps* caps = context->contextPriv().caps();
 
         for (size_t i = 0; i < SK_ARRAY_COUNT(testCases); ++i) {
-            const GrReducedClip reduced(stack, testCases[i].testBounds, context.get());
+            const GrReducedClip reduced(stack, testCases[i].testBounds, caps);
             REPORTER_ASSERT(reporter, reduced.maskElements().count() ==
                             testCases[i].reducedClipCount);
             SkASSERT(reduced.maskElements().count() == testCases[i].reducedClipCount);
@@ -1228,9 +1229,10 @@
     SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
 
     auto context = GrContext::MakeMock(nullptr);
+    const GrCaps* caps = context->contextPriv().caps();
 
     // At the time, this would crash.
-    const GrReducedClip reduced(stack, bounds, context.get());
+    const GrReducedClip reduced(stack, bounds, caps);
     REPORTER_ASSERT(reporter, reduced.maskElements().isEmpty());
 }
 
@@ -1246,10 +1248,11 @@
                           const SkRect& preXformQuery, ClipMethod expectedMethod,
                           int numExpectedElems = 0) {
     auto context = GrContext::MakeMock(nullptr);
+    const GrCaps* caps = context->contextPriv().caps();
 
     SkRect queryBounds;
     queryXform.mapRect(&queryBounds, preXformQuery);
-    const GrReducedClip reduced(stack, queryBounds, context.get());
+    const GrReducedClip reduced(stack, queryBounds, caps);
 
     SkClipStack::BoundsType stackBoundsType;
     SkRect stackBounds;
@@ -1407,13 +1410,14 @@
     pathStack.clipPath(clipPath, SkMatrix::I(), kIntersect_SkClipOp, true);
 
     auto context = GrContext::MakeMock(nullptr);
+    const GrCaps* caps = context->contextPriv().caps();
 
     for (const SkClipStack& stack : {rectStack, pathStack}) {
         for (SkRect queryBounds : {SkRect::MakeXYWH(53, 60, GrClip::kBoundsTolerance, 1000),
                                    SkRect::MakeXYWH(53, 60, GrClip::kBoundsTolerance/2, 1000),
                                    SkRect::MakeXYWH(53, 160, 1000, GrClip::kBoundsTolerance),
                                    SkRect::MakeXYWH(53, 160, 1000, GrClip::kBoundsTolerance/2)}) {
-            const GrReducedClip reduced(stack, queryBounds, context.get());
+            const GrReducedClip reduced(stack, queryBounds, caps);
             REPORTER_ASSERT(reporter, !reduced.hasScissor());
             REPORTER_ASSERT(reporter, reduced.maskElements().isEmpty());
             REPORTER_ASSERT(reporter,