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
diff --git a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
index 51a0340..8fcb0b9 100644
--- a/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLFragmentShaderBuilder.cpp
@@ -36,6 +36,47 @@
     }
 }
 
+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 @@
     } 
 }
 
+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;