Revert "Workaround Adreno driver issue with stencil clears."

This reverts commit 4e8c581f2aa911bf49f97a246cc26134da292a8c.

Reason for revert: breaks Google3 roll

Original change's description:
> Workaround Adreno driver issue with stencil clears.
> 
> This also removes the "debug wire rect" which was not used and not implemented for Vulkan.
> 
> Also some declared but not implemented methods are removed from GrGLGpu.
> 
> Bug: skia:5587
> 
> Change-Id: I750051e90e6cfbfad6a6fe20792226182f698bcf
> Reviewed-on: https://skia-review.googlesource.com/18639
> Reviewed-by: Chris Dalton <csmartdalton@google.com>
> Commit-Queue: Brian Salomon <bsalomon@google.com>

TBR=bsalomon@google.com,csmartdalton@google.com
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:5587

Change-Id: I65aa16b3f8c70cdef56ff16e16304ba09604c475
Reviewed-on: https://skia-review.googlesource.com/18924
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 8b8c7b3..dd63839 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -479,6 +479,9 @@
     // clears target's entire stencil buffer to 0
     virtual void clearStencil(GrRenderTarget* target) = 0;
 
+    // draws an outline rectangle for debugging/visualization purposes.
+    virtual void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) = 0;
+
     // Determines whether a texture will need to be rescaled in order to be used with the
     // GrSamplerParams. This variation is called when the caller will create a new texture using the
     // resource provider from a non-texture src (cpu-backed image, ...).
diff --git a/src/gpu/GrStencilSettings.cpp b/src/gpu/GrStencilSettings.cpp
index 689557e..7790c55 100644
--- a/src/gpu/GrStencilSettings.cpp
+++ b/src/gpu/GrStencilSettings.cpp
@@ -455,20 +455,6 @@
     return gUserToClipTable[invertedFill][op];
 }
 
-static constexpr GrUserStencilSettings gZeroStencilClipBit(
-    GrUserStencilSettings::StaticInit<
-        0x0000,
-        GrUserStencilTest::kAlways,
-        0xffff,
-        GrUserStencilOp::kZeroClipBit,
-        GrUserStencilOp::kZeroClipBit,
-        0x0000>()
-);
-
-const GrUserStencilSettings* GrStencilSettings::SetClipBitSettings(bool setToInside) {
-    return setToInside ? &gReplaceClip : &gZeroStencilClipBit;
-}
-
 void GrStencilSettings::genKey(GrProcessorKeyBuilder* b) const {
     b->add32(fFlags);
     if (this->isDisabled()) {
diff --git a/src/gpu/GrStencilSettings.h b/src/gpu/GrStencilSettings.h
index 1fed6b8..15a8cac 100644
--- a/src/gpu/GrStencilSettings.h
+++ b/src/gpu/GrStencilSettings.h
@@ -109,9 +109,6 @@
                                                              bool invertedFill,
                                                              bool* drawDirectToClip);
 
-    /** Gets the user stencil settings to directly set the clip bit. */
-    static const GrUserStencilSettings* SetClipBitSettings(bool setToInside);
-
 private:
     // Internal flag for backends to optionally mark their tracked stencil state as invalid.
     enum { kInvalid_PrivateFlag = (kLast_StencilFlag << 1) };
diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp
index 44d2529..c672cb9 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -55,7 +55,6 @@
     fClearToBoundaryValuesIsBroken = false;
     fClearTextureSupport = false;
     fDrawArraysBaseVertexIsBroken = false;
-    fUseDrawToClearStencilClip = false;
 
     fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
 
@@ -512,7 +511,6 @@
 
     if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer()) {
         fUseDrawInsteadOfPartialRenderTargetWrite = true;
-        fUseDrawToClearStencilClip = true;
     }
 
     // Texture uploads sometimes seem to be ignored to textures bound to FBOS on Tegra3.
diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h
index efb324b..b7273a0 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -368,11 +368,6 @@
     // https://bugs.chromium.org/p/skia/issues/detail?id=6650
     bool drawArraysBaseVertexIsBroken() const { return fDrawArraysBaseVertexIsBroken; }
 
-    /// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit
-    /// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil
-    /// op instead of using glClear seems to resolve the issue.
-    bool useDrawToClearStencilClip() const { return fUseDrawToClearStencilClip; }
-
     bool initDescForDstCopy(const GrRenderTargetProxy* src, GrSurfaceDesc* desc,
                             bool* rectsMustMatch, bool* disallowSubrect) const override;
 
@@ -447,7 +442,6 @@
     bool fClearToBoundaryValuesIsBroken : 1;
     bool fClearTextureSupport : 1;
     bool fDrawArraysBaseVertexIsBroken : 1;
-    bool fUseDrawToClearStencilClip : 1;
 
     uint32_t fBlitFramebufferFlags;
 
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index 3160eca..fc629d6 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -220,7 +220,7 @@
     for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
         fMipmapPrograms[i].fProgram = 0;
     }
-    fStencilClipClearProgram = 0;
+    fWireRectProgram.fProgram = 0;
 
     SkASSERT(ctx);
     fCaps.reset(SkRef(ctx->caps()));
@@ -277,7 +277,7 @@
     fPathRendering.reset();
     fCopyProgramArrayBuffer.reset();
     fMipmapProgramArrayBuffer.reset();
-    fStencilClipClearArrayBuffer.reset();
+    fWireRectArrayBuffer.reset();
 
     if (0 != fHWProgramID) {
         // detach the current program so there is no confusion on OpenGL's part
@@ -307,8 +307,8 @@
         }
     }
 
-    if (0 != fStencilClipClearProgram) {
-        GL_CALL(DeleteProgram(fStencilClipClearProgram));
+    if (0 != fWireRectProgram.fProgram) {
+        GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
     }
 
     delete fProgramCache;
@@ -339,8 +339,8 @@
                 GL_CALL(DeleteProgram(fMipmapPrograms[i].fProgram));
             }
         }
-        if (fStencilClipClearProgram) {
-            GL_CALL(DeleteProgram(fStencilClipClearProgram));
+        if (fWireRectProgram.fProgram) {
+            GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
         }
     } else {
         if (fProgramCache) {
@@ -363,8 +363,8 @@
     for (size_t i = 0; i < SK_ARRAY_COUNT(fMipmapPrograms); ++i) {
         fMipmapPrograms[i].fProgram = 0;
     }
-    fStencilClipClearProgram = 0;
-    fStencilClipClearArrayBuffer.reset();
+    fWireRectProgram.fProgram = 0;
+    fWireRectArrayBuffer.reset();
     if (this->glCaps().shaderCaps()->pathRenderingSupport()) {
         this->glPathRendering()->disconnect(type);
     }
@@ -1943,11 +1943,6 @@
     SkASSERT(target);
     this->handleDirtyContext();
 
-    if (this->glCaps().useDrawToClearStencilClip()) {
-        this->clearStencilClipAsDraw(clip, insideStencilMask, target);
-        return;
-    }
-
     GrStencilAttachment* sb = target->renderTargetPriv().getStencilAttachment();
     // this should only be called internally when we know we have a
     // stencil buffer.
@@ -3616,43 +3611,64 @@
     return true;
 }
 
-bool GrGLGpu::createStencilClipClearProgram() {
-    if (!fStencilClipClearArrayBuffer) {
-        static const GrGLfloat vdata[] = {-1, -1, 1, -1, -1, 1, 1, 1};
-        fStencilClipClearArrayBuffer.reset(GrGLBuffer::Create(
-                this, sizeof(vdata), kVertex_GrBufferType, kStatic_GrAccessPattern, vdata));
-        if (!fStencilClipClearArrayBuffer) {
+bool GrGLGpu::createWireRectProgram() {
+    if (!fWireRectArrayBuffer) {
+        static const GrGLfloat vdata[] = {
+            0, 0,
+            0, 1,
+            1, 1,
+            1, 0
+        };
+        fWireRectArrayBuffer.reset(GrGLBuffer::Create(this, sizeof(vdata), kVertex_GrBufferType,
+                                                      kStatic_GrAccessPattern, vdata));
+        if (!fWireRectArrayBuffer) {
             return false;
         }
     }
 
-    SkASSERT(!fStencilClipClearProgram);
-    GL_CALL_RET(fStencilClipClearProgram, CreateProgram());
-    if (!fStencilClipClearProgram) {
+    SkASSERT(!fWireRectProgram.fProgram);
+    GL_CALL_RET(fWireRectProgram.fProgram, CreateProgram());
+    if (!fWireRectProgram.fProgram) {
         return false;
     }
 
+    GrShaderVar uColor("u_color", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
+    GrShaderVar uRect("u_rect", kVec4f_GrSLType, GrShaderVar::kUniform_TypeModifier);
     GrShaderVar aVertex("a_vertex", kVec2f_GrSLType, GrShaderVar::kIn_TypeModifier);
     const char* version = this->caps()->shaderCaps()->versionDeclString();
 
+    // The rect uniform specifies the rectangle in NDC space as a vec4 (left,top,right,bottom). The
+    // program is used with a vbo containing the unit square. Vertices are computed from the rect
+    // uniform using the 4 vbo vertices.
     SkString vshaderTxt(version);
     aVertex.appendDecl(this->caps()->shaderCaps(), &vshaderTxt);
     vshaderTxt.append(";");
+    uRect.appendDecl(this->caps()->shaderCaps(), &vshaderTxt);
+    vshaderTxt.append(";");
     vshaderTxt.append(
-            "// Stencil Clip Clear Program VS\n"
-            "void main() {"
-            "  gl_Position = vec4(a_vertex.x, a_vertex.y, 0, 1);"
-            "}");
+        "// Wire Rect Program VS\n"
+        "void main() {"
+        "  gl_Position.x = u_rect.x + a_vertex.x * (u_rect.z - u_rect.x);"
+        "  gl_Position.y = u_rect.y + a_vertex.y * (u_rect.w - u_rect.y);"
+        "  gl_Position.zw = vec2(0, 1);"
+        "}"
+    );
+
+    GrShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
 
     SkString fshaderTxt(version);
     GrGLSLAppendDefaultFloatPrecisionDeclaration(kMedium_GrSLPrecision,
                                                  *this->caps()->shaderCaps(),
                                                  &fshaderTxt);
+    uColor.appendDecl(this->caps()->shaderCaps(), &fshaderTxt);
+    fshaderTxt.append(";");
     fshaderTxt.appendf(
-            "// Stencil Clip Clear Program FS\n"
-            "void main() {"
-            "  sk_FragColor = vec4(0);"
-            "}");
+        "// Write Rect Program FS\n"
+        "void main() {"
+        "  sk_FragColor = %s;"
+        "}",
+        uColor.c_str()
+    );
 
     const char* str;
     GrGLint length;
@@ -3662,21 +3678,25 @@
     SkSL::Program::Settings settings;
     settings.fCaps = this->caps()->shaderCaps();
     SkSL::Program::Inputs inputs;
-    GrGLuint vshader =
-            GrGLCompileAndAttachShader(*fGLContext, fStencilClipClearProgram, GR_GL_VERTEX_SHADER,
-                                       &str, &length, 1, &fStats, settings, &inputs);
+    GrGLuint vshader = GrGLCompileAndAttachShader(*fGLContext, fWireRectProgram.fProgram,
+                                                  GR_GL_VERTEX_SHADER, &str, &length, 1,
+                                                  &fStats, settings, &inputs);
     SkASSERT(inputs.isEmpty());
 
     str = fshaderTxt.c_str();
     length = SkToInt(fshaderTxt.size());
-    GrGLuint fshader =
-            GrGLCompileAndAttachShader(*fGLContext, fStencilClipClearProgram, GR_GL_FRAGMENT_SHADER,
-                                       &str, &length, 1, &fStats, settings, &inputs);
+    GrGLuint fshader = GrGLCompileAndAttachShader(*fGLContext, fWireRectProgram.fProgram,
+                                                  GR_GL_FRAGMENT_SHADER, &str, &length, 1,
+                                                  &fStats, settings, &inputs);
     SkASSERT(inputs.isEmpty());
 
-    GL_CALL(LinkProgram(fStencilClipClearProgram));
+    GL_CALL(LinkProgram(fWireRectProgram.fProgram));
 
-    GL_CALL(BindAttribLocation(fStencilClipClearProgram, 0, "a_vertex"));
+    GL_CALL_RET(fWireRectProgram.fColorUniform,
+                GetUniformLocation(fWireRectProgram.fProgram, "u_color"));
+    GL_CALL_RET(fWireRectProgram.fRectUniform,
+                GetUniformLocation(fWireRectProgram.fProgram, "u_rect"));
+    GL_CALL(BindAttribLocation(fWireRectProgram.fProgram, 0, "a_vertex"));
 
     GL_CALL(DeleteShader(vshader));
     GL_CALL(DeleteShader(fshader));
@@ -3684,46 +3704,71 @@
     return true;
 }
 
-void GrGLGpu::clearStencilClipAsDraw(const GrFixedClip& clip, bool insideStencilMask,
-                                     GrRenderTarget* rt) {
+void GrGLGpu::drawDebugWireRect(GrRenderTarget* rt, const SkIRect& rect, GrColor color) {
     // TODO: This should swizzle the output to match dst's config, though it is a debugging
     // visualization.
 
     this->handleDirtyContext();
-    if (!fStencilClipClearProgram) {
-        if (!this->createStencilClipClearProgram()) {
-            SkDebugf("Failed to create stencil clip clear program.\n");
+    if (!fWireRectProgram.fProgram) {
+        if (!this->createWireRectProgram()) {
+            SkDebugf("Failed to create wire rect program.\n");
             return;
         }
     }
 
-    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(rt->asRenderTarget());
-    this->flushRenderTarget(glRT, nullptr);
+    int w = rt->width();
+    int h = rt->height();
 
-    GL_CALL(UseProgram(fStencilClipClearProgram));
-    fHWProgramID = fStencilClipClearProgram;
+    // Compute the edges of the rectangle (top,left,right,bottom) in NDC space. Must consider
+    // whether the render target is flipped or not.
+    GrGLfloat edges[4];
+    edges[0] = SkIntToScalar(rect.fLeft) + 0.5f;
+    edges[2] = SkIntToScalar(rect.fRight) - 0.5f;
+    if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
+        edges[1] = h - (SkIntToScalar(rect.fTop) + 0.5f);
+        edges[3] = h - (SkIntToScalar(rect.fBottom) - 0.5f);
+    } else {
+        edges[1] = SkIntToScalar(rect.fTop) + 0.5f;
+        edges[3] = SkIntToScalar(rect.fBottom) - 0.5f;
+    }
+    edges[0] = 2 * edges[0] / w - 1.0f;
+    edges[1] = 2 * edges[1] / h - 1.0f;
+    edges[2] = 2 * edges[2] / w - 1.0f;
+    edges[3] = 2 * edges[3] / h - 1.0f;
+
+    GrGLfloat channels[4];
+    static const GrGLfloat scale255 = 1.f / 255.f;
+    channels[0] = GrColorUnpackR(color) * scale255;
+    channels[1] = GrColorUnpackG(color) * scale255;
+    channels[2] = GrColorUnpackB(color) * scale255;
+    channels[3] = GrColorUnpackA(color) * scale255;
+
+    GrGLRenderTarget* glRT = static_cast<GrGLRenderTarget*>(rt->asRenderTarget());
+    this->flushRenderTarget(glRT, &rect);
+
+    GL_CALL(UseProgram(fWireRectProgram.fProgram));
+    fHWProgramID = fWireRectProgram.fProgram;
 
     fHWVertexArrayState.setVertexArrayID(this, 0);
 
     GrGLAttribArrayState* attribs = fHWVertexArrayState.bindInternalVertexArray(this);
     attribs->enableVertexArrays(this, 1);
-    attribs->set(this, 0, fStencilClipClearArrayBuffer.get(), kVec2f_GrVertexAttribType,
+    attribs->set(this, 0, fWireRectArrayBuffer.get(), kVec2f_GrVertexAttribType,
                  2 * sizeof(GrGLfloat), 0);
 
+    GL_CALL(Uniform4fv(fWireRectProgram.fRectUniform, 1, edges));
+    GL_CALL(Uniform4fv(fWireRectProgram.fColorUniform, 1, channels));
+
     GrXferProcessor::BlendInfo blendInfo;
     blendInfo.reset();
     this->flushBlend(blendInfo, GrSwizzle::RGBA());
-    this->flushColorWrite(false);
+    this->flushColorWrite(true);
     this->flushHWAAState(glRT, false, false);
-    this->flushScissor(clip.scissorState(), glRT->getViewport(), glRT->origin());
-    this->flushWindowRectangles(clip.windowRectsState(), glRT);
-    GrStencilAttachment* sb = rt->renderTargetPriv().getStencilAttachment();
-    // This should only be called internally when we know we have a stencil buffer.
-    SkASSERT(sb);
-    GrStencilSettings settings = GrStencilSettings(
-            *GrStencilSettings::SetClipBitSettings(insideStencilMask), false, sb->bits());
-    this->flushStencil(settings);
-    GL_CALL(DrawArrays(GR_GL_TRIANGLE_STRIP, 0, 4));
+    this->disableScissor();
+    this->disableWindowRectangles();
+    this->disableStencil();
+
+    GL_CALL(DrawArrays(GR_GL_LINE_LOOP, 0, 4));
 }
 
 
diff --git a/src/gpu/gl/GrGLGpu.h b/src/gpu/gl/GrGLGpu.h
index 1785eae..770c357 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -162,6 +162,8 @@
 
     void resetShaderCacheForTesting() const override;
 
+    void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override;
+
     GrFence SK_WARN_UNUSED_RESULT insertFence() override;
     bool waitFence(GrFence, uint64_t timeout) override;
     void deleteFence(GrFence) const override;
@@ -294,7 +296,6 @@
                                       const SkIRect& srcRect,
                                       const SkIPoint& dstPoint);
     bool generateMipmap(GrGLTexture* texture, bool gammaCorrect);
-    void clearStencilClipAsDraw(const GrFixedClip&, bool insideStencilMask, GrRenderTarget*);
 
     static bool BlendCoeffReferencesConstant(GrBlendCoeff coeff);
 
@@ -348,6 +349,11 @@
     void flushWindowRectangles(const GrWindowRectsState&, const GrGLRenderTarget*);
     void disableWindowRectangles();
 
+    void initFSAASupport();
+
+    // determines valid stencil formats
+    void initStencilFormats();
+
     // sets a texture unit to use for texture operations other than binding a texture to a program.
     // ensures that such operations don't negatively interact with tracking bound textures.
     void setScratchTextureUnit();
@@ -401,7 +407,7 @@
 
     bool createCopyProgram(GrTexture* srcTexture);
     bool createMipmapProgram(int progIdx);
-    bool createStencilClipClearProgram();
+    bool createWireRectProgram();
 
     // GL program-related state
     ProgramCache*               fProgramCache;
@@ -614,8 +620,12 @@
     }                                       fMipmapPrograms[4];
     sk_sp<GrGLBuffer>                       fMipmapProgramArrayBuffer;
 
-    GrGLuint                                fStencilClipClearProgram;
-    sk_sp<GrGLBuffer>                       fStencilClipClearArrayBuffer;
+    struct {
+        GrGLuint    fProgram;
+        GrGLint     fColorUniform;
+        GrGLint     fRectUniform;
+    }                                       fWireRectProgram;
+    sk_sp<GrGLBuffer>                       fWireRectArrayBuffer;
 
     static int TextureToCopyProgramIdx(GrTexture* texture) {
         switch (texture->texturePriv().samplerType()) {
diff --git a/src/gpu/vk/GrVkGpu.h b/src/gpu/vk/GrVkGpu.h
index f81daea..cce6883 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -98,6 +98,8 @@
             const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo,
             const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) override;
 
+    void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override {}
+
     void addMemoryBarrier(VkPipelineStageFlags srcStageMask,
                           VkPipelineStageFlags dstStageMask,
                           bool byRegion,
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index 32f2d76..bd85cff 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -339,6 +339,8 @@
         return nullptr;
     }
 
+    void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override {}
+
     GrFence SK_WARN_UNUSED_RESULT insertFence() override { return 0; }
     bool waitFence(GrFence, uint64_t) override { return true; }
     void deleteFence(GrFence) const override {}