Update stencil validation rules for WebGL

Based on kbr's patch:
https://chromium-review.googlesource.com/c/angle/angle/+/890605

Implements new rules in this revised WebGL conformance test:
https://github.com/KhronosGroup/WebGL/pull/2583

BUG=chromium:806557

Change-Id: I84701dd7156f0bc4a45ba68e63cb962d2d54c2e5
Reviewed-on: https://chromium-review.googlesource.com/952567
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tests/gl_tests/WebGLCompatibilityTest.cpp b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
index 3b517c1..7d5e374 100644
--- a/src/tests/gl_tests/WebGLCompatibilityTest.cpp
+++ b/src/tests/gl_tests/WebGLCompatibilityTest.cpp
@@ -197,6 +197,7 @@
                              glCheckFramebufferStatus(GL_FRAMEBUFFER));
             return;
         }
+
         ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
 
         const std::string renderingVs =
@@ -225,6 +226,8 @@
             0, 0, GLColor32F(floatData[0], floatData[1], floatData[2], floatData[3]), 1.0f);
     }
 
+    void TestDifferentStencilMaskAndRef(GLenum errIfMismatch);
+
     // Called from RenderingFeedbackLoopWithDrawBuffersEXT.
     void drawBuffersEXTFeedbackLoop(GLuint program,
                                     const std::array<GLenum, 2> &drawBuffers,
@@ -1182,8 +1185,9 @@
     }
 }
 
-// Tests the WebGL requirement of having the same stencil mask, writemask and ref for fron and back
-TEST_P(WebGLCompatibilityTest, RequiresSameStencilMaskAndRef)
+// Tests the WebGL requirement of having the same stencil mask, writemask and ref for front and back
+// (when stencil testing is enabled)
+void WebGLCompatibilityTest::TestDifferentStencilMaskAndRef(GLenum errIfMismatch)
 {
     // Run the test in an FBO to make sure we have some stencil bits.
     GLRenderbuffer renderbuffer;
@@ -1209,7 +1213,7 @@
     // Having a different front - back write mask generates an error.
     glStencilMaskSeparate(GL_FRONT, 1);
     glDrawArrays(GL_TRIANGLES, 0, 6);
-    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+    EXPECT_GL_ERROR(errIfMismatch);
 
     // Setting both write masks separately to the same value is valid.
     glStencilMaskSeparate(GL_BACK, 1);
@@ -1219,7 +1223,7 @@
     // Having a different stencil front - back mask generates an error
     glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 0, 1);
     glDrawArrays(GL_TRIANGLES, 0, 6);
-    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+    EXPECT_GL_ERROR(errIfMismatch);
 
     // Setting both masks separately to the same value is valid.
     glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 0, 1);
@@ -1229,7 +1233,7 @@
     // Having a different stencil front - back reference generates an error
     glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, 255, 1);
     glDrawArrays(GL_TRIANGLES, 0, 6);
-    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+    EXPECT_GL_ERROR(errIfMismatch);
 
     // Setting both references separately to the same value is valid.
     glStencilFuncSeparate(GL_BACK, GL_ALWAYS, 255, 1);
@@ -1241,6 +1245,16 @@
     glDrawArrays(GL_TRIANGLES, 0, 6);
     ASSERT_GL_NO_ERROR();
 }
+TEST_P(WebGLCompatibilityTest, StencilTestEnabledDisallowsDifferentStencilMaskAndRef)
+{
+    glEnable(GL_STENCIL_TEST);
+    TestDifferentStencilMaskAndRef(GL_INVALID_OPERATION);
+}
+TEST_P(WebGLCompatibilityTest, StencilTestDisabledAllowsDifferentStencilMaskAndRef)
+{
+    glDisable(GL_STENCIL_TEST);
+    TestDifferentStencilMaskAndRef(GL_NO_ERROR);
+}
 
 // Test that GL_FIXED is forbidden
 TEST_P(WebGLCompatibilityTest, ForbidsGLFixed)