diff options
-rw-r--r-- | include/gpu/GrCaps.h | 9 | ||||
-rw-r--r-- | src/gpu/GrCaps.cpp | 5 | ||||
-rw-r--r-- | src/gpu/effects/GrCustomXfermode.cpp | 11 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.cpp | 61 | ||||
-rw-r--r-- | src/gpu/gl/GrGLCaps.h | 1 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUtil.cpp | 5 | ||||
-rw-r--r-- | src/gpu/gl/GrGLUtil.h | 1 |
7 files changed, 72 insertions, 21 deletions
diff --git a/include/gpu/GrCaps.h b/include/gpu/GrCaps.h index 727e9fcc46..54969c5933 100644 --- a/include/gpu/GrCaps.h +++ b/include/gpu/GrCaps.h @@ -10,6 +10,7 @@ #include "GrTypes.h" #include "GrTypesPriv.h" +#include "GrBlend.h" #include "GrShaderVar.h" #include "SkRefCnt.h" #include "SkString.h" @@ -157,6 +158,11 @@ public: return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; } + bool canUseAdvancedBlendEquation(GrBlendEquation equation) const { + SkASSERT(GrBlendEquationIsAdvanced(equation)); + return SkToBool(fAdvBlendEqBlacklist & (1 << equation)); + } + /** * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and * textures allows partial mappings or full mappings. @@ -228,6 +234,9 @@ protected: bool fUseDrawInsteadOfClear : 1; BlendEquationSupport fBlendEquationSupport; + uint32_t fAdvBlendEqBlacklist; + GR_STATIC_ASSERT(kLast_GrBlendEquation < 32); + uint32_t fMapBufferFlags; int fGeometryBufferMapThreshold; diff --git a/src/gpu/GrCaps.cpp b/src/gpu/GrCaps.cpp index aaa585e3bb..ba4e10430d 100644 --- a/src/gpu/GrCaps.cpp +++ b/src/gpu/GrCaps.cpp @@ -94,6 +94,8 @@ GrCaps::GrCaps(const GrContextOptions& options) { fUseDrawInsteadOfClear = false; fBlendEquationSupport = kBasic_BlendEquationSupport; + fAdvBlendEqBlacklist = 0; + fMapBufferFlags = kNone_MapFlags; fMaxRenderTargetSize = 0; @@ -148,6 +150,9 @@ SkString GrCaps::dump() const { r.appendf("Oversized Stencil Support : %s\n", gNY[fOversizedStencilSupport]); r.appendf("Texture Barrier Support : %s\n", gNY[fTextureBarrierSupport]); r.appendf("Draw Instead of Clear [workaround] : %s\n", gNY[fUseDrawInsteadOfClear]); + if (this->advancedBlendEquationSupport()) { + r.appendf("Advanced Blend Equation Blacklist : 0x%x\n", fAdvBlendEqBlacklist); + } r.appendf("Max Texture Size : %d\n", fMaxTextureSize); r.appendf("Min Texture Size : %d\n", fMinTextureSize); diff --git a/src/gpu/effects/GrCustomXfermode.cpp b/src/gpu/effects/GrCustomXfermode.cpp index b43d2d4ce6..794e55efdc 100644 --- a/src/gpu/effects/GrCustomXfermode.cpp +++ b/src/gpu/effects/GrCustomXfermode.cpp @@ -51,13 +51,18 @@ static GrBlendEquation hw_blend_equation(SkXfermode::Mode mode) { GR_STATIC_ASSERT(kGrBlendEquationCnt == SkXfermode::kLastMode + 1 + kOffset); } -static bool can_use_hw_blend_equation(const GrProcOptInfo& coveragePOI, const GrCaps& caps) { +static bool can_use_hw_blend_equation(GrBlendEquation equation, + const GrProcOptInfo& coveragePOI, + const GrCaps& caps) { if (!caps.advancedBlendEquationSupport()) { return false; } if (coveragePOI.isFourChannelOutput()) { return false; // LCD coverage must be applied after the blend equation. } + if (caps.canUseAdvancedBlendEquation(equation)) { + return false; + } return true; } @@ -788,7 +793,7 @@ GrCustomXPFactory::onCreateXferProcessor(const GrCaps& caps, const GrProcOptInfo& coveragePOI, bool hasMixedSamples, const DstTexture* dstTexture) const { - if (can_use_hw_blend_equation(coveragePOI, caps)) { + if (can_use_hw_blend_equation(fHWBlendEquation, coveragePOI, caps)) { SkASSERT(!dstTexture || !dstTexture->texture()); return SkNEW_ARGS(CustomXP, (fMode, fHWBlendEquation)); } @@ -799,7 +804,7 @@ bool GrCustomXPFactory::willReadDstColor(const GrCaps& caps, const GrProcOptInfo& colorPOI, const GrProcOptInfo& coveragePOI, bool hasMixedSamples) const { - return !can_use_hw_blend_equation(coveragePOI, caps); + return !can_use_hw_blend_equation(fHWBlendEquation, coveragePOI, caps); } void GrCustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, diff --git a/src/gpu/gl/GrGLCaps.cpp b/src/gpu/gl/GrGLCaps.cpp index e8c3b55163..91cf83147c 100644 --- a/src/gpu/gl/GrGLCaps.cpp +++ b/src/gpu/gl/GrGLCaps.cpp @@ -303,6 +303,7 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, **************************************************************************/ this->initFSAASupport(ctxInfo, gli); + this->initBlendEqationSupport(ctxInfo); this->initStencilFormats(ctxInfo); if (kGL_GrGLStandard == standard) { @@ -319,24 +320,6 @@ void GrGLCaps::init(const GrContextOptions& contextOptions, fStencilWrapOpsSupport = true; } -// Disabling advanced blend until we can resolve various bugs -#if 0 - if (kIntel_GrGLVendor != ctxInfo.vendor()) { - if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) { - fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport; - glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction; - } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) { - fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport; - glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction; - } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) { - fBlendEquationSupport = kAdvanced_BlendEquationSupport; - glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction; - } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) { - fBlendEquationSupport = kAdvanced_BlendEquationSupport; - glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction; - } - } -#endif if (kGL_GrGLStandard == standard) { fMapBufferFlags = kCanMap_MapFlag; // we require VBO support and the desktop VBO // extension includes glMapBuffer. @@ -818,6 +801,48 @@ void GrGLCaps::initFSAASupport(const GrGLContextInfo& ctxInfo, const GrGLInterfa } } +void GrGLCaps::initBlendEqationSupport(const GrGLContextInfo& ctxInfo) { + GrGLSLCaps* glslCaps = static_cast<GrGLSLCaps*>(fShaderCaps.get()); + + // Disabling advanced blend on various platforms with major known issues. We also block Chrome + // for now until its own blacklists can be updated. + if (kAdreno4xx_GrGLRenderer == ctxInfo.renderer() || + kIntel_GrGLDriver == ctxInfo.driver() || + kChromium_GrGLDriver == ctxInfo.driver()) { + return; + } + + if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced_coherent")) { + fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport; + glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction; + } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced_coherent")) { + fBlendEquationSupport = kAdvancedCoherent_BlendEquationSupport; + glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction; + } else if (kNVIDIA_GrGLDriver == ctxInfo.driver() && + ctxInfo.driverVersion() < GR_GL_DRIVER_VER(337,00)) { + // Non-coherent advanced blend has an issue on NVIDIA pre 337.00. + return; + } else if (ctxInfo.hasExtension("GL_NV_blend_equation_advanced")) { + fBlendEquationSupport = kAdvanced_BlendEquationSupport; + glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kAutomatic_AdvBlendEqInteraction; + } else if (ctxInfo.hasExtension("GL_KHR_blend_equation_advanced")) { + fBlendEquationSupport = kAdvanced_BlendEquationSupport; + glslCaps->fAdvBlendEqInteraction = GrGLSLCaps::kGeneralEnable_AdvBlendEqInteraction; + // TODO: Use kSpecificEnables_AdvBlendEqInteraction if "blend_support_all_equations" is + // slow on a particular platform. + } else { + return; // No advanced blend support. + } + + SkASSERT(this->advancedBlendEquationSupport()); + + if (kNVIDIA_GrGLDriver == ctxInfo.driver()) { + // Blacklist color-dodge and color-burn on NVIDIA until the fix is released. + fAdvBlendEqBlacklist |= (1 << kColorDodge_GrBlendEquation) | + (1 << kColorBurn_GrBlendEquation); + } +} + namespace { const GrGLuint kUnknownBitCount = GrGLStencilAttachment::kUnknownBitCount; } diff --git a/src/gpu/gl/GrGLCaps.h b/src/gpu/gl/GrGLCaps.h index b04bf34361..ac89115a7b 100644 --- a/src/gpu/gl/GrGLCaps.h +++ b/src/gpu/gl/GrGLCaps.h @@ -309,6 +309,7 @@ private: }; void initFSAASupport(const GrGLContextInfo&, const GrGLInterface*); + void initBlendEqationSupport(const GrGLContextInfo&); void initStencilFormats(const GrGLContextInfo&); // This must be called after initFSAASupport(). void initConfigRenderableTable(const GrGLContextInfo&); diff --git a/src/gpu/gl/GrGLUtil.cpp b/src/gpu/gl/GrGLUtil.cpp index 5db541ca7f..0a71a1d4ac 100644 --- a/src/gpu/gl/GrGLUtil.cpp +++ b/src/gpu/gl/GrGLUtil.cpp @@ -148,6 +148,11 @@ void GrGLGetDriverInfo(GrGLStandard standard, return; } } + + if (kIntel_GrGLVendor == vendor) { + // We presume we're on the Intel driver since it hasn't identified itself as Mesa. + *outDriver = kIntel_GrGLDriver; + } } GrGLVersion GrGLGetVersionFromString(const char* versionString) { diff --git a/src/gpu/gl/GrGLUtil.h b/src/gpu/gl/GrGLUtil.h index 3a7f4505f7..f485b8d850 100644 --- a/src/gpu/gl/GrGLUtil.h +++ b/src/gpu/gl/GrGLUtil.h @@ -58,6 +58,7 @@ enum GrGLDriver { kMesa_GrGLDriver, kChromium_GrGLDriver, kNVIDIA_GrGLDriver, + kIntel_GrGLDriver, kUnknown_GrGLDriver }; |