diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 7ccdce5309..ffdd4dcdcd 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -1080,6 +1080,7 @@ void GrDrawTargetCaps::reset() { fReuseScratchTextures = true; fGpuTracingSupport = false; fCompressedTexSubImageSupport = false; + fOversizedStencilSupport = false; fUseDrawInsteadOfClear = false; @@ -1110,6 +1111,7 @@ GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) { fReuseScratchTextures = other.fReuseScratchTextures; fGpuTracingSupport = other.fGpuTracingSupport; fCompressedTexSubImageSupport = other.fCompressedTexSubImageSupport; + fOversizedStencilSupport = other.fOversizedStencilSupport; fUseDrawInsteadOfClear = other.fUseDrawInsteadOfClear; @@ -1192,7 +1194,7 @@ SkString GrDrawTargetCaps::dump() const { r.appendf("Reuse Scratch Textures : %s\n", gNY[fReuseScratchTextures]); r.appendf("Gpu Tracing Support : %s\n", gNY[fGpuTracingSupport]); r.appendf("Compressed Update Support : %s\n", gNY[fCompressedTexSubImageSupport]); - + r.appendf("Oversized Stencil Support : %s\n", gNY[fOversizedStencilSupport]); r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]); r.appendf("Max Texture Size : %d\n", fMaxTextureSize); diff --git a/src/gpu/GrDrawTargetCaps.h b/src/gpu/GrDrawTargetCaps.h index 1bd18b081e..61ec3b2196 100644 --- a/src/gpu/GrDrawTargetCaps.h +++ b/src/gpu/GrDrawTargetCaps.h @@ -82,6 +82,7 @@ public: bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; } bool gpuTracingSupport() const { return fGpuTracingSupport; } bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; } + bool oversizedStencilSupport() const { return fOversizedStencilSupport; } bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; } @@ -146,23 +147,23 @@ public: uint32_t getUniqueID() const { return fUniqueID; } protected: - bool fNPOTTextureTileSupport : 1; - bool fMipMapSupport : 1; - bool fTwoSidedStencilSupport : 1; - bool fStencilWrapOpsSupport : 1; - bool fHWAALineSupport : 1; - bool fShaderDerivativeSupport : 1; - bool fGeometryShaderSupport : 1; - bool fDualSourceBlendingSupport : 1; - bool fPathRenderingSupport : 1; - bool fDstReadInShaderSupport : 1; - bool fDiscardRenderTargetSupport: 1; - bool fReuseScratchTextures : 1; - bool fGpuTracingSupport : 1; - bool fCompressedTexSubImageSupport : 1; - + bool fNPOTTextureTileSupport : 1; + bool fMipMapSupport : 1; + bool fTwoSidedStencilSupport : 1; + bool fStencilWrapOpsSupport : 1; + bool fHWAALineSupport : 1; + bool fShaderDerivativeSupport : 1; + bool fGeometryShaderSupport : 1; + bool fDualSourceBlendingSupport : 1; + bool fPathRenderingSupport : 1; + bool fDstReadInShaderSupport : 1; + bool fDiscardRenderTargetSupport : 1; + bool fReuseScratchTextures : 1; + bool fGpuTracingSupport : 1; + bool fCompressedTexSubImageSupport : 1; + bool fOversizedStencilSupport : 1; // Driver workaround - bool fUseDrawInsteadOfClear : 1; + bool fUseDrawInsteadOfClear : 1; uint32_t fMapBufferFlags; diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 27fed3c582..d22399f81c 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -87,8 +87,15 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& desc, bool budgeted, bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) { SkASSERT(NULL == rt->getStencilBuffer()); GrUniqueKey sbKey; - GrStencilBuffer::ComputeSharedStencilBufferKey(rt->width(), rt->height(), rt->numSamples(), - &sbKey); + + int width = rt->width(); + int height = rt->height(); + if (this->caps()->oversizedStencilSupport()) { + width = SkNextPow2(width); + height = SkNextPow2(height); + } + + GrStencilBuffer::ComputeSharedStencilBufferKey(width, height, rt->numSamples(), &sbKey); SkAutoTUnref sb(static_cast( this->getContext()->getResourceCache()->findAndRefUniqueResource(sbKey))); if (sb) { @@ -99,7 +106,7 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) { } return attached; } - if (this->createStencilBufferForRenderTarget(rt, rt->width(), rt->height())) { + if (this->createStencilBufferForRenderTarget(rt, width, height)) { // Right now we're clearing the stencil buffer here after it is // attached to an RT for the first time. When we start matching // stencil buffers with smaller color targets this will no longer diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index 6d8b4bab25..1f50f8d1e1 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -407,6 +407,19 @@ bool GrGLCaps::init(const GrGLContextInfo& ctxInfo, const GrGLInterface* gli) { fUseDrawInsteadOfClear = true; } + if (kGL_GrGLStandard == standard) { + // ARB allows mixed size FBO attachments, EXT does not. + if (ctxInfo.version() >= GR_GL_VER(3, 0) || + ctxInfo.hasExtension("GL_ARB_framebuffer_object")) { + fOversizedStencilSupport = true; + } else { + SkASSERT(ctxInfo.hasExtension("GL_EXT_framebuffer_object")); + } + } else { + // ES 3.0 supports mixed size FBO attachments, 2.0 does not. + fOversizedStencilSupport = ctxInfo.version() >= GR_GL_VER(3, 0); + } + this->initConfigTexturableTable(ctxInfo, gli); this->initConfigRenderableTable(ctxInfo);