aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/gpu/GrCaps.h9
-rw-r--r--src/gpu/GrCaps.cpp5
-rw-r--r--src/gpu/effects/GrCustomXfermode.cpp11
-rw-r--r--src/gpu/gl/GrGLCaps.cpp61
-rw-r--r--src/gpu/gl/GrGLCaps.h1
-rw-r--r--src/gpu/gl/GrGLUtil.cpp5
-rw-r--r--src/gpu/gl/GrGLUtil.h1
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
};