GLES1: glMatrixMode

BUG=angleproject:2306

Change-Id: I83e15990c10d9354c2db00766ddc7b0ab960aa5c
Reviewed-on: https://chromium-review.googlesource.com/996019
Commit-Queue: Lingfeng Yang <lfy@google.com>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index a239260..5fbc18b 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -6872,6 +6872,10 @@
                 *type      = GL_FLOAT;
                 *numParams = 4;
                 return true;
+            case GL_MATRIX_MODE:
+                *type      = GL_INT;
+                *numParams = 1;
+                return true;
         }
     }
 
diff --git a/src/libANGLE/Context_gles_1_0.cpp b/src/libANGLE/Context_gles_1_0.cpp
index d0a292b..913d3bd 100644
--- a/src/libANGLE/Context_gles_1_0.cpp
+++ b/src/libANGLE/Context_gles_1_0.cpp
@@ -264,7 +264,7 @@
 
 void Context::matrixMode(MatrixType mode)
 {
-    UNIMPLEMENTED();
+    mGLState.gles1().setMatrixMode(mode);
 }
 
 void Context::multMatrixf(const GLfloat *m)
diff --git a/src/libANGLE/GLES1State.cpp b/src/libANGLE/GLES1State.cpp
index 0a4e17d..7d742c9 100644
--- a/src/libANGLE/GLES1State.cpp
+++ b/src/libANGLE/GLES1State.cpp
@@ -44,7 +44,7 @@
       mCurrentColor({0.0f, 0.0f, 0.0f, 0.0f}),
       mCurrentNormal({0.0f, 0.0f, 0.0f}),
       mClientActiveTexture(0),
-      mCurrMatrixMode(MatrixType::Modelview),
+      mMatrixMode(MatrixType::Modelview),
       mShadeModel(ShadingModel::Smooth),
       mAlphaTestFunc(AlphaTestFunc::AlwaysPass),
       mAlphaTestRef(0.0f),
@@ -88,7 +88,7 @@
     mColorMaterialEnabled = false;
     mReflectionMapEnabled = false;
 
-    mCurrMatrixMode = MatrixType::Modelview;
+    mMatrixMode = MatrixType::Modelview;
 
     mCurrentColor  = {1.0f, 1.0f, 1.0f, 1.0f};
     mCurrentNormal = {0.0f, 0.0f, 1.0f};
@@ -200,4 +200,14 @@
     return mCurrentTextureCoords[unit];
 }
 
+void GLES1State::setMatrixMode(MatrixType mode)
+{
+    mMatrixMode = mode;
+}
+
+MatrixType GLES1State::getMatrixMode() const
+{
+    return mMatrixMode;
+}
+
 }  // namespace gl
diff --git a/src/libANGLE/GLES1State.h b/src/libANGLE/GLES1State.h
index c0e7e65..e67c360 100644
--- a/src/libANGLE/GLES1State.h
+++ b/src/libANGLE/GLES1State.h
@@ -135,6 +135,9 @@
     void setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords);
     const TextureCoordF &getCurrentTextureCoords(unsigned int unit) const;
 
+    void setMatrixMode(MatrixType mode);
+    MatrixType getMatrixMode() const;
+
   private:
     friend class State;
 
@@ -179,7 +182,7 @@
 
     // Table 6.7
     using MatrixStack = std::vector<angle::Mat4>;
-    MatrixType mCurrMatrixMode;
+    MatrixType mMatrixMode;
     MatrixStack mProjMatrices;
     MatrixStack mModelviewMatrices;
     std::vector<MatrixStack> mTextureMatrices;
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 770aa90..914fc66 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -2333,6 +2333,9 @@
         case GL_CLIENT_ACTIVE_TEXTURE:
             *params = mGLES1State.mClientActiveTexture + GL_TEXTURE0;
             break;
+        case GL_MATRIX_MODE:
+            *params = ToGLenum(mGLES1State.mMatrixMode);
+            break;
         default:
             UNREACHABLE();
             break;
diff --git a/src/libANGLE/validationES1.cpp b/src/libANGLE/validationES1.cpp
index 4a9d708..d8f8c85 100644
--- a/src/libANGLE/validationES1.cpp
+++ b/src/libANGLE/validationES1.cpp
@@ -371,8 +371,17 @@
 
 bool ValidateMatrixMode(Context *context, MatrixType mode)
 {
-    UNIMPLEMENTED();
-    return true;
+    ANGLE_VALIDATE_IS_GLES1(context);
+    switch (mode)
+    {
+        case MatrixType::Projection:
+        case MatrixType::Modelview:
+        case MatrixType::Texture:
+            return true;
+        default:
+            ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
+            return false;
+    }
 }
 
 bool ValidateMultMatrixf(Context *context, const GLfloat *m)
diff --git a/src/tests/angle_end2end_tests.gypi b/src/tests/angle_end2end_tests.gypi
index be63201..af4da5d 100644
--- a/src/tests/angle_end2end_tests.gypi
+++ b/src/tests/angle_end2end_tests.gypi
@@ -52,6 +52,7 @@
             '<(angle_path)/src/tests/gl_tests/gles1/CurrentColorTest.cpp',
             '<(angle_path)/src/tests/gl_tests/gles1/CurrentNormalTest.cpp',
             '<(angle_path)/src/tests/gl_tests/gles1/CurrentTextureCoordsTest.cpp',
+            '<(angle_path)/src/tests/gl_tests/gles1/MatrixModeTest.cpp',
             '<(angle_path)/src/tests/gl_tests/GLSLTest.cpp',
             '<(angle_path)/src/tests/gl_tests/ImageTest.cpp',
             '<(angle_path)/src/tests/gl_tests/IncompleteTextureTest.cpp',
diff --git a/src/tests/gl_tests/gles1/MatrixModeTest.cpp b/src/tests/gl_tests/gles1/MatrixModeTest.cpp
new file mode 100644
index 0000000..954055f
--- /dev/null
+++ b/src/tests/gl_tests/gles1/MatrixModeTest.cpp
@@ -0,0 +1,65 @@
+//
+// Copyright 2018 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// MatrixModeTest.cpp: Tests basic usage of glMatrixMode.
+
+#include "test_utils/ANGLETest.h"
+#include "test_utils/gl_raii.h"
+
+#include <vector>
+
+using namespace angle;
+
+class MatrixModeTest : public ANGLETest
+{
+  protected:
+    MatrixModeTest()
+    {
+        setWindowWidth(32);
+        setWindowHeight(32);
+        setConfigRedBits(8);
+        setConfigGreenBits(8);
+        setConfigBlueBits(8);
+        setConfigAlphaBits(8);
+        setConfigDepthBits(24);
+    }
+};
+
+// State query: Checks the initial state is correct.
+TEST_P(MatrixModeTest, InitialState)
+{
+    GLint matrixMode;
+    glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
+    EXPECT_GL_NO_ERROR();
+    EXPECT_GLENUM_EQ(GL_MODELVIEW, matrixMode);
+}
+
+// Checks for error-generating cases.
+TEST_P(MatrixModeTest, Negative)
+{
+    glMatrixMode(0);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+    glMatrixMode(GL_TEXTURE_2D);
+    EXPECT_GL_ERROR(GL_INVALID_ENUM);
+}
+
+// Checks that matrix mode can be set.
+TEST_P(MatrixModeTest, Set)
+{
+    GLint matrixMode;
+
+    std::vector<GLenum> modes = {GL_PROJECTION, GL_MODELVIEW, GL_TEXTURE};
+
+    for (auto mode : modes)
+    {
+        glMatrixMode(mode);
+        EXPECT_GL_NO_ERROR();
+        glGetIntegerv(GL_MATRIX_MODE, &matrixMode);
+        EXPECT_GLENUM_EQ(mode, matrixMode);
+    }
+}
+
+ANGLE_INSTANTIATE_TEST(MatrixModeTest, ES1_D3D11(), ES1_OPENGL(), ES1_OPENGLES());