aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@google.com>2017-06-06 21:47:32 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-06 22:12:48 +0000
commit8b06ed7c9f76760563ed3c46716e8e8f27ec2311 (patch)
tree13d827f87401f9c7f3dd83d434b5447effe3345b /src
parenta88da48436f4c013722b27064e02a0b33574d2f8 (diff)
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>
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrGpu.h3
-rw-r--r--src/gpu/GrStencilSettings.cpp14
-rw-r--r--src/gpu/GrStencilSettings.h3
-rw-r--r--src/gpu/gl/GrGLCaps.cpp2
-rw-r--r--src/gpu/gl/GrGLCaps.h6
-rw-r--r--src/gpu/gl/GrGLGpu.cpp159
-rw-r--r--src/gpu/gl/GrGLGpu.h18
-rw-r--r--src/gpu/vk/GrVkGpu.h2
8 files changed, 121 insertions, 86 deletions
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 8b8c7b3809..dd63839db5 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -479,6 +479,9 @@ public:
// 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 689557eaf4..7790c5506b 100644
--- a/src/gpu/GrStencilSettings.cpp
+++ b/src/gpu/GrStencilSettings.cpp
@@ -455,20 +455,6 @@ GrUserStencilSettings const* const* GrStencilSettings::GetClipPasses(SkRegion::O
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 1fed6b8e63..15a8cac12f 100644
--- a/src/gpu/GrStencilSettings.h
+++ b/src/gpu/GrStencilSettings.h
@@ -109,9 +109,6 @@ public:
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 44d25299ae..c672cb9a59 100644
--- a/src/gpu/gl/GrGLCaps.cpp
+++ b/src/gpu/gl/GrGLCaps.cpp
@@ -55,7 +55,6 @@ GrGLCaps::GrGLCaps(const GrContextOptions& contextOptions,
fClearToBoundaryValuesIsBroken = false;
fClearTextureSupport = false;
fDrawArraysBaseVertexIsBroken = false;
- fUseDrawToClearStencilClip = false;
fBlitFramebufferFlags = kNoSupport_BlitFramebufferFlag;
@@ -512,7 +511,6 @@ void GrGLCaps::init(const GrContextOptions& contextOptions,
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 efb324b064..b7273a08b1 100644
--- a/src/gpu/gl/GrGLCaps.h
+++ b/src/gpu/gl/GrGLCaps.h
@@ -368,11 +368,6 @@ public:
// 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 @@ private:
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 3160ecaed5..fc629d60d0 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -220,7 +220,7 @@ GrGLGpu::GrGLGpu(GrGLContext* ctx, GrContext* context)
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 @@ GrGLGpu::~GrGLGpu() {
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 @@ GrGLGpu::~GrGLGpu() {
}
}
- if (0 != fStencilClipClearProgram) {
- GL_CALL(DeleteProgram(fStencilClipClearProgram));
+ if (0 != fWireRectProgram.fProgram) {
+ GL_CALL(DeleteProgram(fWireRectProgram.fProgram));
}
delete fProgramCache;
@@ -339,8 +339,8 @@ void GrGLGpu::disconnect(DisconnectType type) {
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 @@ void GrGLGpu::disconnect(DisconnectType type) {
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 @@ void GrGLGpu::clearStencilClip(const GrFixedClip& clip,
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 @@ bool GrGLGpu::createMipmapProgram(int progIdx) {
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 @@ bool GrGLGpu::createStencilClipClearProgram() {
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 @@ bool GrGLGpu::createStencilClipClearProgram() {
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;
}
}
+ int w = rt->width();
+ int h = rt->height();
+
+ // 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, nullptr);
+ this->flushRenderTarget(glRT, &rect);
- GL_CALL(UseProgram(fStencilClipClearProgram));
- fHWProgramID = fStencilClipClearProgram;
+ 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 1785eae143..770c357c5f 100644
--- a/src/gpu/gl/GrGLGpu.h
+++ b/src/gpu/gl/GrGLGpu.h
@@ -162,6 +162,8 @@ public:
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 @@ private:
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 @@ private:
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 @@ private:
bool createCopyProgram(GrTexture* srcTexture);
bool createMipmapProgram(int progIdx);
- bool createStencilClipClearProgram();
+ bool createWireRectProgram();
// GL program-related state
ProgramCache* fProgramCache;
@@ -614,8 +620,12 @@ private:
} 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 f81daea336..cce6883f8d 100644
--- a/src/gpu/vk/GrVkGpu.h
+++ b/src/gpu/vk/GrVkGpu.h
@@ -98,6 +98,8 @@ public:
const GrGpuCommandBuffer::LoadAndStoreInfo& colorInfo,
const GrGpuCommandBuffer::LoadAndStoreInfo& stencilInfo) override;
+ void drawDebugWireRect(GrRenderTarget*, const SkIRect&, GrColor) override {}
+
void addMemoryBarrier(VkPipelineStageFlags srcStageMask,
VkPipelineStageFlags dstStageMask,
bool byRegion,