diff options
author | 2015-05-06 13:40:21 -0700 | |
---|---|---|
committer | 2015-05-06 13:40:21 -0700 | |
commit | 8917d62ef4d9bde9ec4f879dc42b309b03a0ad98 (patch) | |
tree | 155b2ec06eecc8aadee64f9152b6ea95515778ce /src/gpu/gl/builders | |
parent | e0cab96599764f7611de015f558a6b22162c3eda (diff) |
Implement support for KHR_blend_equation_advanced
Uses KHR(or NV)_blend_equation_advanced to implement custom Xfer modes
in hardware.
BUG=skia:
Review URL: https://codereview.chromium.org/1037123003
Diffstat (limited to 'src/gpu/gl/builders')
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp | 58 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLFragmentShaderBuilder.h | 10 | ||||
-rw-r--r-- | src/gpu/gl/builders/GrGLShaderBuilder.cpp | 3 |
3 files changed, 69 insertions, 2 deletions
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp index 51a0340ea9..8fcb0b972e 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp @@ -36,6 +36,47 @@ static void append_default_precision_qualifier(GrSLPrecision p, } } +static const char* specific_layout_qualifier_name(GrBlendEquation equation) { + SkASSERT(GrBlendEquationIsAdvanced(equation)); + + static const char* kLayoutQualifierNames[] = { + "blend_support_screen", + "blend_support_overlay", + "blend_support_darken", + "blend_support_lighten", + "blend_support_colordodge", + "blend_support_colorburn", + "blend_support_hardlight", + "blend_support_softlight", + "blend_support_difference", + "blend_support_exclusion", + "blend_support_multiply", + "blend_support_hsl_hue", + "blend_support_hsl_saturation", + "blend_support_hsl_color", + "blend_support_hsl_luminosity" + }; + return kLayoutQualifierNames[equation - kFirstAdvancedGrBlendEquation]; + + GR_STATIC_ASSERT(0 == kScreen_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(1 == kOverlay_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(2 == kDarken_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(3 == kLighten_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(4 == kColorDodge_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(5 == kColorBurn_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(6 == kHardLight_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(7 == kSoftLight_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(8 == kDifference_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(9 == kExclusion_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(10 == kMultiply_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(11 == kHSLHue_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(12 == kHSLSaturation_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(13 == kHSLColor_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(14 == kHSLLuminosity_GrBlendEquation - kFirstAdvancedGrBlendEquation); + GR_STATIC_ASSERT(SK_ARRAY_COUNT(kLayoutQualifierNames) == + kTotalGrBlendEquationCount - kFirstAdvancedGrBlendEquation); +} + GrGLFragmentShaderBuilder::DstReadKey GrGLFragmentShaderBuilder::KeyForDstRead(const GrTexture* dstCopy, const GrGLCaps& caps) { uint32_t key = kYesDstRead_DstReadKeyBit; @@ -183,6 +224,23 @@ const char* GrGLFragmentShaderBuilder::dstColor() { } } +void GrGLFragmentShaderBuilder::enableAdvancedBlendEquationIfNeeded(GrBlendEquation equation) { + SkASSERT(GrBlendEquationIsAdvanced(equation)); + + const GrGLSLCaps& caps = *fProgramBuilder->gpu()->glCaps().glslCaps(); + if (!caps.mustEnableAdvBlendEqs()) { + return; + } + + this->addFeature(1 << kBlendEquationAdvanced_GLSLPrivateFeature, + "GL_KHR_blend_equation_advanced"); + if (caps.mustEnableSpecificAdvBlendEqs()) { + this->addLayoutQualifier(specific_layout_qualifier_name(equation), kOut_InterfaceQualifier); + } else { + this->addLayoutQualifier("blend_support_all_equations", kOut_InterfaceQualifier); + } +} + void GrGLFragmentShaderBuilder::enableCustomOutput() { if (!fHasCustomColorOutput) { fHasCustomColorOutput = true; diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h index 7afc76c711..1ab7af6b1b 100644 --- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h +++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.h @@ -66,6 +66,11 @@ public: no effect advertised that it will read the destination. */ virtual const char* dstColor() = 0; + /** Adds any necessary layout qualifiers in order to legalize the supplied blend equation with + this shader. It is only legal to call this method with an advanced blend equation, and only + if these equations are supported. */ + virtual void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) = 0; + private: typedef GrGLFragmentBuilder INHERITED; }; @@ -95,6 +100,8 @@ public: const char* fragmentPosition() override; const char* dstColor() override; + void enableAdvancedBlendEquationIfNeeded(GrBlendEquation) override; + private: // Private public interface, used by GrGLProgramBuilder to build a fragment shader void enableCustomOutput(); @@ -123,7 +130,8 @@ private: */ enum GLSLPrivateFeature { kFragCoordConventions_GLSLPrivateFeature = kLastGLSLFeature + 1, - kLastGLSLPrivateFeature = kFragCoordConventions_GLSLPrivateFeature + kBlendEquationAdvanced_GLSLPrivateFeature, + kLastGLSLPrivateFeature = kBlendEquationAdvanced_GLSLPrivateFeature }; // Interpretation of DstReadKey when generating code diff --git a/src/gpu/gl/builders/GrGLShaderBuilder.cpp b/src/gpu/gl/builders/GrGLShaderBuilder.cpp index e885d36a43..67fbe2451d 100644 --- a/src/gpu/gl/builders/GrGLShaderBuilder.cpp +++ b/src/gpu/gl/builders/GrGLShaderBuilder.cpp @@ -173,7 +173,8 @@ void GrGLShaderBuilder::appendTextureLookup(const char* samplerName, } void GrGLShaderBuilder::addLayoutQualifier(const char* param, InterfaceQualifier interface) { - SkASSERT(fProgramBuilder->gpu()->glslGeneration() >= k330_GrGLSLGeneration); + SkASSERT(fProgramBuilder->gpu()->glslGeneration() >= k330_GrGLSLGeneration || + fProgramBuilder->gpu()->glCaps().glslCaps()->mustEnableAdvBlendEqs()); fLayoutParams[interface].push_back() = param; } |