| Index: src/gpu/gl/GrGLGpu.cpp
 | 
| diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
 | 
| index d7a060031e55deb265d045fd3cc70f023b28f37d..84f2bdda8e915863d4d648d518a5deaa842cea0d 100644
 | 
| --- a/src/gpu/gl/GrGLGpu.cpp
 | 
| +++ b/src/gpu/gl/GrGLGpu.cpp
 | 
| @@ -12,7 +12,6 @@
 | 
|  #include "GrGLTextureRenderTarget.h"
 | 
|  #include "GrGpuResourcePriv.h"
 | 
|  #include "GrPipeline.h"
 | 
| -#include "GrPLSGeometryProcessor.h"
 | 
|  #include "GrRenderTargetPriv.h"
 | 
|  #include "GrSurfacePriv.h"
 | 
|  #include "GrTexturePriv.h"
 | 
| @@ -21,7 +20,6 @@
 | 
|  #include "builders/GrGLShaderStringBuilder.h"
 | 
|  #include "glsl/GrGLSL.h"
 | 
|  #include "glsl/GrGLSLCaps.h"
 | 
| -#include "glsl/GrGLSLPLSPathRendering.h"
 | 
|  #include "SkStrokeRec.h"
 | 
|  #include "SkTemplates.h"
 | 
|  
 | 
| @@ -40,6 +38,7 @@
 | 
|      #define CHECK_ALLOC_ERROR(iface)          GR_GL_NO_ERROR
 | 
|  #endif
 | 
|  
 | 
| +
 | 
|  ///////////////////////////////////////////////////////////////////////////////
 | 
|  
 | 
|  
 | 
| @@ -225,14 +224,6 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
 | 
|      this->createCopyPrograms();
 | 
|      fWireRectProgram.fProgram = 0;
 | 
|      fWireRectArrayBuffer = 0;
 | 
| -    if (this->glCaps().shaderCaps()->plsPathRenderingSupport()) {
 | 
| -        this->createPLSSetupProgram();
 | 
| -    }
 | 
| -    else {
 | 
| -        memset(&fPLSSetupProgram, 0, sizeof(fPLSSetupProgram));
 | 
| -    }
 | 
| -    fHWPLSEnabled = false;
 | 
| -    fPLSHasBeenUsed = false;
 | 
|  }
 | 
|  
 | 
|  GrGLGpu::~GrGLGpu() {
 | 
| @@ -274,106 +265,9 @@ GrGLGpu::~GrGLGpu() {
 | 
|          GL_CALL(DeleteBuffers(1, &fWireRectArrayBuffer));
 | 
|      }
 | 
|  
 | 
| -    if (0 != fPLSSetupProgram.fArrayBuffer) {
 | 
| -        GL_CALL(DeleteBuffers(1, &fPLSSetupProgram.fArrayBuffer));
 | 
| -    }
 | 
| -
 | 
| -    if (0 != fPLSSetupProgram.fProgram) {
 | 
| -        GL_CALL(DeleteProgram(fPLSSetupProgram.fProgram));
 | 
| -    }
 | 
| -
 | 
|      delete fProgramCache;
 | 
|  }
 | 
|  
 | 
| -void GrGLGpu::createPLSSetupProgram() {
 | 
| -    const char* version = this->glCaps().glslCaps()->versionDeclString();
 | 
| -
 | 
| -    GrGLSLShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
 | 
| -    GrGLSLShaderVar uTexCoordXform("u_texCoordXform", kVec4f_GrSLType,
 | 
| -                                   GrShaderVar::kUniform_TypeModifier);
 | 
| -    GrGLSLShaderVar uPosXform("u_posXform", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
 | 
| -    GrGLSLShaderVar uTexture("u_texture", kSampler2D_GrSLType, GrShaderVar::kUniform_TypeModifier);
 | 
| -    GrGLSLShaderVar vTexCoord("v_texCoord", kVec2f_GrSLType, GrShaderVar::kVaryingOut_TypeModifier);
 | 
| -    
 | 
| -    SkString vshaderTxt(version);
 | 
| -    aVertex.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
 | 
| -    vshaderTxt.append(";");
 | 
| -    uTexCoordXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
 | 
| -    vshaderTxt.append(";");
 | 
| -    uPosXform.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
 | 
| -    vshaderTxt.append(";");
 | 
| -    vTexCoord.appendDecl(this->glCaps().glslCaps(), &vshaderTxt);
 | 
| -    vshaderTxt.append(";");
 | 
| -    
 | 
| -    vshaderTxt.append(
 | 
| -        "// PLS Setup Program VS\n"
 | 
| -        "void main() {"
 | 
| -        "  gl_Position.xy = a_vertex * u_posXform.xy + u_posXform.zw;"
 | 
| -        "  gl_Position.zw = vec2(0, 1);"
 | 
| -        "}"
 | 
| -    );
 | 
| -
 | 
| -    SkString fshaderTxt(version);
 | 
| -    fshaderTxt.append("#extension ");
 | 
| -    fshaderTxt.append(this->glCaps().glslCaps()->fbFetchExtensionString());
 | 
| -    fshaderTxt.append(" : require\n");
 | 
| -    fshaderTxt.append("#extension GL_EXT_shader_pixel_local_storage : require\n");
 | 
| -    GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision,
 | 
| -                                                 *this->glCaps().glslCaps(),
 | 
| -                                                 &fshaderTxt);
 | 
| -    vTexCoord.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
 | 
| -    vTexCoord.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
 | 
| -    fshaderTxt.append(";");
 | 
| -    uTexture.appendDecl(this->glCaps().glslCaps(), &fshaderTxt);
 | 
| -    fshaderTxt.append(";");
 | 
| -
 | 
| -    fshaderTxt.appendf(
 | 
| -        "// PLS Setup Program FS\n"
 | 
| -        GR_GL_PLS_PATH_DATA_DECL
 | 
| -        "void main() {\n"
 | 
| -        "    " GR_GL_PLS_DSTCOLOR_NAME " = gl_LastFragColorARM;\n"
 | 
| -        "    pls.windings = ivec4(0, 0, 0, 0);\n"
 | 
| -        "}"
 | 
| -    );
 | 
| -    GL_CALL_RET(fPLSSetupProgram.fProgram, CreateProgram());
 | 
| -    const char* str;
 | 
| -    GrGLint length;
 | 
| -
 | 
| -    str = vshaderTxt.c_str();
 | 
| -    length = SkToInt(vshaderTxt.size());
 | 
| -    GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fPLSSetupProgram.fProgram,
 | 
| -                                                  GR_GL_VERTEX_SHADER, &str, &length, 1, &fStats);
 | 
| -
 | 
| -    str = fshaderTxt.c_str();
 | 
| -    length = SkToInt(fshaderTxt.size());
 | 
| -    GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fPLSSetupProgram.fProgram,
 | 
| -                                                  GR_GL_FRAGMENT_SHADER, &str, &length, 1, &fStats);
 | 
| -
 | 
| -    GL_CALL(LinkProgram(fPLSSetupProgram.fProgram));
 | 
| -
 | 
| -    GL_CALL_RET(fPLSSetupProgram.fPosXformUniform, GetUniformLocation(fPLSSetupProgram.fProgram,
 | 
| -                                                                  "u_posXform"));
 | 
| -
 | 
| -    GL_CALL(BindAttribLocation(fPLSSetupProgram.fProgram, 0, "a_vertex"));
 | 
| -
 | 
| -    GL_CALL(DeleteShader(vshader));
 | 
| -    GL_CALL(DeleteShader(fshader));
 | 
| -
 | 
| -    GL_CALL(GenBuffers(1, &fPLSSetupProgram.fArrayBuffer));
 | 
| -    fHWGeometryState.setVertexBufferID(this, fPLSSetupProgram.fArrayBuffer);
 | 
| -    static const GrGLfloat vdata[] = {
 | 
| -        0, 0,
 | 
| -        0, 1,
 | 
| -        1, 0,
 | 
| -        1, 1
 | 
| -    };
 | 
| -    GL_ALLOC_CALL(this->glInterface(),
 | 
| -                  BufferData(GR_GL_ARRAY_BUFFER,
 | 
| -                             (GrGLsizeiptr) sizeof(vdata),
 | 
| -                             vdata,  // data ptr
 | 
| -                             GR_GL_STATIC_DRAW));
 | 
| -}
 | 
| -
 | 
|  void GrGLGpu::contextAbandoned() {
 | 
|      INHERITED::contextAbandoned();
 | 
|      fProgramCache->abandon();
 | 
| @@ -2307,28 +2201,8 @@ bool GrGLGpu::onReadPixels(GrSurface* surface,
 | 
|      return true;
 | 
|  }
 | 
|  
 | 
| -void GrGLGpu::performFlushWorkaround() {
 | 
| -    if (fPLSHasBeenUsed) {
 | 
| -        /* There is an ARM driver bug where if we use PLS, and then draw a frame which does not 
 | 
| -         * use PLS, it leaves garbage all over the place. As a workaround, we use PLS in a 
 | 
| -         * trivial way every frame. And since we use it every frame, there's never a point at which
 | 
| -         * it becomes safe to stop using this workaround once we start.
 | 
| -         */
 | 
| -        this->disableScissor();
 | 
| -        // using PLS in the presence of MSAA results in GL_INVALID_OPERATION
 | 
| -        this->flushHWAAState(nullptr, false);
 | 
| -        SkASSERT(!fHWPLSEnabled);
 | 
| -        SkASSERT(fMSAAEnabled != kYes_TriState);
 | 
| -        GL_CALL(Enable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
 | 
| -        this->stampRectUsingProgram(fPLSSetupProgram.fProgram, 
 | 
| -                                    SkRect::MakeXYWH(-100.0f, -100.0f, 0.01f, 0.01f), 
 | 
| -                                    fPLSSetupProgram.fPosXformUniform, 
 | 
| -                                    fPLSSetupProgram.fArrayBuffer);
 | 
| -        GL_CALL(Disable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
 | 
| -    }
 | 
| -}
 | 
| -
 | 
|  void GrGLGpu::flushRenderTarget(GrGLRenderTarget* target, const SkIRect* bound) {
 | 
| +
 | 
|      SkASSERT(target);
 | 
|  
 | 
|      uint32_t rtID = target->getUniqueID();
 | 
| @@ -2411,19 +2285,6 @@ void GrGLGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertice
 | 
|          return;
 | 
|      }
 | 
|  
 | 
| -    GrPixelLocalStorageState plsState = args.fPrimitiveProcessor->getPixelLocalStorageState();
 | 
| -    if (!fHWPLSEnabled && plsState != 
 | 
| -        GrPixelLocalStorageState::kDisabled_GrPixelLocalStorageState) {
 | 
| -        GL_CALL(Enable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
 | 
| -        this->setupPixelLocalStorage(args);
 | 
| -        fHWPLSEnabled = true;
 | 
| -    }
 | 
| -    if (plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState) {
 | 
| -        GrStencilSettings stencil;
 | 
| -        stencil.setDisabled();
 | 
| -        this->flushStencil(stencil);
 | 
| -    }
 | 
| -
 | 
|      size_t indexOffsetInBytes = 0;
 | 
|      this->setupGeometry(*args.fPrimitiveProcessor, vertices, &indexOffsetInBytes);
 | 
|  
 | 
| @@ -2445,16 +2306,6 @@ void GrGLGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertice
 | 
|          GL_CALL(DrawArrays(gPrimitiveType2GLMode[vertices.primitiveType()], 0,
 | 
|                             vertices.vertexCount()));
 | 
|      }
 | 
| -
 | 
| -    if (fHWPLSEnabled && plsState == GrPixelLocalStorageState::kFinish_GrPixelLocalStorageState) {
 | 
| -        // PLS draws always involve multiple draws, finishing up with a non-PLS
 | 
| -        // draw that writes to the color buffer. That draw ends up here; we wait
 | 
| -        // until after it is complete to actually disable PLS.
 | 
| -        GL_CALL(Disable(GR_GL_SHADER_PIXEL_LOCAL_STORAGE));
 | 
| -        fHWPLSEnabled = false;
 | 
| -        this->disableScissor();
 | 
| -    }
 | 
| -
 | 
|  #if SWAP_PER_DRAW
 | 
|      glFlush();
 | 
|      #if defined(SK_BUILD_FOR_MAC)
 | 
| @@ -2469,57 +2320,6 @@ void GrGLGpu::onDraw(const DrawArgs& args, const GrNonInstancedVertices& vertice
 | 
|  #endif
 | 
|  }
 | 
|  
 | 
| -void GrGLGpu::stampRectUsingProgram(GrGLuint program, const SkRect& bounds, GrGLint posXformUniform, 
 | 
| -                                    GrGLuint arrayBuffer) {
 | 
| -    GL_CALL(UseProgram(program));
 | 
| -    this->fHWGeometryState.setVertexArrayID(this, 0);
 | 
| -
 | 
| -    GrGLAttribArrayState* attribs =
 | 
| -            this->fHWGeometryState.bindArrayAndBufferToDraw(this, arrayBuffer);
 | 
| -    attribs->set(this, 0, arrayBuffer, 2, GR_GL_FLOAT, false, 2 * sizeof(GrGLfloat), 0);
 | 
| -    attribs->disableUnusedArrays(this, 0x1);
 | 
| -
 | 
| -    GL_CALL(Uniform4f(posXformUniform, bounds.width(), bounds.height(), bounds.left(), 
 | 
| -                      bounds.top()));
 | 
| -
 | 
| -    GrXferProcessor::BlendInfo blendInfo;
 | 
| -    blendInfo.reset();
 | 
| -    this->flushBlend(blendInfo, GrSwizzle());
 | 
| -    this->flushColorWrite(true);
 | 
| -    this->flushDrawFace(GrPipelineBuilder::kBoth_DrawFace);
 | 
| -    if (!fHWStencilSettings.isDisabled()) {
 | 
| -        GL_CALL(Disable(GR_GL_STENCIL_TEST));
 | 
| -    }
 | 
| -    GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
 | 
| -    GL_CALL(UseProgram(fHWProgramID));
 | 
| -    if (!fHWStencilSettings.isDisabled()) {
 | 
| -        GL_CALL(Enable(GR_GL_STENCIL_TEST));
 | 
| -    }
 | 
| -}
 | 
| -
 | 
| -void GrGLGpu::setupPixelLocalStorage(const DrawArgs& args) {
 | 
| -    fPLSHasBeenUsed = true;
 | 
| -    const SkRect& bounds = 
 | 
| -            static_cast<const GrPLSGeometryProcessor*>(args.fPrimitiveProcessor)->getBounds();
 | 
| -    // setup pixel local storage -- this means capturing and storing the current framebuffer color
 | 
| -    // and initializing the winding counts to zero
 | 
| -    GrRenderTarget* rt = args.fPipeline->getRenderTarget();
 | 
| -    SkScalar width = SkIntToScalar(rt->width());
 | 
| -    SkScalar height = SkIntToScalar(rt->height());
 | 
| -    // dst rect edges in NDC (-1 to 1)
 | 
| -    // having some issues with rounding, just expand the bounds by 1 and trust the scissor to keep
 | 
| -    // it contained properly
 | 
| -    GrGLfloat dx0 = 2.0f * (bounds.left() - 1) / width - 1.0f;
 | 
| -    GrGLfloat dx1 = 2.0f * (bounds.right() + 1) / width - 1.0f;
 | 
| -    GrGLfloat dy0 = -2.0f * (bounds.top() - 1) / height + 1.0f;
 | 
| -    GrGLfloat dy1 = -2.0f * (bounds.bottom() + 1) / height + 1.0f;
 | 
| -    SkRect deviceBounds = SkRect::MakeXYWH(dx0, dy0, dx1 - dx0, dy1 - dy0);
 | 
| -    
 | 
| -    GL_CALL(Enable(GR_GL_FETCH_PER_SAMPLE_ARM));
 | 
| -    this->stampRectUsingProgram(fPLSSetupProgram.fProgram, deviceBounds, 
 | 
| -                                fPLSSetupProgram.fPosXformUniform, fPLSSetupProgram.fArrayBuffer);
 | 
| -}
 | 
| -
 | 
|  void GrGLGpu::onResolveRenderTarget(GrRenderTarget* target) {
 | 
|      GrGLRenderTarget* rt = static_cast<GrGLRenderTarget*>(target);
 | 
|      if (rt->needsResolve()) {
 | 
| 
 |