Add initial support for NV_path_rendering extension to gpu command buffer

Add initial support for NV_path_rendering extension to gpu command
buffer. This is needed in order to support NV_path_rendering
implementation in Skia.

Implement this by creating a new GL ES pseudo-extension called
CHROMIUM_path_rendering. The CHROMIUM_path_rendering extension
will be exposed to clients only if the context is not a webgl context,
NV_path_rendering extension is present. Also, EXT_direct_state_access
extension must be present for Open GL.

Add matrix functions needed to support the feature:

void glMatrixLoadfEXT(GLenum matrixMode, const GLfloat* m)
void glMatrixLoadIdentityEXT(GLenum matrixMode)

NV_path_rendering needs these functions to implement transformations
for the path drawing.

Changes the build_gles2_cmd_buffer.py to be able to generate context
state variables that are arrays. The state variable is defined to be an
an array when its default value is an array.

Changes the build_gles2_cmd_buffer.py to round the float GL state
variables with round() when querying them with GetInteger.

The values GL_*_CHROMIUM tokens added match the values of corresponding
GL_*_NV tokens from the NV_path_rendering extensions. This is why the
values are passed after validation to the receiving GL function, without
any mapping.

BUG=344330

Review URL: https://codereview.chromium.org/169603002

Cr-Commit-Position: refs/heads/master@{#291878}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index b46c252b..ff0a04f 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -987,6 +987,9 @@
 
   void DoLoseContextCHROMIUM(GLenum current, GLenum other);
 
+  void DoMatrixLoadfCHROMIUM(GLenum matrix_mode, const GLfloat* matrix);
+  void DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode);
+
   // Creates a Program for the given program.
   Program* CreateProgram(
       GLuint client_id, GLuint service_id) {
@@ -10660,6 +10663,50 @@
   current_decoder_error_ = error::kLostContext;
 }
 
+void GLES2DecoderImpl::DoMatrixLoadfCHROMIUM(GLenum matrix_mode,
+                                             const GLfloat* matrix) {
+  DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
+         matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
+  if (!features().chromium_path_rendering) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
+                       "glMatrixLoadfCHROMIUM",
+                       "function not available");
+    return;
+  }
+
+  GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
+                               ? state_.projection_matrix
+                               : state_.modelview_matrix;
+  memcpy(target_matrix, matrix, sizeof(GLfloat) * 16);
+  // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
+  // since the values of the _NV and _CHROMIUM tokens match.
+  glMatrixLoadfEXT(matrix_mode, matrix);
+}
+
+void GLES2DecoderImpl::DoMatrixLoadIdentityCHROMIUM(GLenum matrix_mode) {
+  DCHECK(matrix_mode == GL_PATH_PROJECTION_CHROMIUM ||
+         matrix_mode == GL_PATH_MODELVIEW_CHROMIUM);
+
+  if (!features().chromium_path_rendering) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION,
+                       "glMatrixLoadIdentityCHROMIUM",
+                       "function not available");
+    return;
+  }
+
+  static GLfloat kIdentityMatrix[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f,
+                                        0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
+                                        0.0f, 0.0f, 0.0f, 1.0f};
+
+  GLfloat* target_matrix = matrix_mode == GL_PATH_PROJECTION_CHROMIUM
+                               ? state_.projection_matrix
+                               : state_.modelview_matrix;
+  memcpy(target_matrix, kIdentityMatrix, sizeof(kIdentityMatrix));
+  // The matrix_mode is either GL_PATH_MODELVIEW_NV or GL_PATH_PROJECTION_NV
+  // since the values of the _NV and _CHROMIUM tokens match.
+  glMatrixLoadIdentityEXT(matrix_mode);
+}
+
 bool GLES2DecoderImpl::ValidateAsyncTransfer(
     const char* function_name,
     TextureRef* texture_ref,