WebGL validation of constant color & alpha blend.

In WebGL, generate INVALID_OPERATION if constant color and constant
alpha are used together as source and destination blend functions.

BUG=angleproject:1817

Change-Id: I9b2d05ab5017c013bb89c13256efbd80198de91b
Reviewed-on: https://chromium-review.googlesource.com/448940
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Commit-Queue: Frank Henigman <fjhenigman@chromium.org>
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 05a6740..cfbf594 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -10,6 +10,30 @@
 
 #include "test_utils/gl_raii.h"
 
+namespace
+{
+
+bool ConstantColorAndAlphaBlendFunctions(GLenum first, GLenum second)
+{
+    return (first == GL_CONSTANT_COLOR || first == GL_ONE_MINUS_CONSTANT_COLOR) &&
+           (second == GL_CONSTANT_ALPHA || second == GL_ONE_MINUS_CONSTANT_ALPHA);
+}
+
+void CheckBlendFunctions(GLenum src, GLenum dst)
+{
+    if (ConstantColorAndAlphaBlendFunctions(src, dst) ||
+        ConstantColorAndAlphaBlendFunctions(dst, src))
+    {
+        EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+    }
+    else
+    {
+        ASSERT_GL_NO_ERROR();
+    }
+}
+
+}  // namespace
+
 namespace angle
 {
 
@@ -436,6 +460,50 @@
     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
+// Test all blend function combinations.
+// In WebGL it is invalid to combine constant color with constant alpha.
+TEST_P(WebGLCompatibilityTest, BlendWithConstantColor)
+{
+    constexpr GLenum srcFunc[] = {
+        GL_ZERO,
+        GL_ONE,
+        GL_SRC_COLOR,
+        GL_ONE_MINUS_SRC_COLOR,
+        GL_DST_COLOR,
+        GL_ONE_MINUS_DST_COLOR,
+        GL_SRC_ALPHA,
+        GL_ONE_MINUS_SRC_ALPHA,
+        GL_DST_ALPHA,
+        GL_ONE_MINUS_DST_ALPHA,
+        GL_CONSTANT_COLOR,
+        GL_ONE_MINUS_CONSTANT_COLOR,
+        GL_CONSTANT_ALPHA,
+        GL_ONE_MINUS_CONSTANT_ALPHA,
+        GL_SRC_ALPHA_SATURATE,
+    };
+
+    constexpr GLenum dstFunc[] = {
+        GL_ZERO,           GL_ONE,
+        GL_SRC_COLOR,      GL_ONE_MINUS_SRC_COLOR,
+        GL_DST_COLOR,      GL_ONE_MINUS_DST_COLOR,
+        GL_SRC_ALPHA,      GL_ONE_MINUS_SRC_ALPHA,
+        GL_DST_ALPHA,      GL_ONE_MINUS_DST_ALPHA,
+        GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR,
+        GL_CONSTANT_ALPHA, GL_ONE_MINUS_CONSTANT_ALPHA,
+    };
+
+    for (GLenum src : srcFunc)
+    {
+        for (GLenum dst : dstFunc)
+        {
+            glBlendFunc(src, dst);
+            CheckBlendFunctions(src, dst);
+            glBlendFuncSeparate(src, dst, GL_ONE, GL_ONE);
+            CheckBlendFunctions(src, dst);
+        }
+    }
+}
+
 // Test the checks for OOB reads in the vertex buffers, instanced version
 TEST_P(WebGL2CompatibilityTest, DrawArraysBufferOutOfBoundsInstanced)
 {