Number of views should match when Draw* is called

The ANGLE_multiview specification is modified so that Draw* generates
an error if the number of views in the active program does not match
with the number of views in the active draw framebuffer object.
The tests and validation are modified accordingly.

The patch also sets a contact person, updates the contributor list and
sets the correct enum values in the ANGLE_multiview specification.

BUG=angleproject:2062
TEST=angle_end2end_tests

Change-Id: I15fee4c5e729605bb1d6292f7ad1155637578dea
Reviewed-on: https://chromium-review.googlesource.com/663160
Commit-Queue: Martin Radev <mradev@nvidia.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/tests/gl_tests/MultiviewDrawTest.cpp b/src/tests/gl_tests/MultiviewDrawTest.cpp
index 4b735bc..193c08e 100644
--- a/src/tests/gl_tests/MultiviewDrawTest.cpp
+++ b/src/tests/gl_tests/MultiviewDrawTest.cpp
@@ -594,7 +594,6 @@
 // 1) generates an INVALID_OPERATION error if the number of views in the active draw framebuffer and
 // program differs.
 // 2) does not generate any error if the number of views is the same.
-// 3) does not generate any error if the program does not use the multiview extension.
 TEST_P(MultiviewDrawValidationTest, NumViewsMismatch)
 {
     if (!requestMultiviewExtension())
@@ -645,30 +644,38 @@
         glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
         EXPECT_GL_NO_ERROR();
     }
+}
 
-    // Check that no errors are generated if the program does not use the multiview extension.
+// The test verifies that glDraw* generates an INVALID_OPERATION error if the program does not use
+// the multiview extension, but the active draw framebuffer has more than one view.
+TEST_P(MultiviewDrawValidationTest, NumViewsMismatchForNonMultiviewProgram)
+{
+    if (!requestMultiviewExtension())
     {
-        const std::string &vsSourceNoMultiview =
-            "#version 300 es\n"
-            "void main()\n"
-            "{}\n";
-        const std::string &fsSourceNoMultiview =
-            "#version 300 es\n"
-            "precision mediump float;\n"
-            "void main()\n"
-            "{}\n";
-        ANGLE_GL_PROGRAM(programNoMultiview, vsSourceNoMultiview, fsSourceNoMultiview);
-        glUseProgram(programNoMultiview);
-
-        glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTex2d,
-                                                     0, 2, &viewportOffsets[0]);
-
-        glDrawArrays(GL_TRIANGLES, 0, 3);
-        EXPECT_GL_NO_ERROR();
-
-        glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
-        EXPECT_GL_NO_ERROR();
+        return;
     }
+
+    const std::string &vsSourceNoMultiview =
+        "#version 300 es\n"
+        "void main()\n"
+        "{}\n";
+    const std::string &fsSourceNoMultiview =
+        "#version 300 es\n"
+        "precision mediump float;\n"
+        "void main()\n"
+        "{}\n";
+    ANGLE_GL_PROGRAM(programNoMultiview, vsSourceNoMultiview, fsSourceNoMultiview);
+    glUseProgram(programNoMultiview);
+
+    const GLint viewportOffsets[4] = {0, 0, 2, 0};
+    glFramebufferTextureMultiviewSideBySideANGLE(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, mTex2d, 0, 2,
+                                                 &viewportOffsets[0]);
+
+    glDrawArrays(GL_TRIANGLES, 0, 3);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
+
+    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
+    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
 }
 
 // The test verifies that glDraw*:
@@ -1118,14 +1125,17 @@
     // It is necessary to call draw, so that the divisor is propagated and to guarantee that dirty
     // bits are cleared.
     glUseProgram(dummyProgram);
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glBindVertexArray(vao[0]);
     glVertexAttribDivisor(1, 0);
     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
     glUseProgram(0);
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     ASSERT_GL_NO_ERROR();
 
     // Check that vertexAttribDivisor uses the number of views to update the divisor.
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawFramebuffer);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glUseProgram(program);
     glVertexAttribDivisor(1, 1);
     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
@@ -1136,13 +1146,16 @@
     // We keep the vao active and propagate the divisor to guarantee that there are no unresolved
     // dirty bits when useProgram is called.
     glUseProgram(dummyProgram);
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glVertexAttribDivisor(1, 1);
     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
     glUseProgram(0);
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     ASSERT_GL_NO_ERROR();
 
     // Check that useProgram uses the number of views to update the divisor.
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawFramebuffer);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glUseProgram(program);
     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
     EXPECT_EQ(GLColor::red, GetViewColor(0, 0, 0));
@@ -1150,25 +1163,28 @@
 
     // We go through similar steps as before.
     glUseProgram(dummyProgram);
+    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glVertexAttribDivisor(1, 1);
     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
     glUseProgram(0);
-    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     ASSERT_GL_NO_ERROR();
 
     // Check that bindVertexArray uses the number of views to update the divisor.
     {
         // Call useProgram with vao[1] being active to guarantee that useProgram will adjust the
         // divisor for vao[1] only.
+        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mDrawFramebuffer);
+        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         glBindVertexArray(vao[1]);
         glUseProgram(program);
         glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
-        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
         glBindVertexArray(0);
         ASSERT_GL_NO_ERROR();
     }
     // Bind vao[0] after useProgram is called to ensure that bindVertexArray is the call which
     // adjusts the divisor.
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glBindVertexArray(vao[0]);
     glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 1);
     EXPECT_EQ(GLColor::red, GetViewColor(0, 0, 0));