aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/gl/builders
diff options
context:
space:
mode:
authorGravatar cdalton <cdalton@nvidia.com>2015-05-06 13:40:21 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-05-06 13:40:21 -0700
commit8917d62ef4d9bde9ec4f879dc42b309b03a0ad98 (patch)
tree155b2ec06eecc8aadee64f9152b6ea95515778ce /src/gpu/gl/builders
parente0cab96599764f7611de015f558a6b22162c3eda (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.cpp58
-rw-r--r--src/gpu/gl/builders/GrGLFragmentShaderBuilder.h10
-rw-r--r--src/gpu/gl/builders/GrGLShaderBuilder.cpp3
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;
}