Make GLES2Implementation based on GLES2Interface

GLES2Interface is a pure virutal interface. It's likely
that more functions of GLES2Implementation will need have
be declared in GLES2Interface but this is a first step

BUG=155914


Review URL: https://chromiumcodereview.appspot.com/11138021

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162216 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 3b7596d..1b9db9f 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -2249,7 +2249,7 @@
     """Writes the GLES2 Implemention declaration."""
     impl_decl = func.GetInfo('impl_decl')
     if impl_decl == None or impl_decl == True:
-      file.Write("%s %s(%s);\n" %
+      file.Write("virtual %s %s(%s) OVERRIDE;\n" %
                  (func.return_type, func.original_name,
                   func.MakeTypedOriginalArgString("")))
       file.Write("\n")
@@ -2282,6 +2282,10 @@
 
   def WriteGLES2ImplementationHeader(self, func, file):
     """Writes the GLES2 Implemention."""
+    self.WriteGLES2ImplementationDeclaration(func, file)
+
+  def WriteGLES2Implementation(self, func, file):
+    """Writes the GLES2 Implemention."""
     impl_func = func.GetInfo('impl_func')
     impl_decl = func.GetInfo('impl_decl')
     gen_cmd = func.GetInfo('gen_cmd')
@@ -2289,7 +2293,7 @@
         (impl_func == None or impl_func == True) and
         (impl_decl == None or impl_decl == True) and
         (gen_cmd == None or gen_cmd == True)):
-      file.Write("%s %s(%s) {\n" %
+      file.Write("%s GLES2Implementation::%s(%s) {\n" %
                  (func.return_type, func.original_name,
                   func.MakeTypedOriginalArgString("")))
       file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
@@ -2302,8 +2306,29 @@
       self.WriteClientGLReturnLog(func, file)
       file.Write("}\n")
       file.Write("\n")
-    else:
-      self.WriteGLES2ImplementationDeclaration(func, file)
+
+  def WriteGLES2InterfaceHeader(self, func, file):
+    """Writes the GLES2 Interface."""
+    file.Write("virtual %s %s(%s) = 0;\n" %
+               (func.return_type, func.original_name,
+                func.MakeTypedOriginalArgString("")))
+
+  def WriteGLES2InterfaceStub(self, func, file):
+    """Writes the GLES2 Interface stub declaration."""
+    file.Write("virtual %s %s(%s) OVERRIDE;\n" %
+               (func.return_type, func.original_name,
+                func.MakeTypedOriginalArgString("")))
+
+  def WriteGLES2InterfaceStubImpl(self, func, file):
+    """Writes the GLES2 Interface stub declaration."""
+    args = func.GetOriginalArgs()
+    arg_string = ", ".join(
+        ["%s /* %s */" % (arg.type, arg.name) for arg in args])
+    file.Write("%s GLES2InterfaceStub::%s(%s) {\n" %
+               (func.return_type, func.original_name, arg_string))
+    if func.return_type != "void":
+      file.Write("  return 0;\n")
+    file.Write("}\n")
 
   def WriteGLES2ImplementationUnitTest(self, func, file):
     """Writes the GLES2 Implemention unit test."""
@@ -2474,9 +2499,9 @@
     """Overrriden from TypeHandler."""
     pass
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("%s %s(%s) {\n" %
+    file.Write("%s GLES2Implementation::%s(%s) {\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
     file.Write("  // TODO: for now this is a no-op\n")
@@ -2607,9 +2632,13 @@
     """Overrriden from TypeHandler."""
     file.Write("// TODO(gman): Implement test for %s\n" % func.name)
 
+  def WriteGLES2Implementation(self, func, file):
+    """Overrriden from TypeHandler."""
+    pass
+
   def WriteGLES2ImplementationHeader(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("%s %s(%s);\n" %
+    file.Write("virtual %s %s(%s) OVERRIDE;\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
     file.Write("\n")
@@ -2822,7 +2851,7 @@
 """
     self.WriteInvalidUnitTest(func, file, invalid_test)
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Writes the GLES2 Implemention."""
 
     impl_func = func.GetInfo('impl_func')
@@ -2832,7 +2861,7 @@
           (impl_func == None or impl_func == True) and
           (impl_decl == None or impl_decl == True)):
 
-      file.Write("%s %s(%s) {\n" %
+      file.Write("%s GLES2Implementation::%s(%s) {\n" %
                  (func.return_type, func.original_name,
                   func.MakeTypedOriginalArgString("")))
       file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
@@ -2866,9 +2895,6 @@
           'lc_type': name_arg.resource_type.lower(),
         })
 
-    else:
-      self.WriteGLES2ImplementationDeclaration(func, file)
-
 
 class GENnHandler(TypeHandler):
   """Handler for glGen___ type functions."""
@@ -2903,7 +2929,7 @@
                "  }\n" %
                (func.original_name, func.GetLastOriginalArg().name))
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
     log_code = ("""  GPU_CLIENT_LOG_CODE_BLOCK({
     for (GLsizei i = 0; i < n; ++i) {
@@ -2919,7 +2945,9 @@
         'resource_types': func.GetInfo('resource_types'),
         'count_name': func.GetOriginalArgs()[0].name,
       }
-    file.Write("%(return_type)s %(name)s(%(typed_args)s) {\n" % args)
+    file.Write(
+        "%(return_type)s GLES2Implementation::%(name)s(%(typed_args)s) {\n" %
+        args)
     func.WriteDestinationInitalizationValidation(file)
     self.WriteClientGLCallLog(func, file)
     for arg in func.GetOriginalArgs():
@@ -3164,9 +3192,9 @@
     file.Write("    return error::kInvalidArguments;\n")
     file.Write("  }\n")
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("%s %s(%s) {\n" %
+    file.Write("%s GLES2Implementation::%s(%s) {\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
     file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
@@ -3196,9 +3224,9 @@
     """Overrriden from TypeHandler."""
     pass
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("%s %s(%s) {\n" %
+    file.Write("%s GLES2Implementation::%s(%s) {\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
     file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
@@ -3328,7 +3356,7 @@
     file.Write("  %sHelper(n, %s);\n" %
                (func.original_name, func.GetLastOriginalArg().name))
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
     impl_decl = func.GetInfo('impl_decl')
     if impl_decl == None or impl_decl == True:
@@ -3340,7 +3368,9 @@
           'resource_type': func.GetInfo('resource_type').lower(),
           'count_name': func.GetOriginalArgs()[0].name,
         }
-      file.Write("%(return_type)s %(name)s(%(typed_args)s) {\n" % args)
+      file.Write(
+          "%(return_type)s GLES2Implementation::%(name)s(%(typed_args)s) {\n" %
+          args)
       file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
       func.WriteDestinationInitalizationValidation(file)
       self.WriteClientGLCallLog(func, file)
@@ -3507,11 +3537,11 @@
 """
     file.Write(code)
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
     impl_decl = func.GetInfo('impl_decl')
     if impl_decl == None or impl_decl == True:
-      file.Write("%s %s(%s) {\n" %
+      file.Write("%s GLES2Implementation::%s(%s) {\n" %
                  (func.return_type, func.original_name,
                   func.MakeTypedOriginalArgString("")))
       file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
@@ -3741,9 +3771,9 @@
       file.Write("    return error::kOutOfBounds;\n")
       file.Write("  }\n")
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("%s %s(%s) {\n" %
+    file.Write("%s GLES2Implementation::%s(%s) {\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
     file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
@@ -4010,9 +4040,9 @@
       file.Write("    return error::kOutOfBounds;\n")
       file.Write("  }\n")
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
-    file.Write("%s %s(%s) {\n" %
+    file.Write("%s GLES2Implementation::%s(%s) {\n" %
                (func.return_type, func.original_name,
                 func.MakeTypedOriginalArgString("")))
     file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
@@ -4493,12 +4523,12 @@
     file.Write("}\n")
     file.Write("\n")
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
     impl_func = func.GetInfo('impl_func')
     if impl_func == None or impl_func == True:
       error_value = func.GetInfo("error_value") or "GL_FALSE"
-      file.Write("%s %s(%s) {\n" %
+      file.Write("%s GLES2Implementation::%s(%s) {\n" %
                  (func.return_type, func.original_name,
                   func.MakeTypedOriginalArgString("")))
       file.Write("  GPU_CLIENT_SINGLE_THREAD_CHECK();\n")
@@ -4522,8 +4552,6 @@
       file.Write("  return *result;\n")
       file.Write("}\n")
       file.Write("\n")
-    else:
-      self.WriteGLES2ImplementationDeclaration(func, file)
 
   def WriteGLES2ImplementationUnitTest(self, func, file):
     """Overrriden from TypeHandler."""
@@ -4571,9 +4599,9 @@
     # add on a bucket id.
     func.AddCmdArg(Argument('bucket_id', 'uint32'))
 
-  def WriteGLES2ImplementationHeader(self, func, file):
+  def WriteGLES2Implementation(self, func, file):
     """Overrriden from TypeHandler."""
-    code_1 = """%(return_type)s %(func_name)s(%(args)s) {
+    code_1 = """%(return_type)s GLES2Implementation::%(func_name)s(%(args)s) {
   GPU_CLIENT_SINGLE_THREAD_CHECK();
 """
     code_2 = """  GPU_CLIENT_LOG("[" << GetLogPrefix()
@@ -5505,10 +5533,26 @@
     """Writes the GLES2 C Lib Implemention."""
     self.type_handler.WriteGLES2CLibImplementation(self, file)
 
+  def WriteGLES2InterfaceHeader(self, file):
+    """Writes the GLES2 Interface declaration."""
+    self.type_handler.WriteGLES2InterfaceHeader(self, file)
+
+  def WriteGLES2InterfaceStub(self, file):
+    """Writes the GLES2 Interface Stub declaration."""
+    self.type_handler.WriteGLES2InterfaceStub(self, file)
+
+  def WriteGLES2InterfaceStubImpl(self, file):
+    """Writes the GLES2 Interface Stub declaration."""
+    self.type_handler.WriteGLES2InterfaceStubImpl(self, file)
+
   def WriteGLES2ImplementationHeader(self, file):
     """Writes the GLES2 Implemention declaration."""
     self.type_handler.WriteGLES2ImplementationHeader(self, file)
 
+  def WriteGLES2Implementation(self, file):
+    """Writes the GLES2 Implemention definition."""
+    self.type_handler.WriteGLES2Implementation(self, file)
+
   def WriteGLES2ImplementationUnitTest(self, file):
     """Writes the GLES2 Implemention unit test."""
     self.type_handler.WriteGLES2ImplementationUnitTest(self, file)
@@ -6023,8 +6067,36 @@
 
     file.Close()
 
+  def WriteGLES2InterfaceHeader(self, filename):
+    """Writes the GLES2 interface header."""
+    file = CHeaderWriter(
+        filename,
+        "// This file is included by gles2_interface.h to declare the\n"
+        "// GL api functions.\n")
+    for func in self.original_functions:
+      func.WriteGLES2InterfaceHeader(file)
+    file.Close()
+
+  def WriteGLES2InterfaceStub(self, filename):
+    """Writes the GLES2 interface stub header."""
+    file = CHeaderWriter(
+        filename,
+        "// This file is included by gles2_interface_stub.h.\n")
+    for func in self.original_functions:
+      func.WriteGLES2InterfaceStub(file)
+    file.Close()
+
+  def WriteGLES2InterfaceStubImpl(self, filename):
+    """Writes the GLES2 interface header."""
+    file = CHeaderWriter(
+        filename,
+        "// This file is included by gles2_interface_stub.cc.\n")
+    for func in self.original_functions:
+      func.WriteGLES2InterfaceStubImpl(file)
+    file.Close()
+
   def WriteGLES2ImplementationHeader(self, filename):
-    """Writes the GLES2 helper header."""
+    """Writes the GLES2 Implementation header."""
     file = CHeaderWriter(
         filename,
         "// This file is included by gles2_implementation.h to declare the\n"
@@ -6033,6 +6105,16 @@
       func.WriteGLES2ImplementationHeader(file)
     file.Close()
 
+  def WriteGLES2Implementation(self, filename):
+    """Writes the GLES2 Implementation."""
+    file = CHeaderWriter(
+        filename,
+        "// This file is included by gles2_implementation.cc to define the\n"
+        "// GL api functions.\n")
+    for func in self.original_functions:
+      func.WriteGLES2Implementation(file)
+    file.Close()
+
   def WriteGLES2ImplementationUnitTests(self, filename):
     """Writes the GLES2 helper header."""
     file = CHeaderWriter(
@@ -6407,7 +6489,12 @@
     gen.WriteCommandIds("common/gles2_cmd_ids_autogen.h")
     gen.WriteFormat("common/gles2_cmd_format_autogen.h")
     gen.WriteFormatTest("common/gles2_cmd_format_test_autogen.h")
+    gen.WriteGLES2InterfaceHeader("client/gles2_interface_autogen.h")
+    gen.WriteGLES2InterfaceStub("client/gles2_interface_stub_autogen.h")
+    gen.WriteGLES2InterfaceStubImpl(
+        "client/gles2_interface_stub_impl_autogen.h")
     gen.WriteGLES2ImplementationHeader("client/gles2_implementation_autogen.h")
+    gen.WriteGLES2Implementation("client/gles2_implementation_impl_autogen.h")
     gen.WriteGLES2ImplementationUnitTests(
         "client/gles2_implementation_unittest_autogen.h")
     gen.WriteGLES2CLibImplementation("client/gles2_c_lib_autogen.h")
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index f72a1d0..8960cff9 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -3470,5 +3470,10 @@
   debug_marker_manager_.PopGroup();
 }
 
+// Include the auto-generated part of this file. We split this because it means
+// we can easily edit the non-auto generated parts right here in this file
+// instead of having to edit some template or the code generator.
+#include "../client/gles2_implementation_impl_autogen.h"
+
 }  // namespace gles2
 }  // namespace gpu
diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h
index c10cc51..47fb3b0 100644
--- a/gpu/command_buffer/client/gles2_implementation.h
+++ b/gpu/command_buffer/client/gles2_implementation.h
@@ -13,11 +13,13 @@
 #include <string>
 #include <vector>
 
+#include "../common/compiler_specific.h"
 #include "../common/debug_marker_manager.h"
 #include "../common/gles2_cmd_utils.h"
 #include "../common/scoped_ptr.h"
 #include "../client/ref_counted.h"
 #include "../client/gles2_cmd_helper.h"
+#include "../client/gles2_interface.h"
 #include "../client/query_tracker.h"
 #include "../client/ring_buffer.h"
 #include "../client/share_group.h"
@@ -98,7 +100,7 @@
 // be had by changing your code to use command buffers directly by using the
 // GLES2CmdHelper but that entails changing your code to use and deal with
 // shared memory and synchronization issues.
-class GLES2_IMPL_EXPORT GLES2Implementation {
+class GLES2_IMPL_EXPORT GLES2Implementation : public GLES2Interface {
  public:
   class ErrorMessageCallback {
    public:
@@ -180,7 +182,7 @@
       bool share_resources,
       bool bind_generates_resource);
 
-  ~GLES2Implementation();
+  virtual ~GLES2Implementation();
 
   bool Initialize(
       unsigned int starting_transfer_buffer_size,
@@ -199,10 +201,12 @@
   // this file instead of having to edit some template or the code generator.
   #include "../client/gles2_implementation_autogen.h"
 
-  void DisableVertexAttribArray(GLuint index);
-  void EnableVertexAttribArray(GLuint index);
-  void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params);
-  void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params);
+  virtual void DisableVertexAttribArray(GLuint index) OVERRIDE;
+  virtual void EnableVertexAttribArray(GLuint index) OVERRIDE;
+  virtual void GetVertexAttribfv(
+      GLuint index, GLenum pname, GLfloat* params) OVERRIDE;
+  virtual void GetVertexAttribiv(
+      GLuint index, GLenum pname, GLint* params) OVERRIDE;
 
   void GetProgramInfoCHROMIUMHelper(GLuint program, std::vector<int8>* result);
   GLint GetAttribLocationHelper(GLuint program, const char* name);
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 8b7901f..7ecd17d 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -11,1621 +11,492 @@
 #ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
 #define GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
 
-void ActiveTexture(GLenum texture);
+virtual void ActiveTexture(GLenum texture) OVERRIDE;
 
-void AttachShader(GLuint program, GLuint shader) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAttachShader(" << program << ", " << shader << ")");  // NOLINT
-  helper_->AttachShader(program, shader);
-}
+virtual void AttachShader(GLuint program, GLuint shader) OVERRIDE;
 
-void BindAttribLocation(GLuint program, GLuint index, const char* name);
+virtual void BindAttribLocation(
+    GLuint program, GLuint index, const char* name) OVERRIDE;
 
-void BindBuffer(GLenum target, GLuint buffer) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindBuffer(" << GLES2Util::GetStringBufferTarget(target) << ", " << buffer << ")");  // NOLINT
-  if (IsBufferReservedId(buffer)) {
-    SetGLError(GL_INVALID_OPERATION, "BindBuffer", "buffer reserved id");
-    return;
-  }
-  BindBufferHelper(target, buffer);
-  helper_->BindBuffer(target, buffer);
-}
+virtual void BindBuffer(GLenum target, GLuint buffer) OVERRIDE;
 
-void BindFramebuffer(GLenum target, GLuint framebuffer) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindFramebuffer(" << GLES2Util::GetStringFrameBufferTarget(target) << ", " << framebuffer << ")");  // NOLINT
-  if (IsFramebufferReservedId(framebuffer)) {
-    SetGLError(
-        GL_INVALID_OPERATION, "BindFramebuffer", "framebuffer reserved id");
-    return;
-  }
-  BindFramebufferHelper(target, framebuffer);
-  helper_->BindFramebuffer(target, framebuffer);
-}
+virtual void BindFramebuffer(GLenum target, GLuint framebuffer) OVERRIDE;
 
-void BindRenderbuffer(GLenum target, GLuint renderbuffer) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindRenderbuffer(" << GLES2Util::GetStringRenderBufferTarget(target) << ", " << renderbuffer << ")");  // NOLINT
-  if (IsRenderbufferReservedId(renderbuffer)) {
-    SetGLError(
-        GL_INVALID_OPERATION, "BindRenderbuffer", "renderbuffer reserved id");
-    return;
-  }
-  BindRenderbufferHelper(target, renderbuffer);
-  helper_->BindRenderbuffer(target, renderbuffer);
-}
+virtual void BindRenderbuffer(GLenum target, GLuint renderbuffer) OVERRIDE;
 
-void BindTexture(GLenum target, GLuint texture) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindTexture(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << texture << ")");  // NOLINT
-  if (IsTextureReservedId(texture)) {
-    SetGLError(GL_INVALID_OPERATION, "BindTexture", "texture reserved id");
-    return;
-  }
-  BindTextureHelper(target, texture);
-  helper_->BindTexture(target, texture);
-}
+virtual void BindTexture(GLenum target, GLuint texture) OVERRIDE;
 
-void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendColor(" << red << ", " << green << ", " << blue << ", " << alpha << ")");  // NOLINT
-  helper_->BlendColor(red, green, blue, alpha);
-}
+virtual void BlendColor(
+    GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) OVERRIDE;
 
-void BlendEquation(GLenum mode) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendEquation(" << GLES2Util::GetStringEquation(mode) << ")");  // NOLINT
-  helper_->BlendEquation(mode);
-}
+virtual void BlendEquation(GLenum mode) OVERRIDE;
 
-void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendEquationSeparate(" << GLES2Util::GetStringEquation(modeRGB) << ", " << GLES2Util::GetStringEquation(modeAlpha) << ")");  // NOLINT
-  helper_->BlendEquationSeparate(modeRGB, modeAlpha);
-}
+virtual void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) OVERRIDE;
 
-void BlendFunc(GLenum sfactor, GLenum dfactor) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendFunc(" << GLES2Util::GetStringSrcBlendFactor(sfactor) << ", " << GLES2Util::GetStringDstBlendFactor(dfactor) << ")");  // NOLINT
-  helper_->BlendFunc(sfactor, dfactor);
-}
+virtual void BlendFunc(GLenum sfactor, GLenum dfactor) OVERRIDE;
 
-void BlendFuncSeparate(
-    GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendFuncSeparate(" << GLES2Util::GetStringSrcBlendFactor(srcRGB) << ", " << GLES2Util::GetStringDstBlendFactor(dstRGB) << ", " << GLES2Util::GetStringSrcBlendFactor(srcAlpha) << ", " << GLES2Util::GetStringDstBlendFactor(dstAlpha) << ")");  // NOLINT
-  helper_->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
+virtual void BlendFuncSeparate(
+    GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) OVERRIDE;
 
-void BufferData(
-    GLenum target, GLsizeiptr size, const void* data, GLenum usage);
+virtual void BufferData(
+    GLenum target, GLsizeiptr size, const void* data, GLenum usage) OVERRIDE;
 
-void BufferSubData(
-    GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
+virtual void BufferSubData(
+    GLenum target, GLintptr offset, GLsizeiptr size,
+    const void* data) OVERRIDE;
 
-GLenum CheckFramebufferStatus(GLenum target) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCheckFramebufferStatus(" << GLES2Util::GetStringFrameBufferTarget(target) << ")");  // NOLINT
-  typedef CheckFramebufferStatus::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return GL_FRAMEBUFFER_UNSUPPORTED;
-  }
-  *result = 0;
-  helper_->CheckFramebufferStatus(
-      target, GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  GPU_CLIENT_LOG("returned " << *result);
-  return *result;
-}
+virtual GLenum CheckFramebufferStatus(GLenum target) OVERRIDE;
 
-void Clear(GLbitfield mask);
+virtual void Clear(GLbitfield mask) OVERRIDE;
 
-void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearColor(" << red << ", " << green << ", " << blue << ", " << alpha << ")");  // NOLINT
-  helper_->ClearColor(red, green, blue, alpha);
-}
+virtual void ClearColor(
+    GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) OVERRIDE;
 
-void ClearDepthf(GLclampf depth) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearDepthf(" << depth << ")");
-  helper_->ClearDepthf(depth);
-}
+virtual void ClearDepthf(GLclampf depth) OVERRIDE;
 
-void ClearStencil(GLint s) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearStencil(" << s << ")");
-  helper_->ClearStencil(s);
-}
+virtual void ClearStencil(GLint s) OVERRIDE;
 
-void ColorMask(
-    GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glColorMask(" << GLES2Util::GetStringBool(red) << ", " << GLES2Util::GetStringBool(green) << ", " << GLES2Util::GetStringBool(blue) << ", " << GLES2Util::GetStringBool(alpha) << ")");  // NOLINT
-  helper_->ColorMask(red, green, blue, alpha);
-}
+virtual void ColorMask(
+    GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) OVERRIDE;
 
-void CompileShader(GLuint shader) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompileShader(" << shader << ")");  // NOLINT
-  helper_->CompileShader(shader);
-}
+virtual void CompileShader(GLuint shader) OVERRIDE;
 
-void CompressedTexImage2D(
+virtual void CompressedTexImage2D(
     GLenum target, GLint level, GLenum internalformat, GLsizei width,
-    GLsizei height, GLint border, GLsizei imageSize, const void* data);
+    GLsizei height, GLint border, GLsizei imageSize,
+    const void* data) OVERRIDE;
 
-void CompressedTexSubImage2D(
+virtual void CompressedTexSubImage2D(
     GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
-    GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+    GLsizei height, GLenum format, GLsizei imageSize,
+    const void* data) OVERRIDE;
 
-void CopyTexImage2D(
+virtual void CopyTexImage2D(
     GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
-    GLsizei width, GLsizei height, GLint border) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyTexImage2D(" << GLES2Util::GetStringTextureTarget(target) << ", " << level << ", " << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " << x << ", " << y << ", " << width << ", " << height << ", " << border << ")");  // NOLINT
-  if (width < 0) {
-    SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "width < 0");
-    return;
-  }
-  if (height < 0) {
-    SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "height < 0");
-    return;
-  }
-  helper_->CopyTexImage2D(
-      target, level, internalformat, x, y, width, height, border);
-}
+    GLsizei width, GLsizei height, GLint border) OVERRIDE;
 
-void CopyTexSubImage2D(
+virtual void CopyTexSubImage2D(
     GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
-    GLsizei width, GLsizei height) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyTexSubImage2D(" << GLES2Util::GetStringTextureTarget(target) << ", " << level << ", " << xoffset << ", " << yoffset << ", " << x << ", " << y << ", " << width << ", " << height << ")");  // NOLINT
-  if (width < 0) {
-    SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D", "width < 0");
-    return;
-  }
-  if (height < 0) {
-    SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D", "height < 0");
-    return;
-  }
-  helper_->CopyTexSubImage2D(
-      target, level, xoffset, yoffset, x, y, width, height);
-}
+    GLsizei width, GLsizei height) OVERRIDE;
 
-GLuint CreateProgram() {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateProgram(" << ")");
-  GLuint client_id;
-  GetIdHandler(id_namespaces::kProgramsAndShaders)->
-      MakeIds(this, 0, 1, &client_id);
-  helper_->CreateProgram(client_id);
-  GPU_CLIENT_LOG("returned " << client_id);
-  return client_id;
-}
+virtual GLuint CreateProgram() OVERRIDE;
 
-GLuint CreateShader(GLenum type) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateShader(" << GLES2Util::GetStringShaderType(type) << ")");  // NOLINT
-  GLuint client_id;
-  GetIdHandler(id_namespaces::kProgramsAndShaders)->
-      MakeIds(this, 0, 1, &client_id);
-  helper_->CreateShader(type, client_id);
-  GPU_CLIENT_LOG("returned " << client_id);
-  return client_id;
-}
+virtual GLuint CreateShader(GLenum type) OVERRIDE;
 
-void CullFace(GLenum mode) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCullFace(" << GLES2Util::GetStringFaceType(mode) << ")");  // NOLINT
-  helper_->CullFace(mode);
-}
+virtual void CullFace(GLenum mode) OVERRIDE;
 
-void DeleteBuffers(GLsizei n, const GLuint* buffers) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteBuffers(" << n << ", " << static_cast<const void*>(buffers) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << buffers[i]);
-    }
-  });
-  GPU_CLIENT_DCHECK_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_DCHECK(buffers[i] != 0);
-    }
-  });
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glDeleteBuffers", "n < 0");
-    return;
-  }
-  DeleteBuffersHelper(n, buffers);
-}
+virtual void DeleteBuffers(GLsizei n, const GLuint* buffers) OVERRIDE;
 
-void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteFramebuffers(" << n << ", " << static_cast<const void*>(framebuffers) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << framebuffers[i]);
-    }
-  });
-  GPU_CLIENT_DCHECK_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_DCHECK(framebuffers[i] != 0);
-    }
-  });
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glDeleteFramebuffers", "n < 0");
-    return;
-  }
-  DeleteFramebuffersHelper(n, framebuffers);
-}
+virtual void DeleteFramebuffers(
+    GLsizei n, const GLuint* framebuffers) OVERRIDE;
 
-void DeleteProgram(GLuint program) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteProgram(" << program << ")");  // NOLINT
-  GPU_CLIENT_DCHECK(program != 0);
-  DeleteProgramHelper(program);
-}
+virtual void DeleteProgram(GLuint program) OVERRIDE;
 
-void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteRenderbuffers(" << n << ", " << static_cast<const void*>(renderbuffers) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << renderbuffers[i]);
-    }
-  });
-  GPU_CLIENT_DCHECK_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_DCHECK(renderbuffers[i] != 0);
-    }
-  });
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glDeleteRenderbuffers", "n < 0");
-    return;
-  }
-  DeleteRenderbuffersHelper(n, renderbuffers);
-}
+virtual void DeleteRenderbuffers(
+    GLsizei n, const GLuint* renderbuffers) OVERRIDE;
 
-void DeleteShader(GLuint shader) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteShader(" << shader << ")");
-  GPU_CLIENT_DCHECK(shader != 0);
-  DeleteShaderHelper(shader);
-}
+virtual void DeleteShader(GLuint shader) OVERRIDE;
 
-void DeleteTextures(GLsizei n, const GLuint* textures) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteTextures(" << n << ", " << static_cast<const void*>(textures) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << textures[i]);
-    }
-  });
-  GPU_CLIENT_DCHECK_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_DCHECK(textures[i] != 0);
-    }
-  });
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glDeleteTextures", "n < 0");
-    return;
-  }
-  DeleteTexturesHelper(n, textures);
-}
+virtual void DeleteTextures(GLsizei n, const GLuint* textures) OVERRIDE;
 
-void DepthFunc(GLenum func) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDepthFunc(" << GLES2Util::GetStringCmpFunction(func) << ")");  // NOLINT
-  helper_->DepthFunc(func);
-}
+virtual void DepthFunc(GLenum func) OVERRIDE;
 
-void DepthMask(GLboolean flag) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDepthMask(" << GLES2Util::GetStringBool(flag) << ")");  // NOLINT
-  helper_->DepthMask(flag);
-}
+virtual void DepthMask(GLboolean flag) OVERRIDE;
 
-void DepthRangef(GLclampf zNear, GLclampf zFar) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDepthRangef(" << zNear << ", " << zFar << ")");  // NOLINT
-  helper_->DepthRangef(zNear, zFar);
-}
+virtual void DepthRangef(GLclampf zNear, GLclampf zFar) OVERRIDE;
 
-void DetachShader(GLuint program, GLuint shader) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDetachShader(" << program << ", " << shader << ")");  // NOLINT
-  helper_->DetachShader(program, shader);
-}
+virtual void DetachShader(GLuint program, GLuint shader) OVERRIDE;
 
-void Disable(GLenum cap);
+virtual void Disable(GLenum cap) OVERRIDE;
 
-void DrawArrays(GLenum mode, GLint first, GLsizei count);
+virtual void DrawArrays(GLenum mode, GLint first, GLsizei count) OVERRIDE;
 
-void DrawElements(
-    GLenum mode, GLsizei count, GLenum type, const void* indices);
+virtual void DrawElements(
+    GLenum mode, GLsizei count, GLenum type, const void* indices) OVERRIDE;
 
-void Enable(GLenum cap);
+virtual void Enable(GLenum cap) OVERRIDE;
 
-void Finish();
+virtual void Finish() OVERRIDE;
 
-void Flush();
+virtual void Flush() OVERRIDE;
 
-void ShallowFlushCHROMIUM();
+virtual void ShallowFlushCHROMIUM() OVERRIDE;
 
-void FramebufferRenderbuffer(
+virtual void FramebufferRenderbuffer(
     GLenum target, GLenum attachment, GLenum renderbuffertarget,
-    GLuint renderbuffer) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFramebufferRenderbuffer(" << GLES2Util::GetStringFrameBufferTarget(target) << ", " << GLES2Util::GetStringAttachment(attachment) << ", " << GLES2Util::GetStringRenderBufferTarget(renderbuffertarget) << ", " << renderbuffer << ")");  // NOLINT
-  helper_->FramebufferRenderbuffer(
-      target, attachment, renderbuffertarget, renderbuffer);
-}
+    GLuint renderbuffer) OVERRIDE;
 
-void FramebufferTexture2D(
+virtual void FramebufferTexture2D(
     GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
-    GLint level) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFramebufferTexture2D(" << GLES2Util::GetStringFrameBufferTarget(target) << ", " << GLES2Util::GetStringAttachment(attachment) << ", " << GLES2Util::GetStringTextureTarget(textarget) << ", " << texture << ", " << level << ")");  // NOLINT
-  helper_->FramebufferTexture2D(target, attachment, textarget, texture, level);
-}
+    GLint level) OVERRIDE;
 
-void FrontFace(GLenum mode) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFrontFace(" << GLES2Util::GetStringFaceMode(mode) << ")");  // NOLINT
-  helper_->FrontFace(mode);
-}
+virtual void FrontFace(GLenum mode) OVERRIDE;
 
-void GenBuffers(GLsizei n, GLuint* buffers) {
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenBuffers(" << n << ", " << static_cast<const void*>(buffers) << ")");  // NOLINT
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glGenBuffers", "n < 0");
-    return;
-  }
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GetIdHandler(id_namespaces::kBuffers)->
-      MakeIds(this, 0, n, buffers);
-  helper_->GenBuffersImmediate(n, buffers);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << buffers[i]);
-    }
-  });
-}
+virtual void GenBuffers(GLsizei n, GLuint* buffers) OVERRIDE;
 
-void GenerateMipmap(GLenum target) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenerateMipmap(" << GLES2Util::GetStringTextureBindTarget(target) << ")");  // NOLINT
-  helper_->GenerateMipmap(target);
-}
+virtual void GenerateMipmap(GLenum target) OVERRIDE;
 
-void GenFramebuffers(GLsizei n, GLuint* framebuffers) {
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenFramebuffers(" << n << ", " << static_cast<const void*>(framebuffers) << ")");  // NOLINT
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glGenFramebuffers", "n < 0");
-    return;
-  }
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GetIdHandler(id_namespaces::kFramebuffers)->
-      MakeIds(this, 0, n, framebuffers);
-  helper_->GenFramebuffersImmediate(n, framebuffers);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << framebuffers[i]);
-    }
-  });
-}
+virtual void GenFramebuffers(GLsizei n, GLuint* framebuffers) OVERRIDE;
 
-void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) {
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenRenderbuffers(" << n << ", " << static_cast<const void*>(renderbuffers) << ")");  // NOLINT
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glGenRenderbuffers", "n < 0");
-    return;
-  }
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GetIdHandler(id_namespaces::kRenderbuffers)->
-      MakeIds(this, 0, n, renderbuffers);
-  helper_->GenRenderbuffersImmediate(n, renderbuffers);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << renderbuffers[i]);
-    }
-  });
-}
+virtual void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) OVERRIDE;
 
-void GenTextures(GLsizei n, GLuint* textures) {
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenTextures(" << n << ", " << static_cast<const void*>(textures) << ")");  // NOLINT
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glGenTextures", "n < 0");
-    return;
-  }
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GetIdHandler(id_namespaces::kTextures)->
-      MakeIds(this, 0, n, textures);
-  helper_->GenTexturesImmediate(n, textures);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << textures[i]);
-    }
-  });
-}
+virtual void GenTextures(GLsizei n, GLuint* textures) OVERRIDE;
 
-void GetActiveAttrib(
+virtual void GetActiveAttrib(
     GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
-    GLenum* type, char* name);
+    GLenum* type, char* name) OVERRIDE;
 
-void GetActiveUniform(
+virtual void GetActiveUniform(
     GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
-    GLenum* type, char* name);
+    GLenum* type, char* name) OVERRIDE;
 
-void GetAttachedShaders(
-    GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
+virtual void GetAttachedShaders(
+    GLuint program, GLsizei maxcount, GLsizei* count,
+    GLuint* shaders) OVERRIDE;
 
-GLint GetAttribLocation(GLuint program, const char* name);
+virtual GLint GetAttribLocation(GLuint program, const char* name) OVERRIDE;
 
-void GetBooleanv(GLenum pname, GLboolean* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLboolean, params);
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetBooleanv(" << GLES2Util::GetStringGLState(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetBooleanvHelper(pname, params)) {
-    return;
-  }
-  typedef GetBooleanv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetBooleanv(pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetBufferParameteriv(" << GLES2Util::GetStringBufferTarget(target) << ", " << GLES2Util::GetStringBufferParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetBufferParameterivHelper(target, pname, params)) {
-    return;
-  }
-  typedef GetBufferParameteriv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetBufferParameteriv(target, pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-GLenum GetError();
+virtual void GetBooleanv(GLenum pname, GLboolean* params) OVERRIDE;
 
-void GetFloatv(GLenum pname, GLfloat* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetFloatv(" << GLES2Util::GetStringGLState(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetFloatvHelper(pname, params)) {
-    return;
-  }
-  typedef GetFloatv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetFloatv(pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-void GetFramebufferAttachmentParameteriv(
-    GLenum target, GLenum attachment, GLenum pname, GLint* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetFramebufferAttachmentParameteriv(" << GLES2Util::GetStringFrameBufferTarget(target) << ", " << GLES2Util::GetStringAttachment(attachment) << ", " << GLES2Util::GetStringFrameBufferParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetFramebufferAttachmentParameterivHelper(
-      target, attachment, pname, params)) {
-    return;
-  }
-  typedef GetFramebufferAttachmentParameteriv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetFramebufferAttachmentParameteriv(target, attachment, pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-void GetIntegerv(GLenum pname, GLint* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetIntegerv(" << GLES2Util::GetStringGLState(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetIntegervHelper(pname, params)) {
-    return;
-  }
-  typedef GetIntegerv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetIntegerv(pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-void GetProgramiv(GLuint program, GLenum pname, GLint* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetProgramiv(" << program << ", " << GLES2Util::GetStringProgramParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetProgramivHelper(program, pname, params)) {
-    return;
-  }
-  typedef GetProgramiv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetProgramiv(program, pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-void GetProgramInfoLog(
-    GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(GLsizei, length);
-  GPU_CLIENT_LOG("[" << GetLogPrefix()
-      << "] glGetProgramInfoLog" << "("
-      << program << ", "
-      << bufsize << ", "
-      << static_cast<void*>(length) << ", "
-      << static_cast<void*>(infolog) << ")");
-  helper_->SetBucketSize(kResultBucketId, 0);
-  helper_->GetProgramInfoLog(program, kResultBucketId);
-  std::string str;
-  GLsizei max_size = 0;
-  if (GetBucketAsString(kResultBucketId, &str)) {
-    if (bufsize > 0) {
-      max_size =
-          std::min(static_cast<size_t>(bufsize) - 1, str.size());
-      memcpy(infolog, str.c_str(), max_size);
-      infolog[max_size] = '\0';
-      GPU_CLIENT_LOG("------\n" << infolog << "\n------");
-    }
-  }
-  if (length != NULL) {
-    *length = max_size;
-  }
-}
-void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetRenderbufferParameteriv(" << GLES2Util::GetStringRenderBufferTarget(target) << ", " << GLES2Util::GetStringRenderBufferParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetRenderbufferParameterivHelper(target, pname, params)) {
-    return;
-  }
-  typedef GetRenderbufferParameteriv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetRenderbufferParameteriv(target, pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-void GetShaderiv(GLuint shader, GLenum pname, GLint* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetShaderiv(" << shader << ", " << GLES2Util::GetStringShaderParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetShaderivHelper(shader, pname, params)) {
-    return;
-  }
-  typedef GetShaderiv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetShaderiv(shader, pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-void GetShaderInfoLog(
-    GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(GLsizei, length);
-  GPU_CLIENT_LOG("[" << GetLogPrefix()
-      << "] glGetShaderInfoLog" << "("
-      << shader << ", "
-      << bufsize << ", "
-      << static_cast<void*>(length) << ", "
-      << static_cast<void*>(infolog) << ")");
-  helper_->SetBucketSize(kResultBucketId, 0);
-  helper_->GetShaderInfoLog(shader, kResultBucketId);
-  std::string str;
-  GLsizei max_size = 0;
-  if (GetBucketAsString(kResultBucketId, &str)) {
-    if (bufsize > 0) {
-      max_size =
-          std::min(static_cast<size_t>(bufsize) - 1, str.size());
-      memcpy(infolog, str.c_str(), max_size);
-      infolog[max_size] = '\0';
-      GPU_CLIENT_LOG("------\n" << infolog << "\n------");
-    }
-  }
-  if (length != NULL) {
-    *length = max_size;
-  }
-}
-void GetShaderPrecisionFormat(
-    GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
+virtual void GetBufferParameteriv(
+    GLenum target, GLenum pname, GLint* params) OVERRIDE;
 
-void GetShaderSource(
-    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(GLsizei, length);
-  GPU_CLIENT_LOG("[" << GetLogPrefix()
-      << "] glGetShaderSource" << "("
-      << shader << ", "
-      << bufsize << ", "
-      << static_cast<void*>(length) << ", "
-      << static_cast<void*>(source) << ")");
-  helper_->SetBucketSize(kResultBucketId, 0);
-  helper_->GetShaderSource(shader, kResultBucketId);
-  std::string str;
-  GLsizei max_size = 0;
-  if (GetBucketAsString(kResultBucketId, &str)) {
-    if (bufsize > 0) {
-      max_size =
-          std::min(static_cast<size_t>(bufsize) - 1, str.size());
-      memcpy(source, str.c_str(), max_size);
-      source[max_size] = '\0';
-      GPU_CLIENT_LOG("------\n" << source << "\n------");
-    }
-  }
-  if (length != NULL) {
-    *length = max_size;
-  }
-}
-const GLubyte* GetString(GLenum name);
+virtual GLenum GetError() OVERRIDE;
 
-void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetTexParameterfv(" << GLES2Util::GetStringGetTexParamTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetTexParameterfvHelper(target, pname, params)) {
-    return;
-  }
-  typedef GetTexParameterfv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetTexParameterfv(target, pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetTexParameteriv(" << GLES2Util::GetStringGetTexParamTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  if (GetTexParameterivHelper(target, pname, params)) {
-    return;
-  }
-  typedef GetTexParameteriv::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return;
-  }
-  result->SetNumResults(0);
-  helper_->GetTexParameteriv(target, pname,
-      GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  result->CopyResult(params);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (int32 i = 0; i < result->GetNumResults(); ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
-    }
-  });
-}
-void GetUniformfv(GLuint program, GLint location, GLfloat* params);
+virtual void GetFloatv(GLenum pname, GLfloat* params) OVERRIDE;
 
-void GetUniformiv(GLuint program, GLint location, GLint* params);
+virtual void GetFramebufferAttachmentParameteriv(
+    GLenum target, GLenum attachment, GLenum pname, GLint* params) OVERRIDE;
 
-GLint GetUniformLocation(GLuint program, const char* name);
+virtual void GetIntegerv(GLenum pname, GLint* params) OVERRIDE;
 
-void GetVertexAttribPointerv(GLuint index, GLenum pname, void** pointer);
+virtual void GetProgramiv(
+    GLuint program, GLenum pname, GLint* params) OVERRIDE;
 
-void Hint(GLenum target, GLenum mode) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glHint(" << GLES2Util::GetStringHintTarget(target) << ", " << GLES2Util::GetStringHintMode(mode) << ")");  // NOLINT
-  helper_->Hint(target, mode);
-}
+virtual void GetProgramInfoLog(
+    GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) OVERRIDE;
 
-GLboolean IsBuffer(GLuint buffer) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsBuffer(" << buffer << ")");
-  typedef IsBuffer::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return GL_FALSE;
-  }
-  *result = 0;
-  helper_->IsBuffer(buffer, GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  GPU_CLIENT_LOG("returned " << *result);
-  return *result;
-}
+virtual void GetRenderbufferParameteriv(
+    GLenum target, GLenum pname, GLint* params) OVERRIDE;
 
-GLboolean IsEnabled(GLenum cap);
+virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) OVERRIDE;
 
-GLboolean IsFramebuffer(GLuint framebuffer) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsFramebuffer(" << framebuffer << ")");  // NOLINT
-  typedef IsFramebuffer::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return GL_FALSE;
-  }
-  *result = 0;
-  helper_->IsFramebuffer(framebuffer, GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  GPU_CLIENT_LOG("returned " << *result);
-  return *result;
-}
+virtual void GetShaderInfoLog(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) OVERRIDE;
 
-GLboolean IsProgram(GLuint program) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsProgram(" << program << ")");
-  typedef IsProgram::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return GL_FALSE;
-  }
-  *result = 0;
-  helper_->IsProgram(program, GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  GPU_CLIENT_LOG("returned " << *result);
-  return *result;
-}
+virtual void GetShaderPrecisionFormat(
+    GLenum shadertype, GLenum precisiontype, GLint* range,
+    GLint* precision) OVERRIDE;
 
-GLboolean IsRenderbuffer(GLuint renderbuffer) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsRenderbuffer(" << renderbuffer << ")");  // NOLINT
-  typedef IsRenderbuffer::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return GL_FALSE;
-  }
-  *result = 0;
-  helper_->IsRenderbuffer(
-      renderbuffer, GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  GPU_CLIENT_LOG("returned " << *result);
-  return *result;
-}
+virtual void GetShaderSource(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) OVERRIDE;
 
-GLboolean IsShader(GLuint shader) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsShader(" << shader << ")");
-  typedef IsShader::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return GL_FALSE;
-  }
-  *result = 0;
-  helper_->IsShader(shader, GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  GPU_CLIENT_LOG("returned " << *result);
-  return *result;
-}
+virtual const GLubyte* GetString(GLenum name) OVERRIDE;
 
-GLboolean IsTexture(GLuint texture) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsTexture(" << texture << ")");
-  typedef IsTexture::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return GL_FALSE;
-  }
-  *result = 0;
-  helper_->IsTexture(texture, GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  GPU_CLIENT_LOG("returned " << *result);
-  return *result;
-}
+virtual void GetTexParameterfv(
+    GLenum target, GLenum pname, GLfloat* params) OVERRIDE;
 
-void LineWidth(GLfloat width) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLineWidth(" << width << ")");
-  helper_->LineWidth(width);
-}
+virtual void GetTexParameteriv(
+    GLenum target, GLenum pname, GLint* params) OVERRIDE;
 
-void LinkProgram(GLuint program);
+virtual void GetUniformfv(
+    GLuint program, GLint location, GLfloat* params) OVERRIDE;
 
-void PixelStorei(GLenum pname, GLint param);
+virtual void GetUniformiv(
+    GLuint program, GLint location, GLint* params) OVERRIDE;
 
-void PolygonOffset(GLfloat factor, GLfloat units) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPolygonOffset(" << factor << ", " << units << ")");  // NOLINT
-  helper_->PolygonOffset(factor, units);
-}
+virtual GLint GetUniformLocation(GLuint program, const char* name) OVERRIDE;
 
-void ReadPixels(
+virtual void GetVertexAttribPointerv(
+    GLuint index, GLenum pname, void** pointer) OVERRIDE;
+
+virtual void Hint(GLenum target, GLenum mode) OVERRIDE;
+
+virtual GLboolean IsBuffer(GLuint buffer) OVERRIDE;
+
+virtual GLboolean IsEnabled(GLenum cap) OVERRIDE;
+
+virtual GLboolean IsFramebuffer(GLuint framebuffer) OVERRIDE;
+
+virtual GLboolean IsProgram(GLuint program) OVERRIDE;
+
+virtual GLboolean IsRenderbuffer(GLuint renderbuffer) OVERRIDE;
+
+virtual GLboolean IsShader(GLuint shader) OVERRIDE;
+
+virtual GLboolean IsTexture(GLuint texture) OVERRIDE;
+
+virtual void LineWidth(GLfloat width) OVERRIDE;
+
+virtual void LinkProgram(GLuint program) OVERRIDE;
+
+virtual void PixelStorei(GLenum pname, GLint param) OVERRIDE;
+
+virtual void PolygonOffset(GLfloat factor, GLfloat units) OVERRIDE;
+
+virtual void ReadPixels(
     GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
-    void* pixels);
+    void* pixels) OVERRIDE;
 
-void ReleaseShaderCompiler() {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glReleaseShaderCompiler(" << ")");
-  helper_->ReleaseShaderCompiler();
-}
+virtual void ReleaseShaderCompiler() OVERRIDE;
 
-void RenderbufferStorage(
-    GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glRenderbufferStorage(" << GLES2Util::GetStringRenderBufferTarget(target) << ", " << GLES2Util::GetStringRenderBufferFormat(internalformat) << ", " << width << ", " << height << ")");  // NOLINT
-  if (width < 0) {
-    SetGLError(GL_INVALID_VALUE, "glRenderbufferStorage", "width < 0");
-    return;
-  }
-  if (height < 0) {
-    SetGLError(GL_INVALID_VALUE, "glRenderbufferStorage", "height < 0");
-    return;
-  }
-  helper_->RenderbufferStorage(target, internalformat, width, height);
-}
+virtual void RenderbufferStorage(
+    GLenum target, GLenum internalformat, GLsizei width,
+    GLsizei height) OVERRIDE;
 
-void SampleCoverage(GLclampf value, GLboolean invert) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSampleCoverage(" << value << ", " << GLES2Util::GetStringBool(invert) << ")");  // NOLINT
-  helper_->SampleCoverage(value, invert);
-}
+virtual void SampleCoverage(GLclampf value, GLboolean invert) OVERRIDE;
 
-void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glScissor(" << x << ", " << y << ", " << width << ", " << height << ")");  // NOLINT
-  if (width < 0) {
-    SetGLError(GL_INVALID_VALUE, "glScissor", "width < 0");
-    return;
-  }
-  if (height < 0) {
-    SetGLError(GL_INVALID_VALUE, "glScissor", "height < 0");
-    return;
-  }
-  helper_->Scissor(x, y, width, height);
-}
+virtual void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) OVERRIDE;
 
-void ShaderBinary(
+virtual void ShaderBinary(
     GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary,
-    GLsizei length);
+    GLsizei length) OVERRIDE;
 
-void ShaderSource(
-    GLuint shader, GLsizei count, const char** str, const GLint* length);
+virtual void ShaderSource(
+    GLuint shader, GLsizei count, const char** str,
+    const GLint* length) OVERRIDE;
 
-void StencilFunc(GLenum func, GLint ref, GLuint mask) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilFunc(" << GLES2Util::GetStringCmpFunction(func) << ", " << ref << ", " << mask << ")");  // NOLINT
-  helper_->StencilFunc(func, ref, mask);
-}
+virtual void StencilFunc(GLenum func, GLint ref, GLuint mask) OVERRIDE;
 
-void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilFuncSeparate(" << GLES2Util::GetStringFaceType(face) << ", " << GLES2Util::GetStringCmpFunction(func) << ", " << ref << ", " << mask << ")");  // NOLINT
-  helper_->StencilFuncSeparate(face, func, ref, mask);
-}
+virtual void StencilFuncSeparate(
+    GLenum face, GLenum func, GLint ref, GLuint mask) OVERRIDE;
 
-void StencilMask(GLuint mask) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilMask(" << mask << ")");
-  helper_->StencilMask(mask);
-}
+virtual void StencilMask(GLuint mask) OVERRIDE;
 
-void StencilMaskSeparate(GLenum face, GLuint mask) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilMaskSeparate(" << GLES2Util::GetStringFaceType(face) << ", " << mask << ")");  // NOLINT
-  helper_->StencilMaskSeparate(face, mask);
-}
+virtual void StencilMaskSeparate(GLenum face, GLuint mask) OVERRIDE;
 
-void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilOp(" << GLES2Util::GetStringStencilOp(fail) << ", " << GLES2Util::GetStringStencilOp(zfail) << ", " << GLES2Util::GetStringStencilOp(zpass) << ")");  // NOLINT
-  helper_->StencilOp(fail, zfail, zpass);
-}
+virtual void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) OVERRIDE;
 
-void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilOpSeparate(" << GLES2Util::GetStringFaceType(face) << ", " << GLES2Util::GetStringStencilOp(fail) << ", " << GLES2Util::GetStringStencilOp(zfail) << ", " << GLES2Util::GetStringStencilOp(zpass) << ")");  // NOLINT
-  helper_->StencilOpSeparate(face, fail, zfail, zpass);
-}
+virtual void StencilOpSeparate(
+    GLenum face, GLenum fail, GLenum zfail, GLenum zpass) OVERRIDE;
 
-void TexImage2D(
+virtual void TexImage2D(
     GLenum target, GLint level, GLint internalformat, GLsizei width,
     GLsizei height, GLint border, GLenum format, GLenum type,
-    const void* pixels);
+    const void* pixels) OVERRIDE;
 
-void TexParameterf(GLenum target, GLenum pname, GLfloat param) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexParameterf(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << param << ")");  // NOLINT
-  helper_->TexParameterf(target, pname, param);
-}
+virtual void TexParameterf(
+    GLenum target, GLenum pname, GLfloat param) OVERRIDE;
 
-void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexParameterfv(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  GPU_CLIENT_LOG("values: " << params[0]);
-  helper_->TexParameterfvImmediate(target, pname, params);
-}
+virtual void TexParameterfv(
+    GLenum target, GLenum pname, const GLfloat* params) OVERRIDE;
 
-void TexParameteri(GLenum target, GLenum pname, GLint param) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexParameteri(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << param << ")");  // NOLINT
-  helper_->TexParameteri(target, pname, param);
-}
+virtual void TexParameteri(GLenum target, GLenum pname, GLint param) OVERRIDE;
 
-void TexParameteriv(GLenum target, GLenum pname, const GLint* params) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexParameteriv(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
-  GPU_CLIENT_LOG("values: " << params[0]);
-  helper_->TexParameterivImmediate(target, pname, params);
-}
+virtual void TexParameteriv(
+    GLenum target, GLenum pname, const GLint* params) OVERRIDE;
 
-void TexSubImage2D(
+virtual void TexSubImage2D(
     GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
-    GLsizei height, GLenum format, GLenum type, const void* pixels);
+    GLsizei height, GLenum format, GLenum type, const void* pixels) OVERRIDE;
 
-void Uniform1f(GLint location, GLfloat x) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1f(" << location << ", " << x << ")");  // NOLINT
-  helper_->Uniform1f(location, x);
-}
+virtual void Uniform1f(GLint location, GLfloat x) OVERRIDE;
 
-void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1fv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 1]);
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniform1fv", "count < 0");
-    return;
-  }
-  helper_->Uniform1fvImmediate(location, count, v);
-}
+virtual void Uniform1fv(
+    GLint location, GLsizei count, const GLfloat* v) OVERRIDE;
 
-void Uniform1i(GLint location, GLint x) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1i(" << location << ", " << x << ")");  // NOLINT
-  helper_->Uniform1i(location, x);
-}
+virtual void Uniform1i(GLint location, GLint x) OVERRIDE;
 
-void Uniform1iv(GLint location, GLsizei count, const GLint* v) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1iv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 1]);
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniform1iv", "count < 0");
-    return;
-  }
-  helper_->Uniform1ivImmediate(location, count, v);
-}
+virtual void Uniform1iv(
+    GLint location, GLsizei count, const GLint* v) OVERRIDE;
 
-void Uniform2f(GLint location, GLfloat x, GLfloat y) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2f(" << location << ", " << x << ", " << y << ")");  // NOLINT
-  helper_->Uniform2f(location, x, y);
-}
+virtual void Uniform2f(GLint location, GLfloat x, GLfloat y) OVERRIDE;
 
-void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2fv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 2] << ", " << v[1 + i * 2]);  // NOLINT
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniform2fv", "count < 0");
-    return;
-  }
-  helper_->Uniform2fvImmediate(location, count, v);
-}
+virtual void Uniform2fv(
+    GLint location, GLsizei count, const GLfloat* v) OVERRIDE;
 
-void Uniform2i(GLint location, GLint x, GLint y) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2i(" << location << ", " << x << ", " << y << ")");  // NOLINT
-  helper_->Uniform2i(location, x, y);
-}
+virtual void Uniform2i(GLint location, GLint x, GLint y) OVERRIDE;
 
-void Uniform2iv(GLint location, GLsizei count, const GLint* v) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2iv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 2] << ", " << v[1 + i * 2]);  // NOLINT
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniform2iv", "count < 0");
-    return;
-  }
-  helper_->Uniform2ivImmediate(location, count, v);
-}
+virtual void Uniform2iv(
+    GLint location, GLsizei count, const GLint* v) OVERRIDE;
 
-void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3f(" << location << ", " << x << ", " << y << ", " << z << ")");  // NOLINT
-  helper_->Uniform3f(location, x, y, z);
-}
+virtual void Uniform3f(
+    GLint location, GLfloat x, GLfloat y, GLfloat z) OVERRIDE;
 
-void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3fv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 3] << ", " << v[1 + i * 3] << ", " << v[2 + i * 3]);  // NOLINT
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniform3fv", "count < 0");
-    return;
-  }
-  helper_->Uniform3fvImmediate(location, count, v);
-}
+virtual void Uniform3fv(
+    GLint location, GLsizei count, const GLfloat* v) OVERRIDE;
 
-void Uniform3i(GLint location, GLint x, GLint y, GLint z) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3i(" << location << ", " << x << ", " << y << ", " << z << ")");  // NOLINT
-  helper_->Uniform3i(location, x, y, z);
-}
+virtual void Uniform3i(GLint location, GLint x, GLint y, GLint z) OVERRIDE;
 
-void Uniform3iv(GLint location, GLsizei count, const GLint* v) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3iv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 3] << ", " << v[1 + i * 3] << ", " << v[2 + i * 3]);  // NOLINT
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniform3iv", "count < 0");
-    return;
-  }
-  helper_->Uniform3ivImmediate(location, count, v);
-}
+virtual void Uniform3iv(
+    GLint location, GLsizei count, const GLint* v) OVERRIDE;
 
-void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4f(" << location << ", " << x << ", " << y << ", " << z << ", " << w << ")");  // NOLINT
-  helper_->Uniform4f(location, x, y, z, w);
-}
+virtual void Uniform4f(
+    GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) OVERRIDE;
 
-void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4fv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 4] << ", " << v[1 + i * 4] << ", " << v[2 + i * 4] << ", " << v[3 + i * 4]);  // NOLINT
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniform4fv", "count < 0");
-    return;
-  }
-  helper_->Uniform4fvImmediate(location, count, v);
-}
+virtual void Uniform4fv(
+    GLint location, GLsizei count, const GLfloat* v) OVERRIDE;
 
-void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4i(" << location << ", " << x << ", " << y << ", " << z << ", " << w << ")");  // NOLINT
-  helper_->Uniform4i(location, x, y, z, w);
-}
+virtual void Uniform4i(
+    GLint location, GLint x, GLint y, GLint z, GLint w) OVERRIDE;
 
-void Uniform4iv(GLint location, GLsizei count, const GLint* v) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4iv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 4] << ", " << v[1 + i * 4] << ", " << v[2 + i * 4] << ", " << v[3 + i * 4]);  // NOLINT
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniform4iv", "count < 0");
-    return;
-  }
-  helper_->Uniform4ivImmediate(location, count, v);
-}
+virtual void Uniform4iv(
+    GLint location, GLsizei count, const GLint* v) OVERRIDE;
 
-void UniformMatrix2fv(
-    GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix2fv(" << location << ", " << count << ", " << GLES2Util::GetStringBool(transpose) << ", " << static_cast<const void*>(value) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << value[0 + i * 4] << ", " << value[1 + i * 4] << ", " << value[2 + i * 4] << ", " << value[3 + i * 4]);  // NOLINT
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniformMatrix2fv", "count < 0");
-    return;
-  }
-  helper_->UniformMatrix2fvImmediate(location, count, transpose, value);
-}
+virtual void UniformMatrix2fv(
+    GLint location, GLsizei count, GLboolean transpose,
+    const GLfloat* value) OVERRIDE;
 
-void UniformMatrix3fv(
-    GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix3fv(" << location << ", " << count << ", " << GLES2Util::GetStringBool(transpose) << ", " << static_cast<const void*>(value) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << value[0 + i * 9] << ", " << value[1 + i * 9] << ", " << value[2 + i * 9] << ", " << value[3 + i * 9] << ", " << value[4 + i * 9] << ", " << value[5 + i * 9] << ", " << value[6 + i * 9] << ", " << value[7 + i * 9] << ", " << value[8 + i * 9]);  // NOLINT
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniformMatrix3fv", "count < 0");
-    return;
-  }
-  helper_->UniformMatrix3fvImmediate(location, count, transpose, value);
-}
+virtual void UniformMatrix3fv(
+    GLint location, GLsizei count, GLboolean transpose,
+    const GLfloat* value) OVERRIDE;
 
-void UniformMatrix4fv(
-    GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix4fv(" << location << ", " << count << ", " << GLES2Util::GetStringBool(transpose) << ", " << static_cast<const void*>(value) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < count; ++i) {
-       GPU_CLIENT_LOG("  " << i << ": " << value[0 + i * 16] << ", " << value[1 + i * 16] << ", " << value[2 + i * 16] << ", " << value[3 + i * 16] << ", " << value[4 + i * 16] << ", " << value[5 + i * 16] << ", " << value[6 + i * 16] << ", " << value[7 + i * 16] << ", " << value[8 + i * 16] << ", " << value[9 + i * 16] << ", " << value[10 + i * 16] << ", " << value[11 + i * 16] << ", " << value[12 + i * 16] << ", " << value[13 + i * 16] << ", " << value[14 + i * 16] << ", " << value[15 + i * 16]);  // NOLINT
-    }
-  });
-  if (count < 0) {
-    SetGLError(GL_INVALID_VALUE, "glUniformMatrix4fv", "count < 0");
-    return;
-  }
-  helper_->UniformMatrix4fvImmediate(location, count, transpose, value);
-}
+virtual void UniformMatrix4fv(
+    GLint location, GLsizei count, GLboolean transpose,
+    const GLfloat* value) OVERRIDE;
 
-void UseProgram(GLuint program) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUseProgram(" << program << ")");
-  helper_->UseProgram(program);
-}
+virtual void UseProgram(GLuint program) OVERRIDE;
 
-void ValidateProgram(GLuint program) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glValidateProgram(" << program << ")");  // NOLINT
-  helper_->ValidateProgram(program);
-}
+virtual void ValidateProgram(GLuint program) OVERRIDE;
 
-void VertexAttrib1f(GLuint indx, GLfloat x) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib1f(" << indx << ", " << x << ")");  // NOLINT
-  helper_->VertexAttrib1f(indx, x);
-}
+virtual void VertexAttrib1f(GLuint indx, GLfloat x) OVERRIDE;
 
-void VertexAttrib1fv(GLuint indx, const GLfloat* values) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib1fv(" << indx << ", " << static_cast<const void*>(values) << ")");  // NOLINT
-  GPU_CLIENT_LOG("values: " << values[0]);
-  helper_->VertexAttrib1fvImmediate(indx, values);
-}
+virtual void VertexAttrib1fv(GLuint indx, const GLfloat* values) OVERRIDE;
 
-void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib2f(" << indx << ", " << x << ", " << y << ")");  // NOLINT
-  helper_->VertexAttrib2f(indx, x, y);
-}
+virtual void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) OVERRIDE;
 
-void VertexAttrib2fv(GLuint indx, const GLfloat* values) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib2fv(" << indx << ", " << static_cast<const void*>(values) << ")");  // NOLINT
-  GPU_CLIENT_LOG("values: " << values[0] << ", " << values[1]);
-  helper_->VertexAttrib2fvImmediate(indx, values);
-}
+virtual void VertexAttrib2fv(GLuint indx, const GLfloat* values) OVERRIDE;
 
-void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib3f(" << indx << ", " << x << ", " << y << ", " << z << ")");  // NOLINT
-  helper_->VertexAttrib3f(indx, x, y, z);
-}
+virtual void VertexAttrib3f(
+    GLuint indx, GLfloat x, GLfloat y, GLfloat z) OVERRIDE;
 
-void VertexAttrib3fv(GLuint indx, const GLfloat* values) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib3fv(" << indx << ", " << static_cast<const void*>(values) << ")");  // NOLINT
-  GPU_CLIENT_LOG("values: " << values[0] << ", " << values[1] << ", " << values[2]);  // NOLINT
-  helper_->VertexAttrib3fvImmediate(indx, values);
-}
+virtual void VertexAttrib3fv(GLuint indx, const GLfloat* values) OVERRIDE;
 
-void VertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib4f(" << indx << ", " << x << ", " << y << ", " << z << ", " << w << ")");  // NOLINT
-  helper_->VertexAttrib4f(indx, x, y, z, w);
-}
+virtual void VertexAttrib4f(
+    GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) OVERRIDE;
 
-void VertexAttrib4fv(GLuint indx, const GLfloat* values) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib4fv(" << indx << ", " << static_cast<const void*>(values) << ")");  // NOLINT
-  GPU_CLIENT_LOG("values: " << values[0] << ", " << values[1] << ", " << values[2] << ", " << values[3]);  // NOLINT
-  helper_->VertexAttrib4fvImmediate(indx, values);
-}
+virtual void VertexAttrib4fv(GLuint indx, const GLfloat* values) OVERRIDE;
 
-void VertexAttribPointer(
+virtual void VertexAttribPointer(
     GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
-    const void* ptr);
+    const void* ptr) OVERRIDE;
 
-void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glViewport(" << x << ", " << y << ", " << width << ", " << height << ")");  // NOLINT
-  if (width < 0) {
-    SetGLError(GL_INVALID_VALUE, "glViewport", "width < 0");
-    return;
-  }
-  if (height < 0) {
-    SetGLError(GL_INVALID_VALUE, "glViewport", "height < 0");
-    return;
-  }
-  helper_->Viewport(x, y, width, height);
-}
+virtual void Viewport(
+    GLint x, GLint y, GLsizei width, GLsizei height) OVERRIDE;
 
-void BlitFramebufferEXT(
+virtual void BlitFramebufferEXT(
     GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
-    GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlitFramebufferEXT(" << srcX0 << ", " << srcY0 << ", " << srcX1 << ", " << srcY1 << ", " << dstX0 << ", " << dstY0 << ", " << dstX1 << ", " << dstY1 << ", " << mask << ", " << GLES2Util::GetStringBlitFilter(filter) << ")");  // NOLINT
-  helper_->BlitFramebufferEXT(
-      srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
-}
+    GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask,
+    GLenum filter) OVERRIDE;
 
-void RenderbufferStorageMultisampleEXT(
+virtual void RenderbufferStorageMultisampleEXT(
     GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
-    GLsizei height) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glRenderbufferStorageMultisampleEXT(" << GLES2Util::GetStringRenderBufferTarget(target) << ", " << samples << ", " << GLES2Util::GetStringRenderBufferFormat(internalformat) << ", " << width << ", " << height << ")");  // NOLINT
-  if (samples < 0) {
-    SetGLError(
-        GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "samples < 0");
-    return;
-  }
-  if (width < 0) {
-    SetGLError(
-        GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "width < 0");
-    return;
-  }
-  if (height < 0) {
-    SetGLError(
-        GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "height < 0");
-    return;
-  }
-  helper_->RenderbufferStorageMultisampleEXT(
-      target, samples, internalformat, width, height);
-}
+    GLsizei height) OVERRIDE;
 
-void TexStorage2DEXT(
+virtual void TexStorage2DEXT(
     GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width,
-    GLsizei height) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexStorage2DEXT(" << GLES2Util::GetStringTextureTarget(target) << ", " << levels << ", " << GLES2Util::GetStringTextureInternalFormatStorage(internalFormat) << ", " << width << ", " << height << ")");  // NOLINT
-  if (levels < 0) {
-    SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT", "levels < 0");
-    return;
-  }
-  if (width < 0) {
-    SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT", "width < 0");
-    return;
-  }
-  if (height < 0) {
-    SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT", "height < 0");
-    return;
-  }
-  helper_->TexStorage2DEXT(target, levels, internalFormat, width, height);
-}
+    GLsizei height) OVERRIDE;
 
-void GenQueriesEXT(GLsizei n, GLuint* queries) {
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenQueriesEXT(" << n << ", " << static_cast<const void*>(queries) << ")");  // NOLINT
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glGenQueriesEXT", "n < 0");
-    return;
-  }
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GetIdHandler(id_namespaces::kQueries)->
-      MakeIds(this, 0, n, queries);
-  helper_->GenQueriesEXTImmediate(n, queries);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << queries[i]);
-    }
-  });
-}
+virtual void GenQueriesEXT(GLsizei n, GLuint* queries) OVERRIDE;
 
-void DeleteQueriesEXT(GLsizei n, const GLuint* queries) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteQueriesEXT(" << n << ", " << static_cast<const void*>(queries) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << queries[i]);
-    }
-  });
-  GPU_CLIENT_DCHECK_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_DCHECK(queries[i] != 0);
-    }
-  });
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glDeleteQueriesEXT", "n < 0");
-    return;
-  }
-  DeleteQueriesEXTHelper(n, queries);
-}
+virtual void DeleteQueriesEXT(GLsizei n, const GLuint* queries) OVERRIDE;
 
-GLboolean IsQueryEXT(GLuint id);
+virtual GLboolean IsQueryEXT(GLuint id) OVERRIDE;
 
-void BeginQueryEXT(GLenum target, GLuint id);
+virtual void BeginQueryEXT(GLenum target, GLuint id) OVERRIDE;
 
-void EndQueryEXT(GLenum target);
+virtual void EndQueryEXT(GLenum target) OVERRIDE;
 
-void GetQueryivEXT(GLenum target, GLenum pname, GLint* params);
+virtual void GetQueryivEXT(
+    GLenum target, GLenum pname, GLint* params) OVERRIDE;
 
-void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params);
+virtual void GetQueryObjectuivEXT(
+    GLuint id, GLenum pname, GLuint* params) OVERRIDE;
 
-void InsertEventMarkerEXT(GLsizei length, const GLchar* marker);
+virtual void InsertEventMarkerEXT(
+    GLsizei length, const GLchar* marker) OVERRIDE;
 
-void PushGroupMarkerEXT(GLsizei length, const GLchar* marker);
+virtual void PushGroupMarkerEXT(GLsizei length, const GLchar* marker) OVERRIDE;
 
-void PopGroupMarkerEXT();
+virtual void PopGroupMarkerEXT() OVERRIDE;
 
-void GenVertexArraysOES(GLsizei n, GLuint* arrays) {
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenVertexArraysOES(" << n << ", " << static_cast<const void*>(arrays) << ")");  // NOLINT
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glGenVertexArraysOES", "n < 0");
-    return;
-  }
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GetIdHandler(id_namespaces::kVertexArrays)->
-      MakeIds(this, 0, n, arrays);
-  helper_->GenVertexArraysOESImmediate(n, arrays);
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << arrays[i]);
-    }
-  });
-}
+virtual void GenVertexArraysOES(GLsizei n, GLuint* arrays) OVERRIDE;
 
-void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteVertexArraysOES(" << n << ", " << static_cast<const void*>(arrays) << ")");  // NOLINT
-  GPU_CLIENT_LOG_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_CLIENT_LOG("  " << i << ": " << arrays[i]);
-    }
-  });
-  GPU_CLIENT_DCHECK_CODE_BLOCK({
-    for (GLsizei i = 0; i < n; ++i) {
-      GPU_DCHECK(arrays[i] != 0);
-    }
-  });
-  if (n < 0) {
-    SetGLError(GL_INVALID_VALUE, "glDeleteVertexArraysOES", "n < 0");
-    return;
-  }
-  DeleteVertexArraysOESHelper(n, arrays);
-}
+virtual void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) OVERRIDE;
 
-GLboolean IsVertexArrayOES(GLuint array) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsVertexArrayOES(" << array << ")");  // NOLINT
-  typedef IsVertexArrayOES::Result Result;
-  Result* result = GetResultAs<Result*>();
-  if (!result) {
-    return GL_FALSE;
-  }
-  *result = 0;
-  helper_->IsVertexArrayOES(array, GetResultShmId(), GetResultShmOffset());
-  WaitForCmd();
-  GPU_CLIENT_LOG("returned " << *result);
-  return *result;
-}
+virtual GLboolean IsVertexArrayOES(GLuint array) OVERRIDE;
 
-void BindVertexArrayOES(GLuint array) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindVertexArrayOES(" << array << ")");  // NOLINT
-  if (IsVertexArrayReservedId(array)) {
-    SetGLError(
-        GL_INVALID_OPERATION, "BindVertexArrayOES", "array reserved id");
-    return;
-  }
-  BindVertexArrayHelper(array);
-  helper_->BindVertexArrayOES(array);
-}
+virtual void BindVertexArrayOES(GLuint array) OVERRIDE;
 
-void SwapBuffers();
+virtual void SwapBuffers() OVERRIDE;
 
-GLuint GetMaxValueInBufferCHROMIUM(
-    GLuint buffer_id, GLsizei count, GLenum type, GLuint offset);
+virtual GLuint GetMaxValueInBufferCHROMIUM(
+    GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) OVERRIDE;
 
-void GenSharedIdsCHROMIUM(
-    GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids);
+virtual void GenSharedIdsCHROMIUM(
+    GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE;
 
-void DeleteSharedIdsCHROMIUM(
-    GLuint namespace_id, GLsizei n, const GLuint* ids);
+virtual void DeleteSharedIdsCHROMIUM(
+    GLuint namespace_id, GLsizei n, const GLuint* ids) OVERRIDE;
 
-void RegisterSharedIdsCHROMIUM(
-    GLuint namespace_id, GLsizei n, const GLuint* ids);
+virtual void RegisterSharedIdsCHROMIUM(
+    GLuint namespace_id, GLsizei n, const GLuint* ids) OVERRIDE;
 
-GLboolean EnableFeatureCHROMIUM(const char* feature);
+virtual GLboolean EnableFeatureCHROMIUM(const char* feature) OVERRIDE;
 
-void* MapBufferSubDataCHROMIUM(
-    GLuint target, GLintptr offset, GLsizeiptr size, GLenum access);
+virtual void* MapBufferSubDataCHROMIUM(
+    GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) OVERRIDE;
 
-void UnmapBufferSubDataCHROMIUM(const void* mem);
+virtual void UnmapBufferSubDataCHROMIUM(const void* mem) OVERRIDE;
 
-void* MapTexSubImage2DCHROMIUM(
+virtual void* MapTexSubImage2DCHROMIUM(
     GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
-    GLsizei height, GLenum format, GLenum type, GLenum access);
+    GLsizei height, GLenum format, GLenum type, GLenum access) OVERRIDE;
 
-void UnmapTexSubImage2DCHROMIUM(const void* mem);
+virtual void UnmapTexSubImage2DCHROMIUM(const void* mem) OVERRIDE;
 
-void ResizeCHROMIUM(GLuint width, GLuint height);
+virtual void ResizeCHROMIUM(GLuint width, GLuint height) OVERRIDE;
 
-const GLchar* GetRequestableExtensionsCHROMIUM();
+virtual const GLchar* GetRequestableExtensionsCHROMIUM() OVERRIDE;
 
-void RequestExtensionCHROMIUM(const char* extension);
+virtual void RequestExtensionCHROMIUM(const char* extension) OVERRIDE;
 
-void RateLimitOffscreenContextCHROMIUM();
+virtual void RateLimitOffscreenContextCHROMIUM() OVERRIDE;
 
-void GetMultipleIntegervCHROMIUM(
-    const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size);
+virtual void GetMultipleIntegervCHROMIUM(
+    const GLenum* pnames, GLuint count, GLint* results,
+    GLsizeiptr size) OVERRIDE;
 
-void GetProgramInfoCHROMIUM(
-    GLuint program, GLsizei bufsize, GLsizei* size, void* info);
+virtual void GetProgramInfoCHROMIUM(
+    GLuint program, GLsizei bufsize, GLsizei* size, void* info) OVERRIDE;
 
-GLuint CreateStreamTextureCHROMIUM(GLuint texture);
+virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) OVERRIDE;
 
-void DestroyStreamTextureCHROMIUM(GLuint texture);
+virtual void DestroyStreamTextureCHROMIUM(GLuint texture) OVERRIDE;
 
-void GetTranslatedShaderSourceANGLE(
-    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(GLsizei, length);
-  GPU_CLIENT_LOG("[" << GetLogPrefix()
-      << "] glGetTranslatedShaderSourceANGLE" << "("
-      << shader << ", "
-      << bufsize << ", "
-      << static_cast<void*>(length) << ", "
-      << static_cast<void*>(source) << ")");
-  helper_->SetBucketSize(kResultBucketId, 0);
-  helper_->GetTranslatedShaderSourceANGLE(shader, kResultBucketId);
-  std::string str;
-  GLsizei max_size = 0;
-  if (GetBucketAsString(kResultBucketId, &str)) {
-    if (bufsize > 0) {
-      max_size =
-          std::min(static_cast<size_t>(bufsize) - 1, str.size());
-      memcpy(source, str.c_str(), max_size);
-      source[max_size] = '\0';
-      GPU_CLIENT_LOG("------\n" << source << "\n------");
-    }
-  }
-  if (length != NULL) {
-    *length = max_size;
-  }
-}
-void PostSubBufferCHROMIUM(GLint x, GLint y, GLint width, GLint height);
+virtual void GetTranslatedShaderSourceANGLE(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) OVERRIDE;
 
-void TexImageIOSurface2DCHROMIUM(
+virtual void PostSubBufferCHROMIUM(
+    GLint x, GLint y, GLint width, GLint height) OVERRIDE;
+
+virtual void TexImageIOSurface2DCHROMIUM(
     GLenum target, GLsizei width, GLsizei height, GLuint ioSurfaceId,
-    GLuint plane) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImageIOSurface2DCHROMIUM(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << width << ", " << height << ", " << ioSurfaceId << ", " << plane << ")");  // NOLINT
-  if (width < 0) {
-    SetGLError(GL_INVALID_VALUE, "glTexImageIOSurface2DCHROMIUM", "width < 0");
-    return;
-  }
-  if (height < 0) {
-    SetGLError(
-        GL_INVALID_VALUE, "glTexImageIOSurface2DCHROMIUM", "height < 0");
-    return;
-  }
-  helper_->TexImageIOSurface2DCHROMIUM(
-      target, width, height, ioSurfaceId, plane);
-}
+    GLuint plane) OVERRIDE;
 
-void CopyTextureCHROMIUM(
+virtual void CopyTextureCHROMIUM(
     GLenum target, GLenum source_id, GLenum dest_id, GLint level,
-    GLint internalformat) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyTextureCHROMIUM(" << GLES2Util::GetStringEnum(target) << ", " << GLES2Util::GetStringEnum(source_id) << ", " << GLES2Util::GetStringEnum(dest_id) << ", " << level << ", " << internalformat << ")");  // NOLINT
-  helper_->CopyTextureCHROMIUM(
-      target, source_id, dest_id, level, internalformat);
-}
+    GLint internalformat) OVERRIDE;
 
-void DrawArraysInstancedANGLE(
-    GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+virtual void DrawArraysInstancedANGLE(
+    GLenum mode, GLint first, GLsizei count, GLsizei primcount) OVERRIDE;
 
-void DrawElementsInstancedANGLE(
+virtual void DrawElementsInstancedANGLE(
     GLenum mode, GLsizei count, GLenum type, const void* indices,
-    GLsizei primcount);
+    GLsizei primcount) OVERRIDE;
 
-void VertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+virtual void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) OVERRIDE;
 
-void GenMailboxCHROMIUM(GLbyte* mailbox);
+virtual void GenMailboxCHROMIUM(GLbyte* mailbox) OVERRIDE;
 
-void ProduceTextureCHROMIUM(GLenum target, const GLbyte* mailbox) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glProduceTextureCHROMIUM(" << GLES2Util::GetStringTextureTarget(target) << ", " << static_cast<const void*>(mailbox) << ")");  // NOLINT
-  GPU_CLIENT_LOG("values: " << mailbox[0] << ", " << mailbox[1] << ", " << mailbox[2] << ", " << mailbox[3] << ", " << mailbox[4] << ", " << mailbox[5] << ", " << mailbox[6] << ", " << mailbox[7] << ", " << mailbox[8] << ", " << mailbox[9] << ", " << mailbox[10] << ", " << mailbox[11] << ", " << mailbox[12] << ", " << mailbox[13] << ", " << mailbox[14] << ", " << mailbox[15] << ", " << mailbox[16] << ", " << mailbox[17] << ", " << mailbox[18] << ", " << mailbox[19] << ", " << mailbox[20] << ", " << mailbox[21] << ", " << mailbox[22] << ", " << mailbox[23] << ", " << mailbox[24] << ", " << mailbox[25] << ", " << mailbox[26] << ", " << mailbox[27] << ", " << mailbox[28] << ", " << mailbox[29] << ", " << mailbox[30] << ", " << mailbox[31] << ", " << mailbox[32] << ", " << mailbox[33] << ", " << mailbox[34] << ", " << mailbox[35] << ", " << mailbox[36] << ", " << mailbox[37] << ", " << mailbox[38] << ", " << mailbox[39] << ", " << mailbox[40] << ", " << mailbox[41] << ", " << mailbox[42] << ", " << mailbox[43] << ", " << mailbox[44] << ", " << mailbox[45] << ", " << mailbox[46] << ", " << mailbox[47] << ", " << mailbox[48] << ", " << mailbox[49] << ", " << mailbox[50] << ", " << mailbox[51] << ", " << mailbox[52] << ", " << mailbox[53] << ", " << mailbox[54] << ", " << mailbox[55] << ", " << mailbox[56] << ", " << mailbox[57] << ", " << mailbox[58] << ", " << mailbox[59] << ", " << mailbox[60] << ", " << mailbox[61] << ", " << mailbox[62] << ", " << mailbox[63]);  // NOLINT
-  helper_->ProduceTextureCHROMIUMImmediate(target, mailbox);
-}
+virtual void ProduceTextureCHROMIUM(
+    GLenum target, const GLbyte* mailbox) OVERRIDE;
 
-void ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) {
-  GPU_CLIENT_SINGLE_THREAD_CHECK();
-  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glConsumeTextureCHROMIUM(" << GLES2Util::GetStringTextureTarget(target) << ", " << static_cast<const void*>(mailbox) << ")");  // NOLINT
-  GPU_CLIENT_LOG("values: " << mailbox[0] << ", " << mailbox[1] << ", " << mailbox[2] << ", " << mailbox[3] << ", " << mailbox[4] << ", " << mailbox[5] << ", " << mailbox[6] << ", " << mailbox[7] << ", " << mailbox[8] << ", " << mailbox[9] << ", " << mailbox[10] << ", " << mailbox[11] << ", " << mailbox[12] << ", " << mailbox[13] << ", " << mailbox[14] << ", " << mailbox[15] << ", " << mailbox[16] << ", " << mailbox[17] << ", " << mailbox[18] << ", " << mailbox[19] << ", " << mailbox[20] << ", " << mailbox[21] << ", " << mailbox[22] << ", " << mailbox[23] << ", " << mailbox[24] << ", " << mailbox[25] << ", " << mailbox[26] << ", " << mailbox[27] << ", " << mailbox[28] << ", " << mailbox[29] << ", " << mailbox[30] << ", " << mailbox[31] << ", " << mailbox[32] << ", " << mailbox[33] << ", " << mailbox[34] << ", " << mailbox[35] << ", " << mailbox[36] << ", " << mailbox[37] << ", " << mailbox[38] << ", " << mailbox[39] << ", " << mailbox[40] << ", " << mailbox[41] << ", " << mailbox[42] << ", " << mailbox[43] << ", " << mailbox[44] << ", " << mailbox[45] << ", " << mailbox[46] << ", " << mailbox[47] << ", " << mailbox[48] << ", " << mailbox[49] << ", " << mailbox[50] << ", " << mailbox[51] << ", " << mailbox[52] << ", " << mailbox[53] << ", " << mailbox[54] << ", " << mailbox[55] << ", " << mailbox[56] << ", " << mailbox[57] << ", " << mailbox[58] << ", " << mailbox[59] << ", " << mailbox[60] << ", " << mailbox[61] << ", " << mailbox[62] << ", " << mailbox[63]);  // NOLINT
-  helper_->ConsumeTextureCHROMIUMImmediate(target, mailbox);
-}
+virtual void ConsumeTextureCHROMIUM(
+    GLenum target, const GLbyte* mailbox) OVERRIDE;
 
-void BindUniformLocationCHROMIUM(
-    GLuint program, GLint location, const char* name);
+virtual void BindUniformLocationCHROMIUM(
+    GLuint program, GLint location, const char* name) OVERRIDE;
 
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
 
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
new file mode 100644
index 0000000..3beca1b1
--- /dev/null
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -0,0 +1,1498 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is auto-generated from
+// gpu/command_buffer/build_gles2_cmd_buffer.py
+// DO NOT EDIT!
+
+// This file is included by gles2_implementation.cc to define the
+// GL api functions.
+#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_IMPL_AUTOGEN_H_
+#define GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_IMPL_AUTOGEN_H_
+
+void GLES2Implementation::AttachShader(GLuint program, GLuint shader) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glAttachShader(" << program << ", " << shader << ")");  // NOLINT
+  helper_->AttachShader(program, shader);
+}
+
+void GLES2Implementation::BindBuffer(GLenum target, GLuint buffer) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindBuffer(" << GLES2Util::GetStringBufferTarget(target) << ", " << buffer << ")");  // NOLINT
+  if (IsBufferReservedId(buffer)) {
+    SetGLError(GL_INVALID_OPERATION, "BindBuffer", "buffer reserved id");
+    return;
+  }
+  BindBufferHelper(target, buffer);
+  helper_->BindBuffer(target, buffer);
+}
+
+void GLES2Implementation::BindFramebuffer(GLenum target, GLuint framebuffer) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindFramebuffer(" << GLES2Util::GetStringFrameBufferTarget(target) << ", " << framebuffer << ")");  // NOLINT
+  if (IsFramebufferReservedId(framebuffer)) {
+    SetGLError(
+        GL_INVALID_OPERATION, "BindFramebuffer", "framebuffer reserved id");
+    return;
+  }
+  BindFramebufferHelper(target, framebuffer);
+  helper_->BindFramebuffer(target, framebuffer);
+}
+
+void GLES2Implementation::BindRenderbuffer(
+    GLenum target, GLuint renderbuffer) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindRenderbuffer(" << GLES2Util::GetStringRenderBufferTarget(target) << ", " << renderbuffer << ")");  // NOLINT
+  if (IsRenderbufferReservedId(renderbuffer)) {
+    SetGLError(
+        GL_INVALID_OPERATION, "BindRenderbuffer", "renderbuffer reserved id");
+    return;
+  }
+  BindRenderbufferHelper(target, renderbuffer);
+  helper_->BindRenderbuffer(target, renderbuffer);
+}
+
+void GLES2Implementation::BindTexture(GLenum target, GLuint texture) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindTexture(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << texture << ")");  // NOLINT
+  if (IsTextureReservedId(texture)) {
+    SetGLError(GL_INVALID_OPERATION, "BindTexture", "texture reserved id");
+    return;
+  }
+  BindTextureHelper(target, texture);
+  helper_->BindTexture(target, texture);
+}
+
+void GLES2Implementation::BlendColor(
+    GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendColor(" << red << ", " << green << ", " << blue << ", " << alpha << ")");  // NOLINT
+  helper_->BlendColor(red, green, blue, alpha);
+}
+
+void GLES2Implementation::BlendEquation(GLenum mode) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendEquation(" << GLES2Util::GetStringEquation(mode) << ")");  // NOLINT
+  helper_->BlendEquation(mode);
+}
+
+void GLES2Implementation::BlendEquationSeparate(
+    GLenum modeRGB, GLenum modeAlpha) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendEquationSeparate(" << GLES2Util::GetStringEquation(modeRGB) << ", " << GLES2Util::GetStringEquation(modeAlpha) << ")");  // NOLINT
+  helper_->BlendEquationSeparate(modeRGB, modeAlpha);
+}
+
+void GLES2Implementation::BlendFunc(GLenum sfactor, GLenum dfactor) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendFunc(" << GLES2Util::GetStringSrcBlendFactor(sfactor) << ", " << GLES2Util::GetStringDstBlendFactor(dfactor) << ")");  // NOLINT
+  helper_->BlendFunc(sfactor, dfactor);
+}
+
+void GLES2Implementation::BlendFuncSeparate(
+    GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlendFuncSeparate(" << GLES2Util::GetStringSrcBlendFactor(srcRGB) << ", " << GLES2Util::GetStringDstBlendFactor(dstRGB) << ", " << GLES2Util::GetStringSrcBlendFactor(srcAlpha) << ", " << GLES2Util::GetStringDstBlendFactor(dstAlpha) << ")");  // NOLINT
+  helper_->BlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+GLenum GLES2Implementation::CheckFramebufferStatus(GLenum target) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCheckFramebufferStatus(" << GLES2Util::GetStringFrameBufferTarget(target) << ")");  // NOLINT
+  typedef CheckFramebufferStatus::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return GL_FRAMEBUFFER_UNSUPPORTED;
+  }
+  *result = 0;
+  helper_->CheckFramebufferStatus(
+      target, GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  GPU_CLIENT_LOG("returned " << *result);
+  return *result;
+}
+
+void GLES2Implementation::ClearColor(
+    GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearColor(" << red << ", " << green << ", " << blue << ", " << alpha << ")");  // NOLINT
+  helper_->ClearColor(red, green, blue, alpha);
+}
+
+void GLES2Implementation::ClearDepthf(GLclampf depth) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearDepthf(" << depth << ")");
+  helper_->ClearDepthf(depth);
+}
+
+void GLES2Implementation::ClearStencil(GLint s) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glClearStencil(" << s << ")");
+  helper_->ClearStencil(s);
+}
+
+void GLES2Implementation::ColorMask(
+    GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glColorMask(" << GLES2Util::GetStringBool(red) << ", " << GLES2Util::GetStringBool(green) << ", " << GLES2Util::GetStringBool(blue) << ", " << GLES2Util::GetStringBool(alpha) << ")");  // NOLINT
+  helper_->ColorMask(red, green, blue, alpha);
+}
+
+void GLES2Implementation::CompileShader(GLuint shader) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCompileShader(" << shader << ")");  // NOLINT
+  helper_->CompileShader(shader);
+}
+
+void GLES2Implementation::CopyTexImage2D(
+    GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
+    GLsizei width, GLsizei height, GLint border) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyTexImage2D(" << GLES2Util::GetStringTextureTarget(target) << ", " << level << ", " << GLES2Util::GetStringTextureInternalFormat(internalformat) << ", " << x << ", " << y << ", " << width << ", " << height << ", " << border << ")");  // NOLINT
+  if (width < 0) {
+    SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "width < 0");
+    return;
+  }
+  if (height < 0) {
+    SetGLError(GL_INVALID_VALUE, "glCopyTexImage2D", "height < 0");
+    return;
+  }
+  helper_->CopyTexImage2D(
+      target, level, internalformat, x, y, width, height, border);
+}
+
+void GLES2Implementation::CopyTexSubImage2D(
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
+    GLsizei width, GLsizei height) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyTexSubImage2D(" << GLES2Util::GetStringTextureTarget(target) << ", " << level << ", " << xoffset << ", " << yoffset << ", " << x << ", " << y << ", " << width << ", " << height << ")");  // NOLINT
+  if (width < 0) {
+    SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D", "width < 0");
+    return;
+  }
+  if (height < 0) {
+    SetGLError(GL_INVALID_VALUE, "glCopyTexSubImage2D", "height < 0");
+    return;
+  }
+  helper_->CopyTexSubImage2D(
+      target, level, xoffset, yoffset, x, y, width, height);
+}
+
+GLuint GLES2Implementation::CreateProgram() {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateProgram(" << ")");
+  GLuint client_id;
+  GetIdHandler(id_namespaces::kProgramsAndShaders)->
+      MakeIds(this, 0, 1, &client_id);
+  helper_->CreateProgram(client_id);
+  GPU_CLIENT_LOG("returned " << client_id);
+  return client_id;
+}
+
+GLuint GLES2Implementation::CreateShader(GLenum type) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCreateShader(" << GLES2Util::GetStringShaderType(type) << ")");  // NOLINT
+  GLuint client_id;
+  GetIdHandler(id_namespaces::kProgramsAndShaders)->
+      MakeIds(this, 0, 1, &client_id);
+  helper_->CreateShader(type, client_id);
+  GPU_CLIENT_LOG("returned " << client_id);
+  return client_id;
+}
+
+void GLES2Implementation::CullFace(GLenum mode) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCullFace(" << GLES2Util::GetStringFaceType(mode) << ")");  // NOLINT
+  helper_->CullFace(mode);
+}
+
+void GLES2Implementation::DeleteBuffers(GLsizei n, const GLuint* buffers) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteBuffers(" << n << ", " << static_cast<const void*>(buffers) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << buffers[i]);
+    }
+  });
+  GPU_CLIENT_DCHECK_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_DCHECK(buffers[i] != 0);
+    }
+  });
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glDeleteBuffers", "n < 0");
+    return;
+  }
+  DeleteBuffersHelper(n, buffers);
+}
+
+void GLES2Implementation::DeleteFramebuffers(
+    GLsizei n, const GLuint* framebuffers) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteFramebuffers(" << n << ", " << static_cast<const void*>(framebuffers) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << framebuffers[i]);
+    }
+  });
+  GPU_CLIENT_DCHECK_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_DCHECK(framebuffers[i] != 0);
+    }
+  });
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glDeleteFramebuffers", "n < 0");
+    return;
+  }
+  DeleteFramebuffersHelper(n, framebuffers);
+}
+
+void GLES2Implementation::DeleteProgram(GLuint program) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteProgram(" << program << ")");  // NOLINT
+  GPU_CLIENT_DCHECK(program != 0);
+  DeleteProgramHelper(program);
+}
+
+void GLES2Implementation::DeleteRenderbuffers(
+    GLsizei n, const GLuint* renderbuffers) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteRenderbuffers(" << n << ", " << static_cast<const void*>(renderbuffers) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << renderbuffers[i]);
+    }
+  });
+  GPU_CLIENT_DCHECK_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_DCHECK(renderbuffers[i] != 0);
+    }
+  });
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glDeleteRenderbuffers", "n < 0");
+    return;
+  }
+  DeleteRenderbuffersHelper(n, renderbuffers);
+}
+
+void GLES2Implementation::DeleteShader(GLuint shader) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteShader(" << shader << ")");
+  GPU_CLIENT_DCHECK(shader != 0);
+  DeleteShaderHelper(shader);
+}
+
+void GLES2Implementation::DeleteTextures(GLsizei n, const GLuint* textures) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteTextures(" << n << ", " << static_cast<const void*>(textures) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << textures[i]);
+    }
+  });
+  GPU_CLIENT_DCHECK_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_DCHECK(textures[i] != 0);
+    }
+  });
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glDeleteTextures", "n < 0");
+    return;
+  }
+  DeleteTexturesHelper(n, textures);
+}
+
+void GLES2Implementation::DepthFunc(GLenum func) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDepthFunc(" << GLES2Util::GetStringCmpFunction(func) << ")");  // NOLINT
+  helper_->DepthFunc(func);
+}
+
+void GLES2Implementation::DepthMask(GLboolean flag) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDepthMask(" << GLES2Util::GetStringBool(flag) << ")");  // NOLINT
+  helper_->DepthMask(flag);
+}
+
+void GLES2Implementation::DepthRangef(GLclampf zNear, GLclampf zFar) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDepthRangef(" << zNear << ", " << zFar << ")");  // NOLINT
+  helper_->DepthRangef(zNear, zFar);
+}
+
+void GLES2Implementation::DetachShader(GLuint program, GLuint shader) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDetachShader(" << program << ", " << shader << ")");  // NOLINT
+  helper_->DetachShader(program, shader);
+}
+
+void GLES2Implementation::FramebufferRenderbuffer(
+    GLenum target, GLenum attachment, GLenum renderbuffertarget,
+    GLuint renderbuffer) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFramebufferRenderbuffer(" << GLES2Util::GetStringFrameBufferTarget(target) << ", " << GLES2Util::GetStringAttachment(attachment) << ", " << GLES2Util::GetStringRenderBufferTarget(renderbuffertarget) << ", " << renderbuffer << ")");  // NOLINT
+  helper_->FramebufferRenderbuffer(
+      target, attachment, renderbuffertarget, renderbuffer);
+}
+
+void GLES2Implementation::FramebufferTexture2D(
+    GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
+    GLint level) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFramebufferTexture2D(" << GLES2Util::GetStringFrameBufferTarget(target) << ", " << GLES2Util::GetStringAttachment(attachment) << ", " << GLES2Util::GetStringTextureTarget(textarget) << ", " << texture << ", " << level << ")");  // NOLINT
+  helper_->FramebufferTexture2D(target, attachment, textarget, texture, level);
+}
+
+void GLES2Implementation::FrontFace(GLenum mode) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glFrontFace(" << GLES2Util::GetStringFaceMode(mode) << ")");  // NOLINT
+  helper_->FrontFace(mode);
+}
+
+void GLES2Implementation::GenBuffers(GLsizei n, GLuint* buffers) {
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenBuffers(" << n << ", " << static_cast<const void*>(buffers) << ")");  // NOLINT
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glGenBuffers", "n < 0");
+    return;
+  }
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GetIdHandler(id_namespaces::kBuffers)->
+      MakeIds(this, 0, n, buffers);
+  helper_->GenBuffersImmediate(n, buffers);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << buffers[i]);
+    }
+  });
+}
+
+void GLES2Implementation::GenerateMipmap(GLenum target) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenerateMipmap(" << GLES2Util::GetStringTextureBindTarget(target) << ")");  // NOLINT
+  helper_->GenerateMipmap(target);
+}
+
+void GLES2Implementation::GenFramebuffers(GLsizei n, GLuint* framebuffers) {
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenFramebuffers(" << n << ", " << static_cast<const void*>(framebuffers) << ")");  // NOLINT
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glGenFramebuffers", "n < 0");
+    return;
+  }
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GetIdHandler(id_namespaces::kFramebuffers)->
+      MakeIds(this, 0, n, framebuffers);
+  helper_->GenFramebuffersImmediate(n, framebuffers);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << framebuffers[i]);
+    }
+  });
+}
+
+void GLES2Implementation::GenRenderbuffers(GLsizei n, GLuint* renderbuffers) {
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenRenderbuffers(" << n << ", " << static_cast<const void*>(renderbuffers) << ")");  // NOLINT
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glGenRenderbuffers", "n < 0");
+    return;
+  }
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GetIdHandler(id_namespaces::kRenderbuffers)->
+      MakeIds(this, 0, n, renderbuffers);
+  helper_->GenRenderbuffersImmediate(n, renderbuffers);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << renderbuffers[i]);
+    }
+  });
+}
+
+void GLES2Implementation::GenTextures(GLsizei n, GLuint* textures) {
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenTextures(" << n << ", " << static_cast<const void*>(textures) << ")");  // NOLINT
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glGenTextures", "n < 0");
+    return;
+  }
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GetIdHandler(id_namespaces::kTextures)->
+      MakeIds(this, 0, n, textures);
+  helper_->GenTexturesImmediate(n, textures);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << textures[i]);
+    }
+  });
+}
+
+void GLES2Implementation::GetBooleanv(GLenum pname, GLboolean* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLboolean, params);
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetBooleanv(" << GLES2Util::GetStringGLState(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetBooleanvHelper(pname, params)) {
+    return;
+  }
+  typedef GetBooleanv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetBooleanv(pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::GetBufferParameteriv(
+    GLenum target, GLenum pname, GLint* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetBufferParameteriv(" << GLES2Util::GetStringBufferTarget(target) << ", " << GLES2Util::GetStringBufferParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetBufferParameterivHelper(target, pname, params)) {
+    return;
+  }
+  typedef GetBufferParameteriv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetBufferParameteriv(target, pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::GetFloatv(GLenum pname, GLfloat* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetFloatv(" << GLES2Util::GetStringGLState(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetFloatvHelper(pname, params)) {
+    return;
+  }
+  typedef GetFloatv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetFloatv(pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::GetFramebufferAttachmentParameteriv(
+    GLenum target, GLenum attachment, GLenum pname, GLint* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetFramebufferAttachmentParameteriv(" << GLES2Util::GetStringFrameBufferTarget(target) << ", " << GLES2Util::GetStringAttachment(attachment) << ", " << GLES2Util::GetStringFrameBufferParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetFramebufferAttachmentParameterivHelper(
+      target, attachment, pname, params)) {
+    return;
+  }
+  typedef GetFramebufferAttachmentParameteriv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetFramebufferAttachmentParameteriv(target, attachment, pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::GetIntegerv(GLenum pname, GLint* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetIntegerv(" << GLES2Util::GetStringGLState(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetIntegervHelper(pname, params)) {
+    return;
+  }
+  typedef GetIntegerv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetIntegerv(pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::GetProgramiv(
+    GLuint program, GLenum pname, GLint* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetProgramiv(" << program << ", " << GLES2Util::GetStringProgramParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetProgramivHelper(program, pname, params)) {
+    return;
+  }
+  typedef GetProgramiv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetProgramiv(program, pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::GetProgramInfoLog(
+    GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(GLsizei, length);
+  GPU_CLIENT_LOG("[" << GetLogPrefix()
+      << "] glGetProgramInfoLog" << "("
+      << program << ", "
+      << bufsize << ", "
+      << static_cast<void*>(length) << ", "
+      << static_cast<void*>(infolog) << ")");
+  helper_->SetBucketSize(kResultBucketId, 0);
+  helper_->GetProgramInfoLog(program, kResultBucketId);
+  std::string str;
+  GLsizei max_size = 0;
+  if (GetBucketAsString(kResultBucketId, &str)) {
+    if (bufsize > 0) {
+      max_size =
+          std::min(static_cast<size_t>(bufsize) - 1, str.size());
+      memcpy(infolog, str.c_str(), max_size);
+      infolog[max_size] = '\0';
+      GPU_CLIENT_LOG("------\n" << infolog << "\n------");
+    }
+  }
+  if (length != NULL) {
+    *length = max_size;
+  }
+}
+void GLES2Implementation::GetRenderbufferParameteriv(
+    GLenum target, GLenum pname, GLint* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetRenderbufferParameteriv(" << GLES2Util::GetStringRenderBufferTarget(target) << ", " << GLES2Util::GetStringRenderBufferParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetRenderbufferParameterivHelper(target, pname, params)) {
+    return;
+  }
+  typedef GetRenderbufferParameteriv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetRenderbufferParameteriv(target, pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::GetShaderiv(
+    GLuint shader, GLenum pname, GLint* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetShaderiv(" << shader << ", " << GLES2Util::GetStringShaderParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetShaderivHelper(shader, pname, params)) {
+    return;
+  }
+  typedef GetShaderiv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetShaderiv(shader, pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::GetShaderInfoLog(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(GLsizei, length);
+  GPU_CLIENT_LOG("[" << GetLogPrefix()
+      << "] glGetShaderInfoLog" << "("
+      << shader << ", "
+      << bufsize << ", "
+      << static_cast<void*>(length) << ", "
+      << static_cast<void*>(infolog) << ")");
+  helper_->SetBucketSize(kResultBucketId, 0);
+  helper_->GetShaderInfoLog(shader, kResultBucketId);
+  std::string str;
+  GLsizei max_size = 0;
+  if (GetBucketAsString(kResultBucketId, &str)) {
+    if (bufsize > 0) {
+      max_size =
+          std::min(static_cast<size_t>(bufsize) - 1, str.size());
+      memcpy(infolog, str.c_str(), max_size);
+      infolog[max_size] = '\0';
+      GPU_CLIENT_LOG("------\n" << infolog << "\n------");
+    }
+  }
+  if (length != NULL) {
+    *length = max_size;
+  }
+}
+void GLES2Implementation::GetShaderSource(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(GLsizei, length);
+  GPU_CLIENT_LOG("[" << GetLogPrefix()
+      << "] glGetShaderSource" << "("
+      << shader << ", "
+      << bufsize << ", "
+      << static_cast<void*>(length) << ", "
+      << static_cast<void*>(source) << ")");
+  helper_->SetBucketSize(kResultBucketId, 0);
+  helper_->GetShaderSource(shader, kResultBucketId);
+  std::string str;
+  GLsizei max_size = 0;
+  if (GetBucketAsString(kResultBucketId, &str)) {
+    if (bufsize > 0) {
+      max_size =
+          std::min(static_cast<size_t>(bufsize) - 1, str.size());
+      memcpy(source, str.c_str(), max_size);
+      source[max_size] = '\0';
+      GPU_CLIENT_LOG("------\n" << source << "\n------");
+    }
+  }
+  if (length != NULL) {
+    *length = max_size;
+  }
+}
+void GLES2Implementation::GetTexParameterfv(
+    GLenum target, GLenum pname, GLfloat* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetTexParameterfv(" << GLES2Util::GetStringGetTexParamTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetTexParameterfvHelper(target, pname, params)) {
+    return;
+  }
+  typedef GetTexParameterfv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetTexParameterfv(target, pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::GetTexParameteriv(
+    GLenum target, GLenum pname, GLint* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_INITALIZATION(GLint, params);
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGetTexParameteriv(" << GLES2Util::GetStringGetTexParamTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  if (GetTexParameterivHelper(target, pname, params)) {
+    return;
+  }
+  typedef GetTexParameteriv::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return;
+  }
+  result->SetNumResults(0);
+  helper_->GetTexParameteriv(target, pname,
+      GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  result->CopyResult(params);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (int32 i = 0; i < result->GetNumResults(); ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << result->GetData()[i]);
+    }
+  });
+}
+void GLES2Implementation::Hint(GLenum target, GLenum mode) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glHint(" << GLES2Util::GetStringHintTarget(target) << ", " << GLES2Util::GetStringHintMode(mode) << ")");  // NOLINT
+  helper_->Hint(target, mode);
+}
+
+GLboolean GLES2Implementation::IsBuffer(GLuint buffer) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsBuffer(" << buffer << ")");
+  typedef IsBuffer::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return GL_FALSE;
+  }
+  *result = 0;
+  helper_->IsBuffer(buffer, GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  GPU_CLIENT_LOG("returned " << *result);
+  return *result;
+}
+
+GLboolean GLES2Implementation::IsFramebuffer(GLuint framebuffer) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsFramebuffer(" << framebuffer << ")");  // NOLINT
+  typedef IsFramebuffer::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return GL_FALSE;
+  }
+  *result = 0;
+  helper_->IsFramebuffer(framebuffer, GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  GPU_CLIENT_LOG("returned " << *result);
+  return *result;
+}
+
+GLboolean GLES2Implementation::IsProgram(GLuint program) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsProgram(" << program << ")");
+  typedef IsProgram::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return GL_FALSE;
+  }
+  *result = 0;
+  helper_->IsProgram(program, GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  GPU_CLIENT_LOG("returned " << *result);
+  return *result;
+}
+
+GLboolean GLES2Implementation::IsRenderbuffer(GLuint renderbuffer) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsRenderbuffer(" << renderbuffer << ")");  // NOLINT
+  typedef IsRenderbuffer::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return GL_FALSE;
+  }
+  *result = 0;
+  helper_->IsRenderbuffer(
+      renderbuffer, GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  GPU_CLIENT_LOG("returned " << *result);
+  return *result;
+}
+
+GLboolean GLES2Implementation::IsShader(GLuint shader) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsShader(" << shader << ")");
+  typedef IsShader::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return GL_FALSE;
+  }
+  *result = 0;
+  helper_->IsShader(shader, GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  GPU_CLIENT_LOG("returned " << *result);
+  return *result;
+}
+
+GLboolean GLES2Implementation::IsTexture(GLuint texture) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsTexture(" << texture << ")");
+  typedef IsTexture::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return GL_FALSE;
+  }
+  *result = 0;
+  helper_->IsTexture(texture, GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  GPU_CLIENT_LOG("returned " << *result);
+  return *result;
+}
+
+void GLES2Implementation::LineWidth(GLfloat width) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glLineWidth(" << width << ")");
+  helper_->LineWidth(width);
+}
+
+void GLES2Implementation::PolygonOffset(GLfloat factor, GLfloat units) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glPolygonOffset(" << factor << ", " << units << ")");  // NOLINT
+  helper_->PolygonOffset(factor, units);
+}
+
+void GLES2Implementation::ReleaseShaderCompiler() {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glReleaseShaderCompiler(" << ")");
+  helper_->ReleaseShaderCompiler();
+}
+
+void GLES2Implementation::RenderbufferStorage(
+    GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glRenderbufferStorage(" << GLES2Util::GetStringRenderBufferTarget(target) << ", " << GLES2Util::GetStringRenderBufferFormat(internalformat) << ", " << width << ", " << height << ")");  // NOLINT
+  if (width < 0) {
+    SetGLError(GL_INVALID_VALUE, "glRenderbufferStorage", "width < 0");
+    return;
+  }
+  if (height < 0) {
+    SetGLError(GL_INVALID_VALUE, "glRenderbufferStorage", "height < 0");
+    return;
+  }
+  helper_->RenderbufferStorage(target, internalformat, width, height);
+}
+
+void GLES2Implementation::SampleCoverage(GLclampf value, GLboolean invert) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSampleCoverage(" << value << ", " << GLES2Util::GetStringBool(invert) << ")");  // NOLINT
+  helper_->SampleCoverage(value, invert);
+}
+
+void GLES2Implementation::Scissor(
+    GLint x, GLint y, GLsizei width, GLsizei height) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glScissor(" << x << ", " << y << ", " << width << ", " << height << ")");  // NOLINT
+  if (width < 0) {
+    SetGLError(GL_INVALID_VALUE, "glScissor", "width < 0");
+    return;
+  }
+  if (height < 0) {
+    SetGLError(GL_INVALID_VALUE, "glScissor", "height < 0");
+    return;
+  }
+  helper_->Scissor(x, y, width, height);
+}
+
+void GLES2Implementation::StencilFunc(GLenum func, GLint ref, GLuint mask) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilFunc(" << GLES2Util::GetStringCmpFunction(func) << ", " << ref << ", " << mask << ")");  // NOLINT
+  helper_->StencilFunc(func, ref, mask);
+}
+
+void GLES2Implementation::StencilFuncSeparate(
+    GLenum face, GLenum func, GLint ref, GLuint mask) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilFuncSeparate(" << GLES2Util::GetStringFaceType(face) << ", " << GLES2Util::GetStringCmpFunction(func) << ", " << ref << ", " << mask << ")");  // NOLINT
+  helper_->StencilFuncSeparate(face, func, ref, mask);
+}
+
+void GLES2Implementation::StencilMask(GLuint mask) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilMask(" << mask << ")");
+  helper_->StencilMask(mask);
+}
+
+void GLES2Implementation::StencilMaskSeparate(GLenum face, GLuint mask) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilMaskSeparate(" << GLES2Util::GetStringFaceType(face) << ", " << mask << ")");  // NOLINT
+  helper_->StencilMaskSeparate(face, mask);
+}
+
+void GLES2Implementation::StencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilOp(" << GLES2Util::GetStringStencilOp(fail) << ", " << GLES2Util::GetStringStencilOp(zfail) << ", " << GLES2Util::GetStringStencilOp(zpass) << ")");  // NOLINT
+  helper_->StencilOp(fail, zfail, zpass);
+}
+
+void GLES2Implementation::StencilOpSeparate(
+    GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glStencilOpSeparate(" << GLES2Util::GetStringFaceType(face) << ", " << GLES2Util::GetStringStencilOp(fail) << ", " << GLES2Util::GetStringStencilOp(zfail) << ", " << GLES2Util::GetStringStencilOp(zpass) << ")");  // NOLINT
+  helper_->StencilOpSeparate(face, fail, zfail, zpass);
+}
+
+void GLES2Implementation::TexParameterf(
+    GLenum target, GLenum pname, GLfloat param) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexParameterf(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << param << ")");  // NOLINT
+  helper_->TexParameterf(target, pname, param);
+}
+
+void GLES2Implementation::TexParameterfv(
+    GLenum target, GLenum pname, const GLfloat* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexParameterfv(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  GPU_CLIENT_LOG("values: " << params[0]);
+  helper_->TexParameterfvImmediate(target, pname, params);
+}
+
+void GLES2Implementation::TexParameteri(
+    GLenum target, GLenum pname, GLint param) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexParameteri(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << param << ")");  // NOLINT
+  helper_->TexParameteri(target, pname, param);
+}
+
+void GLES2Implementation::TexParameteriv(
+    GLenum target, GLenum pname, const GLint* params) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexParameteriv(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << GLES2Util::GetStringTextureParameter(pname) << ", " << static_cast<const void*>(params) << ")");  // NOLINT
+  GPU_CLIENT_LOG("values: " << params[0]);
+  helper_->TexParameterivImmediate(target, pname, params);
+}
+
+void GLES2Implementation::Uniform1f(GLint location, GLfloat x) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1f(" << location << ", " << x << ")");  // NOLINT
+  helper_->Uniform1f(location, x);
+}
+
+void GLES2Implementation::Uniform1fv(
+    GLint location, GLsizei count, const GLfloat* v) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1fv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 1]);
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniform1fv", "count < 0");
+    return;
+  }
+  helper_->Uniform1fvImmediate(location, count, v);
+}
+
+void GLES2Implementation::Uniform1i(GLint location, GLint x) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1i(" << location << ", " << x << ")");  // NOLINT
+  helper_->Uniform1i(location, x);
+}
+
+void GLES2Implementation::Uniform1iv(
+    GLint location, GLsizei count, const GLint* v) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform1iv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 1]);
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniform1iv", "count < 0");
+    return;
+  }
+  helper_->Uniform1ivImmediate(location, count, v);
+}
+
+void GLES2Implementation::Uniform2f(GLint location, GLfloat x, GLfloat y) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2f(" << location << ", " << x << ", " << y << ")");  // NOLINT
+  helper_->Uniform2f(location, x, y);
+}
+
+void GLES2Implementation::Uniform2fv(
+    GLint location, GLsizei count, const GLfloat* v) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2fv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 2] << ", " << v[1 + i * 2]);  // NOLINT
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniform2fv", "count < 0");
+    return;
+  }
+  helper_->Uniform2fvImmediate(location, count, v);
+}
+
+void GLES2Implementation::Uniform2i(GLint location, GLint x, GLint y) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2i(" << location << ", " << x << ", " << y << ")");  // NOLINT
+  helper_->Uniform2i(location, x, y);
+}
+
+void GLES2Implementation::Uniform2iv(
+    GLint location, GLsizei count, const GLint* v) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform2iv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 2] << ", " << v[1 + i * 2]);  // NOLINT
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniform2iv", "count < 0");
+    return;
+  }
+  helper_->Uniform2ivImmediate(location, count, v);
+}
+
+void GLES2Implementation::Uniform3f(
+    GLint location, GLfloat x, GLfloat y, GLfloat z) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3f(" << location << ", " << x << ", " << y << ", " << z << ")");  // NOLINT
+  helper_->Uniform3f(location, x, y, z);
+}
+
+void GLES2Implementation::Uniform3fv(
+    GLint location, GLsizei count, const GLfloat* v) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3fv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 3] << ", " << v[1 + i * 3] << ", " << v[2 + i * 3]);  // NOLINT
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniform3fv", "count < 0");
+    return;
+  }
+  helper_->Uniform3fvImmediate(location, count, v);
+}
+
+void GLES2Implementation::Uniform3i(
+    GLint location, GLint x, GLint y, GLint z) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3i(" << location << ", " << x << ", " << y << ", " << z << ")");  // NOLINT
+  helper_->Uniform3i(location, x, y, z);
+}
+
+void GLES2Implementation::Uniform3iv(
+    GLint location, GLsizei count, const GLint* v) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform3iv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 3] << ", " << v[1 + i * 3] << ", " << v[2 + i * 3]);  // NOLINT
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniform3iv", "count < 0");
+    return;
+  }
+  helper_->Uniform3ivImmediate(location, count, v);
+}
+
+void GLES2Implementation::Uniform4f(
+    GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4f(" << location << ", " << x << ", " << y << ", " << z << ", " << w << ")");  // NOLINT
+  helper_->Uniform4f(location, x, y, z, w);
+}
+
+void GLES2Implementation::Uniform4fv(
+    GLint location, GLsizei count, const GLfloat* v) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4fv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 4] << ", " << v[1 + i * 4] << ", " << v[2 + i * 4] << ", " << v[3 + i * 4]);  // NOLINT
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniform4fv", "count < 0");
+    return;
+  }
+  helper_->Uniform4fvImmediate(location, count, v);
+}
+
+void GLES2Implementation::Uniform4i(
+    GLint location, GLint x, GLint y, GLint z, GLint w) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4i(" << location << ", " << x << ", " << y << ", " << z << ", " << w << ")");  // NOLINT
+  helper_->Uniform4i(location, x, y, z, w);
+}
+
+void GLES2Implementation::Uniform4iv(
+    GLint location, GLsizei count, const GLint* v) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniform4iv(" << location << ", " << count << ", " << static_cast<const void*>(v) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << v[0 + i * 4] << ", " << v[1 + i * 4] << ", " << v[2 + i * 4] << ", " << v[3 + i * 4]);  // NOLINT
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniform4iv", "count < 0");
+    return;
+  }
+  helper_->Uniform4ivImmediate(location, count, v);
+}
+
+void GLES2Implementation::UniformMatrix2fv(
+    GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix2fv(" << location << ", " << count << ", " << GLES2Util::GetStringBool(transpose) << ", " << static_cast<const void*>(value) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << value[0 + i * 4] << ", " << value[1 + i * 4] << ", " << value[2 + i * 4] << ", " << value[3 + i * 4]);  // NOLINT
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniformMatrix2fv", "count < 0");
+    return;
+  }
+  helper_->UniformMatrix2fvImmediate(location, count, transpose, value);
+}
+
+void GLES2Implementation::UniformMatrix3fv(
+    GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix3fv(" << location << ", " << count << ", " << GLES2Util::GetStringBool(transpose) << ", " << static_cast<const void*>(value) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << value[0 + i * 9] << ", " << value[1 + i * 9] << ", " << value[2 + i * 9] << ", " << value[3 + i * 9] << ", " << value[4 + i * 9] << ", " << value[5 + i * 9] << ", " << value[6 + i * 9] << ", " << value[7 + i * 9] << ", " << value[8 + i * 9]);  // NOLINT
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniformMatrix3fv", "count < 0");
+    return;
+  }
+  helper_->UniformMatrix3fvImmediate(location, count, transpose, value);
+}
+
+void GLES2Implementation::UniformMatrix4fv(
+    GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUniformMatrix4fv(" << location << ", " << count << ", " << GLES2Util::GetStringBool(transpose) << ", " << static_cast<const void*>(value) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < count; ++i) {
+       GPU_CLIENT_LOG("  " << i << ": " << value[0 + i * 16] << ", " << value[1 + i * 16] << ", " << value[2 + i * 16] << ", " << value[3 + i * 16] << ", " << value[4 + i * 16] << ", " << value[5 + i * 16] << ", " << value[6 + i * 16] << ", " << value[7 + i * 16] << ", " << value[8 + i * 16] << ", " << value[9 + i * 16] << ", " << value[10 + i * 16] << ", " << value[11 + i * 16] << ", " << value[12 + i * 16] << ", " << value[13 + i * 16] << ", " << value[14 + i * 16] << ", " << value[15 + i * 16]);  // NOLINT
+    }
+  });
+  if (count < 0) {
+    SetGLError(GL_INVALID_VALUE, "glUniformMatrix4fv", "count < 0");
+    return;
+  }
+  helper_->UniformMatrix4fvImmediate(location, count, transpose, value);
+}
+
+void GLES2Implementation::UseProgram(GLuint program) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glUseProgram(" << program << ")");
+  helper_->UseProgram(program);
+}
+
+void GLES2Implementation::ValidateProgram(GLuint program) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glValidateProgram(" << program << ")");  // NOLINT
+  helper_->ValidateProgram(program);
+}
+
+void GLES2Implementation::VertexAttrib1f(GLuint indx, GLfloat x) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib1f(" << indx << ", " << x << ")");  // NOLINT
+  helper_->VertexAttrib1f(indx, x);
+}
+
+void GLES2Implementation::VertexAttrib1fv(GLuint indx, const GLfloat* values) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib1fv(" << indx << ", " << static_cast<const void*>(values) << ")");  // NOLINT
+  GPU_CLIENT_LOG("values: " << values[0]);
+  helper_->VertexAttrib1fvImmediate(indx, values);
+}
+
+void GLES2Implementation::VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib2f(" << indx << ", " << x << ", " << y << ")");  // NOLINT
+  helper_->VertexAttrib2f(indx, x, y);
+}
+
+void GLES2Implementation::VertexAttrib2fv(GLuint indx, const GLfloat* values) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib2fv(" << indx << ", " << static_cast<const void*>(values) << ")");  // NOLINT
+  GPU_CLIENT_LOG("values: " << values[0] << ", " << values[1]);
+  helper_->VertexAttrib2fvImmediate(indx, values);
+}
+
+void GLES2Implementation::VertexAttrib3f(
+    GLuint indx, GLfloat x, GLfloat y, GLfloat z) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib3f(" << indx << ", " << x << ", " << y << ", " << z << ")");  // NOLINT
+  helper_->VertexAttrib3f(indx, x, y, z);
+}
+
+void GLES2Implementation::VertexAttrib3fv(GLuint indx, const GLfloat* values) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib3fv(" << indx << ", " << static_cast<const void*>(values) << ")");  // NOLINT
+  GPU_CLIENT_LOG("values: " << values[0] << ", " << values[1] << ", " << values[2]);  // NOLINT
+  helper_->VertexAttrib3fvImmediate(indx, values);
+}
+
+void GLES2Implementation::VertexAttrib4f(
+    GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib4f(" << indx << ", " << x << ", " << y << ", " << z << ", " << w << ")");  // NOLINT
+  helper_->VertexAttrib4f(indx, x, y, z, w);
+}
+
+void GLES2Implementation::VertexAttrib4fv(GLuint indx, const GLfloat* values) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glVertexAttrib4fv(" << indx << ", " << static_cast<const void*>(values) << ")");  // NOLINT
+  GPU_CLIENT_LOG("values: " << values[0] << ", " << values[1] << ", " << values[2] << ", " << values[3]);  // NOLINT
+  helper_->VertexAttrib4fvImmediate(indx, values);
+}
+
+void GLES2Implementation::Viewport(
+    GLint x, GLint y, GLsizei width, GLsizei height) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glViewport(" << x << ", " << y << ", " << width << ", " << height << ")");  // NOLINT
+  if (width < 0) {
+    SetGLError(GL_INVALID_VALUE, "glViewport", "width < 0");
+    return;
+  }
+  if (height < 0) {
+    SetGLError(GL_INVALID_VALUE, "glViewport", "height < 0");
+    return;
+  }
+  helper_->Viewport(x, y, width, height);
+}
+
+void GLES2Implementation::BlitFramebufferEXT(
+    GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
+    GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBlitFramebufferEXT(" << srcX0 << ", " << srcY0 << ", " << srcX1 << ", " << srcY1 << ", " << dstX0 << ", " << dstY0 << ", " << dstX1 << ", " << dstY1 << ", " << mask << ", " << GLES2Util::GetStringBlitFilter(filter) << ")");  // NOLINT
+  helper_->BlitFramebufferEXT(
+      srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+void GLES2Implementation::RenderbufferStorageMultisampleEXT(
+    GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
+    GLsizei height) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glRenderbufferStorageMultisampleEXT(" << GLES2Util::GetStringRenderBufferTarget(target) << ", " << samples << ", " << GLES2Util::GetStringRenderBufferFormat(internalformat) << ", " << width << ", " << height << ")");  // NOLINT
+  if (samples < 0) {
+    SetGLError(
+        GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "samples < 0");
+    return;
+  }
+  if (width < 0) {
+    SetGLError(
+        GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "width < 0");
+    return;
+  }
+  if (height < 0) {
+    SetGLError(
+        GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT", "height < 0");
+    return;
+  }
+  helper_->RenderbufferStorageMultisampleEXT(
+      target, samples, internalformat, width, height);
+}
+
+void GLES2Implementation::TexStorage2DEXT(
+    GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width,
+    GLsizei height) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexStorage2DEXT(" << GLES2Util::GetStringTextureTarget(target) << ", " << levels << ", " << GLES2Util::GetStringTextureInternalFormatStorage(internalFormat) << ", " << width << ", " << height << ")");  // NOLINT
+  if (levels < 0) {
+    SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT", "levels < 0");
+    return;
+  }
+  if (width < 0) {
+    SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT", "width < 0");
+    return;
+  }
+  if (height < 0) {
+    SetGLError(GL_INVALID_VALUE, "glTexStorage2DEXT", "height < 0");
+    return;
+  }
+  helper_->TexStorage2DEXT(target, levels, internalFormat, width, height);
+}
+
+void GLES2Implementation::GenQueriesEXT(GLsizei n, GLuint* queries) {
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenQueriesEXT(" << n << ", " << static_cast<const void*>(queries) << ")");  // NOLINT
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glGenQueriesEXT", "n < 0");
+    return;
+  }
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GetIdHandler(id_namespaces::kQueries)->
+      MakeIds(this, 0, n, queries);
+  helper_->GenQueriesEXTImmediate(n, queries);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << queries[i]);
+    }
+  });
+}
+
+void GLES2Implementation::DeleteQueriesEXT(GLsizei n, const GLuint* queries) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteQueriesEXT(" << n << ", " << static_cast<const void*>(queries) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << queries[i]);
+    }
+  });
+  GPU_CLIENT_DCHECK_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_DCHECK(queries[i] != 0);
+    }
+  });
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glDeleteQueriesEXT", "n < 0");
+    return;
+  }
+  DeleteQueriesEXTHelper(n, queries);
+}
+
+void GLES2Implementation::GenVertexArraysOES(GLsizei n, GLuint* arrays) {
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glGenVertexArraysOES(" << n << ", " << static_cast<const void*>(arrays) << ")");  // NOLINT
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glGenVertexArraysOES", "n < 0");
+    return;
+  }
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GetIdHandler(id_namespaces::kVertexArrays)->
+      MakeIds(this, 0, n, arrays);
+  helper_->GenVertexArraysOESImmediate(n, arrays);
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << arrays[i]);
+    }
+  });
+}
+
+void GLES2Implementation::DeleteVertexArraysOES(
+    GLsizei n, const GLuint* arrays) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glDeleteVertexArraysOES(" << n << ", " << static_cast<const void*>(arrays) << ")");  // NOLINT
+  GPU_CLIENT_LOG_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_CLIENT_LOG("  " << i << ": " << arrays[i]);
+    }
+  });
+  GPU_CLIENT_DCHECK_CODE_BLOCK({
+    for (GLsizei i = 0; i < n; ++i) {
+      GPU_DCHECK(arrays[i] != 0);
+    }
+  });
+  if (n < 0) {
+    SetGLError(GL_INVALID_VALUE, "glDeleteVertexArraysOES", "n < 0");
+    return;
+  }
+  DeleteVertexArraysOESHelper(n, arrays);
+}
+
+GLboolean GLES2Implementation::IsVertexArrayOES(GLuint array) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glIsVertexArrayOES(" << array << ")");  // NOLINT
+  typedef IsVertexArrayOES::Result Result;
+  Result* result = GetResultAs<Result*>();
+  if (!result) {
+    return GL_FALSE;
+  }
+  *result = 0;
+  helper_->IsVertexArrayOES(array, GetResultShmId(), GetResultShmOffset());
+  WaitForCmd();
+  GPU_CLIENT_LOG("returned " << *result);
+  return *result;
+}
+
+void GLES2Implementation::BindVertexArrayOES(GLuint array) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glBindVertexArrayOES(" << array << ")");  // NOLINT
+  if (IsVertexArrayReservedId(array)) {
+    SetGLError(
+        GL_INVALID_OPERATION, "BindVertexArrayOES", "array reserved id");
+    return;
+  }
+  BindVertexArrayHelper(array);
+  helper_->BindVertexArrayOES(array);
+}
+
+void GLES2Implementation::GetTranslatedShaderSourceANGLE(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_VALIDATE_DESTINATION_OPTIONAL_INITALIZATION(GLsizei, length);
+  GPU_CLIENT_LOG("[" << GetLogPrefix()
+      << "] glGetTranslatedShaderSourceANGLE" << "("
+      << shader << ", "
+      << bufsize << ", "
+      << static_cast<void*>(length) << ", "
+      << static_cast<void*>(source) << ")");
+  helper_->SetBucketSize(kResultBucketId, 0);
+  helper_->GetTranslatedShaderSourceANGLE(shader, kResultBucketId);
+  std::string str;
+  GLsizei max_size = 0;
+  if (GetBucketAsString(kResultBucketId, &str)) {
+    if (bufsize > 0) {
+      max_size =
+          std::min(static_cast<size_t>(bufsize) - 1, str.size());
+      memcpy(source, str.c_str(), max_size);
+      source[max_size] = '\0';
+      GPU_CLIENT_LOG("------\n" << source << "\n------");
+    }
+  }
+  if (length != NULL) {
+    *length = max_size;
+  }
+}
+void GLES2Implementation::TexImageIOSurface2DCHROMIUM(
+    GLenum target, GLsizei width, GLsizei height, GLuint ioSurfaceId,
+    GLuint plane) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glTexImageIOSurface2DCHROMIUM(" << GLES2Util::GetStringTextureBindTarget(target) << ", " << width << ", " << height << ", " << ioSurfaceId << ", " << plane << ")");  // NOLINT
+  if (width < 0) {
+    SetGLError(GL_INVALID_VALUE, "glTexImageIOSurface2DCHROMIUM", "width < 0");
+    return;
+  }
+  if (height < 0) {
+    SetGLError(
+        GL_INVALID_VALUE, "glTexImageIOSurface2DCHROMIUM", "height < 0");
+    return;
+  }
+  helper_->TexImageIOSurface2DCHROMIUM(
+      target, width, height, ioSurfaceId, plane);
+}
+
+void GLES2Implementation::CopyTextureCHROMIUM(
+    GLenum target, GLenum source_id, GLenum dest_id, GLint level,
+    GLint internalformat) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glCopyTextureCHROMIUM(" << GLES2Util::GetStringEnum(target) << ", " << GLES2Util::GetStringEnum(source_id) << ", " << GLES2Util::GetStringEnum(dest_id) << ", " << level << ", " << internalformat << ")");  // NOLINT
+  helper_->CopyTextureCHROMIUM(
+      target, source_id, dest_id, level, internalformat);
+}
+
+void GLES2Implementation::ProduceTextureCHROMIUM(
+    GLenum target, const GLbyte* mailbox) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glProduceTextureCHROMIUM(" << GLES2Util::GetStringTextureTarget(target) << ", " << static_cast<const void*>(mailbox) << ")");  // NOLINT
+  GPU_CLIENT_LOG("values: " << mailbox[0] << ", " << mailbox[1] << ", " << mailbox[2] << ", " << mailbox[3] << ", " << mailbox[4] << ", " << mailbox[5] << ", " << mailbox[6] << ", " << mailbox[7] << ", " << mailbox[8] << ", " << mailbox[9] << ", " << mailbox[10] << ", " << mailbox[11] << ", " << mailbox[12] << ", " << mailbox[13] << ", " << mailbox[14] << ", " << mailbox[15] << ", " << mailbox[16] << ", " << mailbox[17] << ", " << mailbox[18] << ", " << mailbox[19] << ", " << mailbox[20] << ", " << mailbox[21] << ", " << mailbox[22] << ", " << mailbox[23] << ", " << mailbox[24] << ", " << mailbox[25] << ", " << mailbox[26] << ", " << mailbox[27] << ", " << mailbox[28] << ", " << mailbox[29] << ", " << mailbox[30] << ", " << mailbox[31] << ", " << mailbox[32] << ", " << mailbox[33] << ", " << mailbox[34] << ", " << mailbox[35] << ", " << mailbox[36] << ", " << mailbox[37] << ", " << mailbox[38] << ", " << mailbox[39] << ", " << mailbox[40] << ", " << mailbox[41] << ", " << mailbox[42] << ", " << mailbox[43] << ", " << mailbox[44] << ", " << mailbox[45] << ", " << mailbox[46] << ", " << mailbox[47] << ", " << mailbox[48] << ", " << mailbox[49] << ", " << mailbox[50] << ", " << mailbox[51] << ", " << mailbox[52] << ", " << mailbox[53] << ", " << mailbox[54] << ", " << mailbox[55] << ", " << mailbox[56] << ", " << mailbox[57] << ", " << mailbox[58] << ", " << mailbox[59] << ", " << mailbox[60] << ", " << mailbox[61] << ", " << mailbox[62] << ", " << mailbox[63]);  // NOLINT
+  helper_->ProduceTextureCHROMIUMImmediate(target, mailbox);
+}
+
+void GLES2Implementation::ConsumeTextureCHROMIUM(
+    GLenum target, const GLbyte* mailbox) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glConsumeTextureCHROMIUM(" << GLES2Util::GetStringTextureTarget(target) << ", " << static_cast<const void*>(mailbox) << ")");  // NOLINT
+  GPU_CLIENT_LOG("values: " << mailbox[0] << ", " << mailbox[1] << ", " << mailbox[2] << ", " << mailbox[3] << ", " << mailbox[4] << ", " << mailbox[5] << ", " << mailbox[6] << ", " << mailbox[7] << ", " << mailbox[8] << ", " << mailbox[9] << ", " << mailbox[10] << ", " << mailbox[11] << ", " << mailbox[12] << ", " << mailbox[13] << ", " << mailbox[14] << ", " << mailbox[15] << ", " << mailbox[16] << ", " << mailbox[17] << ", " << mailbox[18] << ", " << mailbox[19] << ", " << mailbox[20] << ", " << mailbox[21] << ", " << mailbox[22] << ", " << mailbox[23] << ", " << mailbox[24] << ", " << mailbox[25] << ", " << mailbox[26] << ", " << mailbox[27] << ", " << mailbox[28] << ", " << mailbox[29] << ", " << mailbox[30] << ", " << mailbox[31] << ", " << mailbox[32] << ", " << mailbox[33] << ", " << mailbox[34] << ", " << mailbox[35] << ", " << mailbox[36] << ", " << mailbox[37] << ", " << mailbox[38] << ", " << mailbox[39] << ", " << mailbox[40] << ", " << mailbox[41] << ", " << mailbox[42] << ", " << mailbox[43] << ", " << mailbox[44] << ", " << mailbox[45] << ", " << mailbox[46] << ", " << mailbox[47] << ", " << mailbox[48] << ", " << mailbox[49] << ", " << mailbox[50] << ", " << mailbox[51] << ", " << mailbox[52] << ", " << mailbox[53] << ", " << mailbox[54] << ", " << mailbox[55] << ", " << mailbox[56] << ", " << mailbox[57] << ", " << mailbox[58] << ", " << mailbox[59] << ", " << mailbox[60] << ", " << mailbox[61] << ", " << mailbox[62] << ", " << mailbox[63]);  // NOLINT
+  helper_->ConsumeTextureCHROMIUMImmediate(target, mailbox);
+}
+
+#endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_IMPL_AUTOGEN_H_
+
diff --git a/gpu/command_buffer/client/gles2_interface.cc b/gpu/command_buffer/client/gles2_interface.cc
new file mode 100644
index 0000000..b09e5f8
--- /dev/null
+++ b/gpu/command_buffer/client/gles2_interface.cc
@@ -0,0 +1,19 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "../client/gles2_interface.h"
+
+namespace gpu {
+namespace gles2 {
+
+GLES2Interface::GLES2Interface() {
+}
+
+GLES2Interface::~GLES2Interface() {
+}
+
+}  // namespace gles2
+}  // namespace gpu
+
+
diff --git a/gpu/command_buffer/client/gles2_interface.h b/gpu/command_buffer/client/gles2_interface.h
new file mode 100644
index 0000000..9fe54a1
--- /dev/null
+++ b/gpu/command_buffer/client/gles2_interface.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_H_
+#define GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_H_
+
+#include <GLES2/gl2.h>
+#include "gles2_impl_export.h"
+
+namespace gpu {
+namespace gles2 {
+
+// This class is the interface for all client side GL functions.
+class GLES2_IMPL_EXPORT GLES2Interface {
+ public:
+  GLES2Interface();
+  virtual ~GLES2Interface();
+
+  // Include the auto-generated part of this class. We split this because
+  // it means we can easily edit the non-auto generated parts right here in
+  // this file instead of having to edit some template or the code generator.
+  #include "../client/gles2_interface_autogen.h"
+};
+
+}  // namespace gles2
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_H_
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
new file mode 100644
index 0000000..4f38485
--- /dev/null
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -0,0 +1,290 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is auto-generated from
+// gpu/command_buffer/build_gles2_cmd_buffer.py
+// DO NOT EDIT!
+
+// This file is included by gles2_interface.h to declare the
+// GL api functions.
+#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_
+#define GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_
+
+virtual void ActiveTexture(GLenum texture) = 0;
+virtual void AttachShader(GLuint program, GLuint shader) = 0;
+virtual void BindAttribLocation(
+    GLuint program, GLuint index, const char* name) = 0;
+virtual void BindBuffer(GLenum target, GLuint buffer) = 0;
+virtual void BindFramebuffer(GLenum target, GLuint framebuffer) = 0;
+virtual void BindRenderbuffer(GLenum target, GLuint renderbuffer) = 0;
+virtual void BindTexture(GLenum target, GLuint texture) = 0;
+virtual void BlendColor(
+    GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = 0;
+virtual void BlendEquation(GLenum mode) = 0;
+virtual void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) = 0;
+virtual void BlendFunc(GLenum sfactor, GLenum dfactor) = 0;
+virtual void BlendFuncSeparate(
+    GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) = 0;
+virtual void BufferData(
+    GLenum target, GLsizeiptr size, const void* data, GLenum usage) = 0;
+virtual void BufferSubData(
+    GLenum target, GLintptr offset, GLsizeiptr size, const void* data) = 0;
+virtual GLenum CheckFramebufferStatus(GLenum target) = 0;
+virtual void Clear(GLbitfield mask) = 0;
+virtual void ClearColor(
+    GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = 0;
+virtual void ClearDepthf(GLclampf depth) = 0;
+virtual void ClearStencil(GLint s) = 0;
+virtual void ColorMask(
+    GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) = 0;
+virtual void CompileShader(GLuint shader) = 0;
+virtual void CompressedTexImage2D(
+    GLenum target, GLint level, GLenum internalformat, GLsizei width,
+    GLsizei height, GLint border, GLsizei imageSize, const void* data) = 0;
+virtual void CompressedTexSubImage2D(
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+    GLsizei height, GLenum format, GLsizei imageSize, const void* data) = 0;
+virtual void CopyTexImage2D(
+    GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
+    GLsizei width, GLsizei height, GLint border) = 0;
+virtual void CopyTexSubImage2D(
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
+    GLsizei width, GLsizei height) = 0;
+virtual GLuint CreateProgram() = 0;
+virtual GLuint CreateShader(GLenum type) = 0;
+virtual void CullFace(GLenum mode) = 0;
+virtual void DeleteBuffers(GLsizei n, const GLuint* buffers) = 0;
+virtual void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) = 0;
+virtual void DeleteProgram(GLuint program) = 0;
+virtual void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) = 0;
+virtual void DeleteShader(GLuint shader) = 0;
+virtual void DeleteTextures(GLsizei n, const GLuint* textures) = 0;
+virtual void DepthFunc(GLenum func) = 0;
+virtual void DepthMask(GLboolean flag) = 0;
+virtual void DepthRangef(GLclampf zNear, GLclampf zFar) = 0;
+virtual void DetachShader(GLuint program, GLuint shader) = 0;
+virtual void Disable(GLenum cap) = 0;
+virtual void DisableVertexAttribArray(GLuint index) = 0;
+virtual void DrawArrays(GLenum mode, GLint first, GLsizei count) = 0;
+virtual void DrawElements(
+    GLenum mode, GLsizei count, GLenum type, const void* indices) = 0;
+virtual void Enable(GLenum cap) = 0;
+virtual void EnableVertexAttribArray(GLuint index) = 0;
+virtual void Finish() = 0;
+virtual void Flush() = 0;
+virtual void ShallowFlushCHROMIUM() = 0;
+virtual void FramebufferRenderbuffer(
+    GLenum target, GLenum attachment, GLenum renderbuffertarget,
+    GLuint renderbuffer) = 0;
+virtual void FramebufferTexture2D(
+    GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
+    GLint level) = 0;
+virtual void FrontFace(GLenum mode) = 0;
+virtual void GenBuffers(GLsizei n, GLuint* buffers) = 0;
+virtual void GenerateMipmap(GLenum target) = 0;
+virtual void GenFramebuffers(GLsizei n, GLuint* framebuffers) = 0;
+virtual void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) = 0;
+virtual void GenTextures(GLsizei n, GLuint* textures) = 0;
+virtual void GetActiveAttrib(
+    GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
+    GLenum* type, char* name) = 0;
+virtual void GetActiveUniform(
+    GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
+    GLenum* type, char* name) = 0;
+virtual void GetAttachedShaders(
+    GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) = 0;
+virtual GLint GetAttribLocation(GLuint program, const char* name) = 0;
+virtual void GetBooleanv(GLenum pname, GLboolean* params) = 0;
+virtual void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) =
+    0;
+virtual GLenum GetError() = 0;
+virtual void GetFloatv(GLenum pname, GLfloat* params) = 0;
+virtual void GetFramebufferAttachmentParameteriv(
+    GLenum target, GLenum attachment, GLenum pname, GLint* params) = 0;
+virtual void GetIntegerv(GLenum pname, GLint* params) = 0;
+virtual void GetProgramiv(GLuint program, GLenum pname, GLint* params) = 0;
+virtual void GetProgramInfoLog(
+    GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) = 0;
+virtual void GetRenderbufferParameteriv(
+    GLenum target, GLenum pname, GLint* params) = 0;
+virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) = 0;
+virtual void GetShaderInfoLog(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) = 0;
+virtual void GetShaderPrecisionFormat(
+    GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) =
+        0;
+virtual void GetShaderSource(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) = 0;
+virtual const GLubyte* GetString(GLenum name) = 0;
+virtual void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) =
+    0;
+virtual void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) = 0;
+virtual void GetUniformfv(GLuint program, GLint location, GLfloat* params) = 0;
+virtual void GetUniformiv(GLuint program, GLint location, GLint* params) = 0;
+virtual GLint GetUniformLocation(GLuint program, const char* name) = 0;
+virtual void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) =
+    0;
+virtual void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) = 0;
+virtual void GetVertexAttribPointerv(
+    GLuint index, GLenum pname, void** pointer) = 0;
+virtual void Hint(GLenum target, GLenum mode) = 0;
+virtual GLboolean IsBuffer(GLuint buffer) = 0;
+virtual GLboolean IsEnabled(GLenum cap) = 0;
+virtual GLboolean IsFramebuffer(GLuint framebuffer) = 0;
+virtual GLboolean IsProgram(GLuint program) = 0;
+virtual GLboolean IsRenderbuffer(GLuint renderbuffer) = 0;
+virtual GLboolean IsShader(GLuint shader) = 0;
+virtual GLboolean IsTexture(GLuint texture) = 0;
+virtual void LineWidth(GLfloat width) = 0;
+virtual void LinkProgram(GLuint program) = 0;
+virtual void PixelStorei(GLenum pname, GLint param) = 0;
+virtual void PolygonOffset(GLfloat factor, GLfloat units) = 0;
+virtual void ReadPixels(
+    GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+    void* pixels) = 0;
+virtual void ReleaseShaderCompiler() = 0;
+virtual void RenderbufferStorage(
+    GLenum target, GLenum internalformat, GLsizei width, GLsizei height) = 0;
+virtual void SampleCoverage(GLclampf value, GLboolean invert) = 0;
+virtual void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) = 0;
+virtual void ShaderBinary(
+    GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary,
+    GLsizei length) = 0;
+virtual void ShaderSource(
+    GLuint shader, GLsizei count, const char** str, const GLint* length) = 0;
+virtual void StencilFunc(GLenum func, GLint ref, GLuint mask) = 0;
+virtual void StencilFuncSeparate(
+    GLenum face, GLenum func, GLint ref, GLuint mask) = 0;
+virtual void StencilMask(GLuint mask) = 0;
+virtual void StencilMaskSeparate(GLenum face, GLuint mask) = 0;
+virtual void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) = 0;
+virtual void StencilOpSeparate(
+    GLenum face, GLenum fail, GLenum zfail, GLenum zpass) = 0;
+virtual void TexImage2D(
+    GLenum target, GLint level, GLint internalformat, GLsizei width,
+    GLsizei height, GLint border, GLenum format, GLenum type,
+    const void* pixels) = 0;
+virtual void TexParameterf(GLenum target, GLenum pname, GLfloat param) = 0;
+virtual void TexParameterfv(
+    GLenum target, GLenum pname, const GLfloat* params) = 0;
+virtual void TexParameteri(GLenum target, GLenum pname, GLint param) = 0;
+virtual void TexParameteriv(GLenum target, GLenum pname, const GLint* params) =
+    0;
+virtual void TexSubImage2D(
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+    GLsizei height, GLenum format, GLenum type, const void* pixels) = 0;
+virtual void Uniform1f(GLint location, GLfloat x) = 0;
+virtual void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) = 0;
+virtual void Uniform1i(GLint location, GLint x) = 0;
+virtual void Uniform1iv(GLint location, GLsizei count, const GLint* v) = 0;
+virtual void Uniform2f(GLint location, GLfloat x, GLfloat y) = 0;
+virtual void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) = 0;
+virtual void Uniform2i(GLint location, GLint x, GLint y) = 0;
+virtual void Uniform2iv(GLint location, GLsizei count, const GLint* v) = 0;
+virtual void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) = 0;
+virtual void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) = 0;
+virtual void Uniform3i(GLint location, GLint x, GLint y, GLint z) = 0;
+virtual void Uniform3iv(GLint location, GLsizei count, const GLint* v) = 0;
+virtual void Uniform4f(
+    GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = 0;
+virtual void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) = 0;
+virtual void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) = 0;
+virtual void Uniform4iv(GLint location, GLsizei count, const GLint* v) = 0;
+virtual void UniformMatrix2fv(
+    GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) =
+        0;
+virtual void UniformMatrix3fv(
+    GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) =
+        0;
+virtual void UniformMatrix4fv(
+    GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) =
+        0;
+virtual void UseProgram(GLuint program) = 0;
+virtual void ValidateProgram(GLuint program) = 0;
+virtual void VertexAttrib1f(GLuint indx, GLfloat x) = 0;
+virtual void VertexAttrib1fv(GLuint indx, const GLfloat* values) = 0;
+virtual void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) = 0;
+virtual void VertexAttrib2fv(GLuint indx, const GLfloat* values) = 0;
+virtual void VertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z) = 0;
+virtual void VertexAttrib3fv(GLuint indx, const GLfloat* values) = 0;
+virtual void VertexAttrib4f(
+    GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) = 0;
+virtual void VertexAttrib4fv(GLuint indx, const GLfloat* values) = 0;
+virtual void VertexAttribPointer(
+    GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
+    const void* ptr) = 0;
+virtual void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) = 0;
+virtual void BlitFramebufferEXT(
+    GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
+    GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) = 0;
+virtual void RenderbufferStorageMultisampleEXT(
+    GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
+    GLsizei height) = 0;
+virtual void TexStorage2DEXT(
+    GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width,
+    GLsizei height) = 0;
+virtual void GenQueriesEXT(GLsizei n, GLuint* queries) = 0;
+virtual void DeleteQueriesEXT(GLsizei n, const GLuint* queries) = 0;
+virtual GLboolean IsQueryEXT(GLuint id) = 0;
+virtual void BeginQueryEXT(GLenum target, GLuint id) = 0;
+virtual void EndQueryEXT(GLenum target) = 0;
+virtual void GetQueryivEXT(GLenum target, GLenum pname, GLint* params) = 0;
+virtual void GetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint* params) = 0;
+virtual void InsertEventMarkerEXT(GLsizei length, const GLchar* marker) = 0;
+virtual void PushGroupMarkerEXT(GLsizei length, const GLchar* marker) = 0;
+virtual void PopGroupMarkerEXT() = 0;
+virtual void GenVertexArraysOES(GLsizei n, GLuint* arrays) = 0;
+virtual void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) = 0;
+virtual GLboolean IsVertexArrayOES(GLuint array) = 0;
+virtual void BindVertexArrayOES(GLuint array) = 0;
+virtual void SwapBuffers() = 0;
+virtual GLuint GetMaxValueInBufferCHROMIUM(
+    GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) = 0;
+virtual void GenSharedIdsCHROMIUM(
+    GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) = 0;
+virtual void DeleteSharedIdsCHROMIUM(
+    GLuint namespace_id, GLsizei n, const GLuint* ids) = 0;
+virtual void RegisterSharedIdsCHROMIUM(
+    GLuint namespace_id, GLsizei n, const GLuint* ids) = 0;
+virtual GLboolean EnableFeatureCHROMIUM(const char* feature) = 0;
+virtual void* MapBufferSubDataCHROMIUM(
+    GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) = 0;
+virtual void UnmapBufferSubDataCHROMIUM(const void* mem) = 0;
+virtual void* MapTexSubImage2DCHROMIUM(
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+    GLsizei height, GLenum format, GLenum type, GLenum access) = 0;
+virtual void UnmapTexSubImage2DCHROMIUM(const void* mem) = 0;
+virtual void ResizeCHROMIUM(GLuint width, GLuint height) = 0;
+virtual const GLchar* GetRequestableExtensionsCHROMIUM() = 0;
+virtual void RequestExtensionCHROMIUM(const char* extension) = 0;
+virtual void RateLimitOffscreenContextCHROMIUM() = 0;
+virtual void GetMultipleIntegervCHROMIUM(
+    const GLenum* pnames, GLuint count, GLint* results, GLsizeiptr size) = 0;
+virtual void GetProgramInfoCHROMIUM(
+    GLuint program, GLsizei bufsize, GLsizei* size, void* info) = 0;
+virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) = 0;
+virtual void DestroyStreamTextureCHROMIUM(GLuint texture) = 0;
+virtual void GetTranslatedShaderSourceANGLE(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) = 0;
+virtual void PostSubBufferCHROMIUM(
+    GLint x, GLint y, GLint width, GLint height) = 0;
+virtual void TexImageIOSurface2DCHROMIUM(
+    GLenum target, GLsizei width, GLsizei height, GLuint ioSurfaceId,
+    GLuint plane) = 0;
+virtual void CopyTextureCHROMIUM(
+    GLenum target, GLenum source_id, GLenum dest_id, GLint level,
+    GLint internalformat) = 0;
+virtual void DrawArraysInstancedANGLE(
+    GLenum mode, GLint first, GLsizei count, GLsizei primcount) = 0;
+virtual void DrawElementsInstancedANGLE(
+    GLenum mode, GLsizei count, GLenum type, const void* indices,
+    GLsizei primcount) = 0;
+virtual void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) = 0;
+virtual void GenMailboxCHROMIUM(GLbyte* mailbox) = 0;
+virtual void ProduceTextureCHROMIUM(GLenum target, const GLbyte* mailbox) = 0;
+virtual void ConsumeTextureCHROMIUM(GLenum target, const GLbyte* mailbox) = 0;
+virtual void BindUniformLocationCHROMIUM(
+    GLuint program, GLint location, const char* name) = 0;
+#endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_
+
diff --git a/gpu/command_buffer/client/gles2_interface_stub.cc b/gpu/command_buffer/client/gles2_interface_stub.cc
new file mode 100644
index 0000000..3f4d7baf
--- /dev/null
+++ b/gpu/command_buffer/client/gles2_interface_stub.cc
@@ -0,0 +1,24 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/client/gles2_interface_stub.h"
+
+namespace gpu {
+namespace gles2 {
+
+GLES2InterfaceStub::GLES2InterfaceStub() {
+}
+
+GLES2InterfaceStub::~GLES2InterfaceStub() {
+}
+
+// Include the auto-generated part of this class. We split this because
+// it means we can easily edit the non-auto generated parts right here in
+// this file instead of having to edit some template or the code generator.
+#include "gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h"
+
+}  // namespace gles2
+}  // namespace gpu
+
+
diff --git a/gpu/command_buffer/client/gles2_interface_stub.h b/gpu/command_buffer/client/gles2_interface_stub.h
new file mode 100644
index 0000000..342fc9ba
--- /dev/null
+++ b/gpu/command_buffer/client/gles2_interface_stub.h
@@ -0,0 +1,29 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_H_
+#define GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_H_
+
+#include "gpu/command_buffer/common/compiler_specific.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+
+namespace gpu {
+namespace gles2 {
+
+// This class a stub to help with mocks for the GLES2Interface class.
+class GLES2InterfaceStub : public GLES2Interface {
+ public:
+  GLES2InterfaceStub();
+  virtual ~GLES2InterfaceStub();
+
+  // Include the auto-generated part of this class. We split this because
+  // it means we can easily edit the non-auto generated parts right here in
+  // this file instead of having to edit some template or the code generator.
+  #include "gpu/command_buffer/client/gles2_interface_stub_autogen.h"
+};
+
+}  // namespace gles2
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_H_
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
new file mode 100644
index 0000000..02f75af
--- /dev/null
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -0,0 +1,322 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is auto-generated from
+// gpu/command_buffer/build_gles2_cmd_buffer.py
+// DO NOT EDIT!
+
+// This file is included by gles2_interface_stub.h.
+#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_
+#define GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_
+
+virtual void ActiveTexture(GLenum texture) OVERRIDE;
+virtual void AttachShader(GLuint program, GLuint shader) OVERRIDE;
+virtual void BindAttribLocation(
+    GLuint program, GLuint index, const char* name) OVERRIDE;
+virtual void BindBuffer(GLenum target, GLuint buffer) OVERRIDE;
+virtual void BindFramebuffer(GLenum target, GLuint framebuffer) OVERRIDE;
+virtual void BindRenderbuffer(GLenum target, GLuint renderbuffer) OVERRIDE;
+virtual void BindTexture(GLenum target, GLuint texture) OVERRIDE;
+virtual void BlendColor(
+    GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) OVERRIDE;
+virtual void BlendEquation(GLenum mode) OVERRIDE;
+virtual void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) OVERRIDE;
+virtual void BlendFunc(GLenum sfactor, GLenum dfactor) OVERRIDE;
+virtual void BlendFuncSeparate(
+    GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) OVERRIDE;
+virtual void BufferData(
+    GLenum target, GLsizeiptr size, const void* data, GLenum usage) OVERRIDE;
+virtual void BufferSubData(
+    GLenum target, GLintptr offset, GLsizeiptr size,
+    const void* data) OVERRIDE;
+virtual GLenum CheckFramebufferStatus(GLenum target) OVERRIDE;
+virtual void Clear(GLbitfield mask) OVERRIDE;
+virtual void ClearColor(
+    GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) OVERRIDE;
+virtual void ClearDepthf(GLclampf depth) OVERRIDE;
+virtual void ClearStencil(GLint s) OVERRIDE;
+virtual void ColorMask(
+    GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) OVERRIDE;
+virtual void CompileShader(GLuint shader) OVERRIDE;
+virtual void CompressedTexImage2D(
+    GLenum target, GLint level, GLenum internalformat, GLsizei width,
+    GLsizei height, GLint border, GLsizei imageSize,
+    const void* data) OVERRIDE;
+virtual void CompressedTexSubImage2D(
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+    GLsizei height, GLenum format, GLsizei imageSize,
+    const void* data) OVERRIDE;
+virtual void CopyTexImage2D(
+    GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
+    GLsizei width, GLsizei height, GLint border) OVERRIDE;
+virtual void CopyTexSubImage2D(
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
+    GLsizei width, GLsizei height) OVERRIDE;
+virtual GLuint CreateProgram() OVERRIDE;
+virtual GLuint CreateShader(GLenum type) OVERRIDE;
+virtual void CullFace(GLenum mode) OVERRIDE;
+virtual void DeleteBuffers(GLsizei n, const GLuint* buffers) OVERRIDE;
+virtual void DeleteFramebuffers(
+    GLsizei n, const GLuint* framebuffers) OVERRIDE;
+virtual void DeleteProgram(GLuint program) OVERRIDE;
+virtual void DeleteRenderbuffers(
+    GLsizei n, const GLuint* renderbuffers) OVERRIDE;
+virtual void DeleteShader(GLuint shader) OVERRIDE;
+virtual void DeleteTextures(GLsizei n, const GLuint* textures) OVERRIDE;
+virtual void DepthFunc(GLenum func) OVERRIDE;
+virtual void DepthMask(GLboolean flag) OVERRIDE;
+virtual void DepthRangef(GLclampf zNear, GLclampf zFar) OVERRIDE;
+virtual void DetachShader(GLuint program, GLuint shader) OVERRIDE;
+virtual void Disable(GLenum cap) OVERRIDE;
+virtual void DisableVertexAttribArray(GLuint index) OVERRIDE;
+virtual void DrawArrays(GLenum mode, GLint first, GLsizei count) OVERRIDE;
+virtual void DrawElements(
+    GLenum mode, GLsizei count, GLenum type, const void* indices) OVERRIDE;
+virtual void Enable(GLenum cap) OVERRIDE;
+virtual void EnableVertexAttribArray(GLuint index) OVERRIDE;
+virtual void Finish() OVERRIDE;
+virtual void Flush() OVERRIDE;
+virtual void ShallowFlushCHROMIUM() OVERRIDE;
+virtual void FramebufferRenderbuffer(
+    GLenum target, GLenum attachment, GLenum renderbuffertarget,
+    GLuint renderbuffer) OVERRIDE;
+virtual void FramebufferTexture2D(
+    GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
+    GLint level) OVERRIDE;
+virtual void FrontFace(GLenum mode) OVERRIDE;
+virtual void GenBuffers(GLsizei n, GLuint* buffers) OVERRIDE;
+virtual void GenerateMipmap(GLenum target) OVERRIDE;
+virtual void GenFramebuffers(GLsizei n, GLuint* framebuffers) OVERRIDE;
+virtual void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) OVERRIDE;
+virtual void GenTextures(GLsizei n, GLuint* textures) OVERRIDE;
+virtual void GetActiveAttrib(
+    GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
+    GLenum* type, char* name) OVERRIDE;
+virtual void GetActiveUniform(
+    GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size,
+    GLenum* type, char* name) OVERRIDE;
+virtual void GetAttachedShaders(
+    GLuint program, GLsizei maxcount, GLsizei* count,
+    GLuint* shaders) OVERRIDE;
+virtual GLint GetAttribLocation(GLuint program, const char* name) OVERRIDE;
+virtual void GetBooleanv(GLenum pname, GLboolean* params) OVERRIDE;
+virtual void GetBufferParameteriv(
+    GLenum target, GLenum pname, GLint* params) OVERRIDE;
+virtual GLenum GetError() OVERRIDE;
+virtual void GetFloatv(GLenum pname, GLfloat* params) OVERRIDE;
+virtual void GetFramebufferAttachmentParameteriv(
+    GLenum target, GLenum attachment, GLenum pname, GLint* params) OVERRIDE;
+virtual void GetIntegerv(GLenum pname, GLint* params) OVERRIDE;
+virtual void GetProgramiv(
+    GLuint program, GLenum pname, GLint* params) OVERRIDE;
+virtual void GetProgramInfoLog(
+    GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) OVERRIDE;
+virtual void GetRenderbufferParameteriv(
+    GLenum target, GLenum pname, GLint* params) OVERRIDE;
+virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) OVERRIDE;
+virtual void GetShaderInfoLog(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) OVERRIDE;
+virtual void GetShaderPrecisionFormat(
+    GLenum shadertype, GLenum precisiontype, GLint* range,
+    GLint* precision) OVERRIDE;
+virtual void GetShaderSource(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) OVERRIDE;
+virtual const GLubyte* GetString(GLenum name) OVERRIDE;
+virtual void GetTexParameterfv(
+    GLenum target, GLenum pname, GLfloat* params) OVERRIDE;
+virtual void GetTexParameteriv(
+    GLenum target, GLenum pname, GLint* params) OVERRIDE;
+virtual void GetUniformfv(
+    GLuint program, GLint location, GLfloat* params) OVERRIDE;
+virtual void GetUniformiv(
+    GLuint program, GLint location, GLint* params) OVERRIDE;
+virtual GLint GetUniformLocation(GLuint program, const char* name) OVERRIDE;
+virtual void GetVertexAttribfv(
+    GLuint index, GLenum pname, GLfloat* params) OVERRIDE;
+virtual void GetVertexAttribiv(
+    GLuint index, GLenum pname, GLint* params) OVERRIDE;
+virtual void GetVertexAttribPointerv(
+    GLuint index, GLenum pname, void** pointer) OVERRIDE;
+virtual void Hint(GLenum target, GLenum mode) OVERRIDE;
+virtual GLboolean IsBuffer(GLuint buffer) OVERRIDE;
+virtual GLboolean IsEnabled(GLenum cap) OVERRIDE;
+virtual GLboolean IsFramebuffer(GLuint framebuffer) OVERRIDE;
+virtual GLboolean IsProgram(GLuint program) OVERRIDE;
+virtual GLboolean IsRenderbuffer(GLuint renderbuffer) OVERRIDE;
+virtual GLboolean IsShader(GLuint shader) OVERRIDE;
+virtual GLboolean IsTexture(GLuint texture) OVERRIDE;
+virtual void LineWidth(GLfloat width) OVERRIDE;
+virtual void LinkProgram(GLuint program) OVERRIDE;
+virtual void PixelStorei(GLenum pname, GLint param) OVERRIDE;
+virtual void PolygonOffset(GLfloat factor, GLfloat units) OVERRIDE;
+virtual void ReadPixels(
+    GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type,
+    void* pixels) OVERRIDE;
+virtual void ReleaseShaderCompiler() OVERRIDE;
+virtual void RenderbufferStorage(
+    GLenum target, GLenum internalformat, GLsizei width,
+    GLsizei height) OVERRIDE;
+virtual void SampleCoverage(GLclampf value, GLboolean invert) OVERRIDE;
+virtual void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) OVERRIDE;
+virtual void ShaderBinary(
+    GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary,
+    GLsizei length) OVERRIDE;
+virtual void ShaderSource(
+    GLuint shader, GLsizei count, const char** str,
+    const GLint* length) OVERRIDE;
+virtual void StencilFunc(GLenum func, GLint ref, GLuint mask) OVERRIDE;
+virtual void StencilFuncSeparate(
+    GLenum face, GLenum func, GLint ref, GLuint mask) OVERRIDE;
+virtual void StencilMask(GLuint mask) OVERRIDE;
+virtual void StencilMaskSeparate(GLenum face, GLuint mask) OVERRIDE;
+virtual void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) OVERRIDE;
+virtual void StencilOpSeparate(
+    GLenum face, GLenum fail, GLenum zfail, GLenum zpass) OVERRIDE;
+virtual void TexImage2D(
+    GLenum target, GLint level, GLint internalformat, GLsizei width,
+    GLsizei height, GLint border, GLenum format, GLenum type,
+    const void* pixels) OVERRIDE;
+virtual void TexParameterf(
+    GLenum target, GLenum pname, GLfloat param) OVERRIDE;
+virtual void TexParameterfv(
+    GLenum target, GLenum pname, const GLfloat* params) OVERRIDE;
+virtual void TexParameteri(GLenum target, GLenum pname, GLint param) OVERRIDE;
+virtual void TexParameteriv(
+    GLenum target, GLenum pname, const GLint* params) OVERRIDE;
+virtual void TexSubImage2D(
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+    GLsizei height, GLenum format, GLenum type, const void* pixels) OVERRIDE;
+virtual void Uniform1f(GLint location, GLfloat x) OVERRIDE;
+virtual void Uniform1fv(
+    GLint location, GLsizei count, const GLfloat* v) OVERRIDE;
+virtual void Uniform1i(GLint location, GLint x) OVERRIDE;
+virtual void Uniform1iv(
+    GLint location, GLsizei count, const GLint* v) OVERRIDE;
+virtual void Uniform2f(GLint location, GLfloat x, GLfloat y) OVERRIDE;
+virtual void Uniform2fv(
+    GLint location, GLsizei count, const GLfloat* v) OVERRIDE;
+virtual void Uniform2i(GLint location, GLint x, GLint y) OVERRIDE;
+virtual void Uniform2iv(
+    GLint location, GLsizei count, const GLint* v) OVERRIDE;
+virtual void Uniform3f(
+    GLint location, GLfloat x, GLfloat y, GLfloat z) OVERRIDE;
+virtual void Uniform3fv(
+    GLint location, GLsizei count, const GLfloat* v) OVERRIDE;
+virtual void Uniform3i(GLint location, GLint x, GLint y, GLint z) OVERRIDE;
+virtual void Uniform3iv(
+    GLint location, GLsizei count, const GLint* v) OVERRIDE;
+virtual void Uniform4f(
+    GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) OVERRIDE;
+virtual void Uniform4fv(
+    GLint location, GLsizei count, const GLfloat* v) OVERRIDE;
+virtual void Uniform4i(
+    GLint location, GLint x, GLint y, GLint z, GLint w) OVERRIDE;
+virtual void Uniform4iv(
+    GLint location, GLsizei count, const GLint* v) OVERRIDE;
+virtual void UniformMatrix2fv(
+    GLint location, GLsizei count, GLboolean transpose,
+    const GLfloat* value) OVERRIDE;
+virtual void UniformMatrix3fv(
+    GLint location, GLsizei count, GLboolean transpose,
+    const GLfloat* value) OVERRIDE;
+virtual void UniformMatrix4fv(
+    GLint location, GLsizei count, GLboolean transpose,
+    const GLfloat* value) OVERRIDE;
+virtual void UseProgram(GLuint program) OVERRIDE;
+virtual void ValidateProgram(GLuint program) OVERRIDE;
+virtual void VertexAttrib1f(GLuint indx, GLfloat x) OVERRIDE;
+virtual void VertexAttrib1fv(GLuint indx, const GLfloat* values) OVERRIDE;
+virtual void VertexAttrib2f(GLuint indx, GLfloat x, GLfloat y) OVERRIDE;
+virtual void VertexAttrib2fv(GLuint indx, const GLfloat* values) OVERRIDE;
+virtual void VertexAttrib3f(
+    GLuint indx, GLfloat x, GLfloat y, GLfloat z) OVERRIDE;
+virtual void VertexAttrib3fv(GLuint indx, const GLfloat* values) OVERRIDE;
+virtual void VertexAttrib4f(
+    GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) OVERRIDE;
+virtual void VertexAttrib4fv(GLuint indx, const GLfloat* values) OVERRIDE;
+virtual void VertexAttribPointer(
+    GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride,
+    const void* ptr) OVERRIDE;
+virtual void Viewport(
+    GLint x, GLint y, GLsizei width, GLsizei height) OVERRIDE;
+virtual void BlitFramebufferEXT(
+    GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
+    GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask,
+    GLenum filter) OVERRIDE;
+virtual void RenderbufferStorageMultisampleEXT(
+    GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
+    GLsizei height) OVERRIDE;
+virtual void TexStorage2DEXT(
+    GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width,
+    GLsizei height) OVERRIDE;
+virtual void GenQueriesEXT(GLsizei n, GLuint* queries) OVERRIDE;
+virtual void DeleteQueriesEXT(GLsizei n, const GLuint* queries) OVERRIDE;
+virtual GLboolean IsQueryEXT(GLuint id) OVERRIDE;
+virtual void BeginQueryEXT(GLenum target, GLuint id) OVERRIDE;
+virtual void EndQueryEXT(GLenum target) OVERRIDE;
+virtual void GetQueryivEXT(
+    GLenum target, GLenum pname, GLint* params) OVERRIDE;
+virtual void GetQueryObjectuivEXT(
+    GLuint id, GLenum pname, GLuint* params) OVERRIDE;
+virtual void InsertEventMarkerEXT(
+    GLsizei length, const GLchar* marker) OVERRIDE;
+virtual void PushGroupMarkerEXT(GLsizei length, const GLchar* marker) OVERRIDE;
+virtual void PopGroupMarkerEXT() OVERRIDE;
+virtual void GenVertexArraysOES(GLsizei n, GLuint* arrays) OVERRIDE;
+virtual void DeleteVertexArraysOES(GLsizei n, const GLuint* arrays) OVERRIDE;
+virtual GLboolean IsVertexArrayOES(GLuint array) OVERRIDE;
+virtual void BindVertexArrayOES(GLuint array) OVERRIDE;
+virtual void SwapBuffers() OVERRIDE;
+virtual GLuint GetMaxValueInBufferCHROMIUM(
+    GLuint buffer_id, GLsizei count, GLenum type, GLuint offset) OVERRIDE;
+virtual void GenSharedIdsCHROMIUM(
+    GLuint namespace_id, GLuint id_offset, GLsizei n, GLuint* ids) OVERRIDE;
+virtual void DeleteSharedIdsCHROMIUM(
+    GLuint namespace_id, GLsizei n, const GLuint* ids) OVERRIDE;
+virtual void RegisterSharedIdsCHROMIUM(
+    GLuint namespace_id, GLsizei n, const GLuint* ids) OVERRIDE;
+virtual GLboolean EnableFeatureCHROMIUM(const char* feature) OVERRIDE;
+virtual void* MapBufferSubDataCHROMIUM(
+    GLuint target, GLintptr offset, GLsizeiptr size, GLenum access) OVERRIDE;
+virtual void UnmapBufferSubDataCHROMIUM(const void* mem) OVERRIDE;
+virtual void* MapTexSubImage2DCHROMIUM(
+    GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+    GLsizei height, GLenum format, GLenum type, GLenum access) OVERRIDE;
+virtual void UnmapTexSubImage2DCHROMIUM(const void* mem) OVERRIDE;
+virtual void ResizeCHROMIUM(GLuint width, GLuint height) OVERRIDE;
+virtual const GLchar* GetRequestableExtensionsCHROMIUM() OVERRIDE;
+virtual void RequestExtensionCHROMIUM(const char* extension) OVERRIDE;
+virtual void RateLimitOffscreenContextCHROMIUM() OVERRIDE;
+virtual void GetMultipleIntegervCHROMIUM(
+    const GLenum* pnames, GLuint count, GLint* results,
+    GLsizeiptr size) OVERRIDE;
+virtual void GetProgramInfoCHROMIUM(
+    GLuint program, GLsizei bufsize, GLsizei* size, void* info) OVERRIDE;
+virtual GLuint CreateStreamTextureCHROMIUM(GLuint texture) OVERRIDE;
+virtual void DestroyStreamTextureCHROMIUM(GLuint texture) OVERRIDE;
+virtual void GetTranslatedShaderSourceANGLE(
+    GLuint shader, GLsizei bufsize, GLsizei* length, char* source) OVERRIDE;
+virtual void PostSubBufferCHROMIUM(
+    GLint x, GLint y, GLint width, GLint height) OVERRIDE;
+virtual void TexImageIOSurface2DCHROMIUM(
+    GLenum target, GLsizei width, GLsizei height, GLuint ioSurfaceId,
+    GLuint plane) OVERRIDE;
+virtual void CopyTextureCHROMIUM(
+    GLenum target, GLenum source_id, GLenum dest_id, GLint level,
+    GLint internalformat) OVERRIDE;
+virtual void DrawArraysInstancedANGLE(
+    GLenum mode, GLint first, GLsizei count, GLsizei primcount) OVERRIDE;
+virtual void DrawElementsInstancedANGLE(
+    GLenum mode, GLsizei count, GLenum type, const void* indices,
+    GLsizei primcount) OVERRIDE;
+virtual void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) OVERRIDE;
+virtual void GenMailboxCHROMIUM(GLbyte* mailbox) OVERRIDE;
+virtual void ProduceTextureCHROMIUM(
+    GLenum target, const GLbyte* mailbox) OVERRIDE;
+virtual void ConsumeTextureCHROMIUM(
+    GLenum target, const GLbyte* mailbox) OVERRIDE;
+virtual void BindUniformLocationCHROMIUM(
+    GLuint program, GLint location, const char* name) OVERRIDE;
+#endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_
+
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
new file mode 100644
index 0000000..b69ce2f
--- /dev/null
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -0,0 +1,600 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is auto-generated from
+// gpu/command_buffer/build_gles2_cmd_buffer.py
+// DO NOT EDIT!
+
+// This file is included by gles2_interface_stub.cc.
+#ifndef GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_
+#define GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_
+
+void GLES2InterfaceStub::ActiveTexture(GLenum /* texture */) {
+}
+void GLES2InterfaceStub::AttachShader(
+    GLuint /* program */, GLuint /* shader */) {
+}
+void GLES2InterfaceStub::BindAttribLocation(
+    GLuint /* program */, GLuint /* index */, const char* /* name */) {
+}
+void GLES2InterfaceStub::BindBuffer(GLenum /* target */, GLuint /* buffer */) {
+}
+void GLES2InterfaceStub::BindFramebuffer(
+    GLenum /* target */, GLuint /* framebuffer */) {
+}
+void GLES2InterfaceStub::BindRenderbuffer(
+    GLenum /* target */, GLuint /* renderbuffer */) {
+}
+void GLES2InterfaceStub::BindTexture(
+    GLenum /* target */, GLuint /* texture */) {
+}
+void GLES2InterfaceStub::BlendColor(
+    GLclampf /* red */, GLclampf /* green */, GLclampf /* blue */,
+    GLclampf /* alpha */) {
+}
+void GLES2InterfaceStub::BlendEquation(GLenum /* mode */) {
+}
+void GLES2InterfaceStub::BlendEquationSeparate(
+    GLenum /* modeRGB */, GLenum /* modeAlpha */) {
+}
+void GLES2InterfaceStub::BlendFunc(
+    GLenum /* sfactor */, GLenum /* dfactor */) {
+}
+void GLES2InterfaceStub::BlendFuncSeparate(
+    GLenum /* srcRGB */, GLenum /* dstRGB */, GLenum /* srcAlpha */,
+    GLenum /* dstAlpha */) {
+}
+void GLES2InterfaceStub::BufferData(
+    GLenum /* target */, GLsizeiptr /* size */, const void* /* data */,
+    GLenum /* usage */) {
+}
+void GLES2InterfaceStub::BufferSubData(
+    GLenum /* target */, GLintptr /* offset */, GLsizeiptr /* size */,
+    const void* /* data */) {
+}
+GLenum GLES2InterfaceStub::CheckFramebufferStatus(GLenum /* target */) {
+  return 0;
+}
+void GLES2InterfaceStub::Clear(GLbitfield /* mask */) {
+}
+void GLES2InterfaceStub::ClearColor(
+    GLclampf /* red */, GLclampf /* green */, GLclampf /* blue */,
+    GLclampf /* alpha */) {
+}
+void GLES2InterfaceStub::ClearDepthf(GLclampf /* depth */) {
+}
+void GLES2InterfaceStub::ClearStencil(GLint /* s */) {
+}
+void GLES2InterfaceStub::ColorMask(
+    GLboolean /* red */, GLboolean /* green */, GLboolean /* blue */,
+    GLboolean /* alpha */) {
+}
+void GLES2InterfaceStub::CompileShader(GLuint /* shader */) {
+}
+void GLES2InterfaceStub::CompressedTexImage2D(
+    GLenum /* target */, GLint /* level */, GLenum /* internalformat */,
+    GLsizei /* width */, GLsizei /* height */, GLint /* border */,
+    GLsizei /* imageSize */, const void* /* data */) {
+}
+void GLES2InterfaceStub::CompressedTexSubImage2D(
+    GLenum /* target */, GLint /* level */, GLint /* xoffset */,
+    GLint /* yoffset */, GLsizei /* width */, GLsizei /* height */,
+    GLenum /* format */, GLsizei /* imageSize */, const void* /* data */) {
+}
+void GLES2InterfaceStub::CopyTexImage2D(
+    GLenum /* target */, GLint /* level */, GLenum /* internalformat */,
+    GLint /* x */, GLint /* y */, GLsizei /* width */, GLsizei /* height */,
+    GLint /* border */) {
+}
+void GLES2InterfaceStub::CopyTexSubImage2D(
+    GLenum /* target */, GLint /* level */, GLint /* xoffset */,
+    GLint /* yoffset */, GLint /* x */, GLint /* y */, GLsizei /* width */,
+    GLsizei /* height */) {
+}
+GLuint GLES2InterfaceStub::CreateProgram() {
+  return 0;
+}
+GLuint GLES2InterfaceStub::CreateShader(GLenum /* type */) {
+  return 0;
+}
+void GLES2InterfaceStub::CullFace(GLenum /* mode */) {
+}
+void GLES2InterfaceStub::DeleteBuffers(
+    GLsizei /* n */, const GLuint* /* buffers */) {
+}
+void GLES2InterfaceStub::DeleteFramebuffers(
+    GLsizei /* n */, const GLuint* /* framebuffers */) {
+}
+void GLES2InterfaceStub::DeleteProgram(GLuint /* program */) {
+}
+void GLES2InterfaceStub::DeleteRenderbuffers(
+    GLsizei /* n */, const GLuint* /* renderbuffers */) {
+}
+void GLES2InterfaceStub::DeleteShader(GLuint /* shader */) {
+}
+void GLES2InterfaceStub::DeleteTextures(
+    GLsizei /* n */, const GLuint* /* textures */) {
+}
+void GLES2InterfaceStub::DepthFunc(GLenum /* func */) {
+}
+void GLES2InterfaceStub::DepthMask(GLboolean /* flag */) {
+}
+void GLES2InterfaceStub::DepthRangef(
+    GLclampf /* zNear */, GLclampf /* zFar */) {
+}
+void GLES2InterfaceStub::DetachShader(
+    GLuint /* program */, GLuint /* shader */) {
+}
+void GLES2InterfaceStub::Disable(GLenum /* cap */) {
+}
+void GLES2InterfaceStub::DisableVertexAttribArray(GLuint /* index */) {
+}
+void GLES2InterfaceStub::DrawArrays(
+    GLenum /* mode */, GLint /* first */, GLsizei /* count */) {
+}
+void GLES2InterfaceStub::DrawElements(
+    GLenum /* mode */, GLsizei /* count */, GLenum /* type */,
+    const void* /* indices */) {
+}
+void GLES2InterfaceStub::Enable(GLenum /* cap */) {
+}
+void GLES2InterfaceStub::EnableVertexAttribArray(GLuint /* index */) {
+}
+void GLES2InterfaceStub::Finish() {
+}
+void GLES2InterfaceStub::Flush() {
+}
+void GLES2InterfaceStub::ShallowFlushCHROMIUM() {
+}
+void GLES2InterfaceStub::FramebufferRenderbuffer(
+    GLenum /* target */, GLenum /* attachment */,
+    GLenum /* renderbuffertarget */, GLuint /* renderbuffer */) {
+}
+void GLES2InterfaceStub::FramebufferTexture2D(
+    GLenum /* target */, GLenum /* attachment */, GLenum /* textarget */,
+    GLuint /* texture */, GLint /* level */) {
+}
+void GLES2InterfaceStub::FrontFace(GLenum /* mode */) {
+}
+void GLES2InterfaceStub::GenBuffers(GLsizei /* n */, GLuint* /* buffers */) {
+}
+void GLES2InterfaceStub::GenerateMipmap(GLenum /* target */) {
+}
+void GLES2InterfaceStub::GenFramebuffers(
+    GLsizei /* n */, GLuint* /* framebuffers */) {
+}
+void GLES2InterfaceStub::GenRenderbuffers(
+    GLsizei /* n */, GLuint* /* renderbuffers */) {
+}
+void GLES2InterfaceStub::GenTextures(GLsizei /* n */, GLuint* /* textures */) {
+}
+void GLES2InterfaceStub::GetActiveAttrib(
+    GLuint /* program */, GLuint /* index */, GLsizei /* bufsize */,
+    GLsizei* /* length */, GLint* /* size */, GLenum* /* type */,
+    char* /* name */) {
+}
+void GLES2InterfaceStub::GetActiveUniform(
+    GLuint /* program */, GLuint /* index */, GLsizei /* bufsize */,
+    GLsizei* /* length */, GLint* /* size */, GLenum* /* type */,
+    char* /* name */) {
+}
+void GLES2InterfaceStub::GetAttachedShaders(
+    GLuint /* program */, GLsizei /* maxcount */, GLsizei* /* count */,
+    GLuint* /* shaders */) {
+}
+GLint GLES2InterfaceStub::GetAttribLocation(
+    GLuint /* program */, const char* /* name */) {
+  return 0;
+}
+void GLES2InterfaceStub::GetBooleanv(
+    GLenum /* pname */, GLboolean* /* params */) {
+}
+void GLES2InterfaceStub::GetBufferParameteriv(
+    GLenum /* target */, GLenum /* pname */, GLint* /* params */) {
+}
+GLenum GLES2InterfaceStub::GetError() {
+  return 0;
+}
+void GLES2InterfaceStub::GetFloatv(GLenum /* pname */, GLfloat* /* params */) {
+}
+void GLES2InterfaceStub::GetFramebufferAttachmentParameteriv(
+    GLenum /* target */, GLenum /* attachment */, GLenum /* pname */,
+    GLint* /* params */) {
+}
+void GLES2InterfaceStub::GetIntegerv(GLenum /* pname */, GLint* /* params */) {
+}
+void GLES2InterfaceStub::GetProgramiv(
+    GLuint /* program */, GLenum /* pname */, GLint* /* params */) {
+}
+void GLES2InterfaceStub::GetProgramInfoLog(
+    GLuint /* program */, GLsizei /* bufsize */, GLsizei* /* length */,
+    char* /* infolog */) {
+}
+void GLES2InterfaceStub::GetRenderbufferParameteriv(
+    GLenum /* target */, GLenum /* pname */, GLint* /* params */) {
+}
+void GLES2InterfaceStub::GetShaderiv(
+    GLuint /* shader */, GLenum /* pname */, GLint* /* params */) {
+}
+void GLES2InterfaceStub::GetShaderInfoLog(
+    GLuint /* shader */, GLsizei /* bufsize */, GLsizei* /* length */,
+    char* /* infolog */) {
+}
+void GLES2InterfaceStub::GetShaderPrecisionFormat(
+    GLenum /* shadertype */, GLenum /* precisiontype */, GLint* /* range */,
+    GLint* /* precision */) {
+}
+void GLES2InterfaceStub::GetShaderSource(
+    GLuint /* shader */, GLsizei /* bufsize */, GLsizei* /* length */,
+    char* /* source */) {
+}
+const GLubyte* GLES2InterfaceStub::GetString(GLenum /* name */) {
+  return 0;
+}
+void GLES2InterfaceStub::GetTexParameterfv(
+    GLenum /* target */, GLenum /* pname */, GLfloat* /* params */) {
+}
+void GLES2InterfaceStub::GetTexParameteriv(
+    GLenum /* target */, GLenum /* pname */, GLint* /* params */) {
+}
+void GLES2InterfaceStub::GetUniformfv(
+    GLuint /* program */, GLint /* location */, GLfloat* /* params */) {
+}
+void GLES2InterfaceStub::GetUniformiv(
+    GLuint /* program */, GLint /* location */, GLint* /* params */) {
+}
+GLint GLES2InterfaceStub::GetUniformLocation(
+    GLuint /* program */, const char* /* name */) {
+  return 0;
+}
+void GLES2InterfaceStub::GetVertexAttribfv(
+    GLuint /* index */, GLenum /* pname */, GLfloat* /* params */) {
+}
+void GLES2InterfaceStub::GetVertexAttribiv(
+    GLuint /* index */, GLenum /* pname */, GLint* /* params */) {
+}
+void GLES2InterfaceStub::GetVertexAttribPointerv(
+    GLuint /* index */, GLenum /* pname */, void** /* pointer */) {
+}
+void GLES2InterfaceStub::Hint(GLenum /* target */, GLenum /* mode */) {
+}
+GLboolean GLES2InterfaceStub::IsBuffer(GLuint /* buffer */) {
+  return 0;
+}
+GLboolean GLES2InterfaceStub::IsEnabled(GLenum /* cap */) {
+  return 0;
+}
+GLboolean GLES2InterfaceStub::IsFramebuffer(GLuint /* framebuffer */) {
+  return 0;
+}
+GLboolean GLES2InterfaceStub::IsProgram(GLuint /* program */) {
+  return 0;
+}
+GLboolean GLES2InterfaceStub::IsRenderbuffer(GLuint /* renderbuffer */) {
+  return 0;
+}
+GLboolean GLES2InterfaceStub::IsShader(GLuint /* shader */) {
+  return 0;
+}
+GLboolean GLES2InterfaceStub::IsTexture(GLuint /* texture */) {
+  return 0;
+}
+void GLES2InterfaceStub::LineWidth(GLfloat /* width */) {
+}
+void GLES2InterfaceStub::LinkProgram(GLuint /* program */) {
+}
+void GLES2InterfaceStub::PixelStorei(GLenum /* pname */, GLint /* param */) {
+}
+void GLES2InterfaceStub::PolygonOffset(
+    GLfloat /* factor */, GLfloat /* units */) {
+}
+void GLES2InterfaceStub::ReadPixels(
+    GLint /* x */, GLint /* y */, GLsizei /* width */, GLsizei /* height */,
+    GLenum /* format */, GLenum /* type */, void* /* pixels */) {
+}
+void GLES2InterfaceStub::ReleaseShaderCompiler() {
+}
+void GLES2InterfaceStub::RenderbufferStorage(
+    GLenum /* target */, GLenum /* internalformat */, GLsizei /* width */,
+    GLsizei /* height */) {
+}
+void GLES2InterfaceStub::SampleCoverage(
+    GLclampf /* value */, GLboolean /* invert */) {
+}
+void GLES2InterfaceStub::Scissor(
+    GLint /* x */, GLint /* y */, GLsizei /* width */, GLsizei /* height */) {
+}
+void GLES2InterfaceStub::ShaderBinary(
+    GLsizei /* n */, const GLuint* /* shaders */, GLenum /* binaryformat */,
+    const void* /* binary */, GLsizei /* length */) {
+}
+void GLES2InterfaceStub::ShaderSource(
+    GLuint /* shader */, GLsizei /* count */, const char** /* str */,
+    const GLint* /* length */) {
+}
+void GLES2InterfaceStub::StencilFunc(
+    GLenum /* func */, GLint /* ref */, GLuint /* mask */) {
+}
+void GLES2InterfaceStub::StencilFuncSeparate(
+    GLenum /* face */, GLenum /* func */, GLint /* ref */, GLuint /* mask */) {
+}
+void GLES2InterfaceStub::StencilMask(GLuint /* mask */) {
+}
+void GLES2InterfaceStub::StencilMaskSeparate(
+    GLenum /* face */, GLuint /* mask */) {
+}
+void GLES2InterfaceStub::StencilOp(
+    GLenum /* fail */, GLenum /* zfail */, GLenum /* zpass */) {
+}
+void GLES2InterfaceStub::StencilOpSeparate(
+    GLenum /* face */, GLenum /* fail */, GLenum /* zfail */,
+    GLenum /* zpass */) {
+}
+void GLES2InterfaceStub::TexImage2D(
+    GLenum /* target */, GLint /* level */, GLint /* internalformat */,
+    GLsizei /* width */, GLsizei /* height */, GLint /* border */,
+    GLenum /* format */, GLenum /* type */, const void* /* pixels */) {
+}
+void GLES2InterfaceStub::TexParameterf(
+    GLenum /* target */, GLenum /* pname */, GLfloat /* param */) {
+}
+void GLES2InterfaceStub::TexParameterfv(
+    GLenum /* target */, GLenum /* pname */, const GLfloat* /* params */) {
+}
+void GLES2InterfaceStub::TexParameteri(
+    GLenum /* target */, GLenum /* pname */, GLint /* param */) {
+}
+void GLES2InterfaceStub::TexParameteriv(
+    GLenum /* target */, GLenum /* pname */, const GLint* /* params */) {
+}
+void GLES2InterfaceStub::TexSubImage2D(
+    GLenum /* target */, GLint /* level */, GLint /* xoffset */,
+    GLint /* yoffset */, GLsizei /* width */, GLsizei /* height */,
+    GLenum /* format */, GLenum /* type */, const void* /* pixels */) {
+}
+void GLES2InterfaceStub::Uniform1f(GLint /* location */, GLfloat /* x */) {
+}
+void GLES2InterfaceStub::Uniform1fv(
+    GLint /* location */, GLsizei /* count */, const GLfloat* /* v */) {
+}
+void GLES2InterfaceStub::Uniform1i(GLint /* location */, GLint /* x */) {
+}
+void GLES2InterfaceStub::Uniform1iv(
+    GLint /* location */, GLsizei /* count */, const GLint* /* v */) {
+}
+void GLES2InterfaceStub::Uniform2f(
+    GLint /* location */, GLfloat /* x */, GLfloat /* y */) {
+}
+void GLES2InterfaceStub::Uniform2fv(
+    GLint /* location */, GLsizei /* count */, const GLfloat* /* v */) {
+}
+void GLES2InterfaceStub::Uniform2i(
+    GLint /* location */, GLint /* x */, GLint /* y */) {
+}
+void GLES2InterfaceStub::Uniform2iv(
+    GLint /* location */, GLsizei /* count */, const GLint* /* v */) {
+}
+void GLES2InterfaceStub::Uniform3f(
+    GLint /* location */, GLfloat /* x */, GLfloat /* y */, GLfloat /* z */) {
+}
+void GLES2InterfaceStub::Uniform3fv(
+    GLint /* location */, GLsizei /* count */, const GLfloat* /* v */) {
+}
+void GLES2InterfaceStub::Uniform3i(
+    GLint /* location */, GLint /* x */, GLint /* y */, GLint /* z */) {
+}
+void GLES2InterfaceStub::Uniform3iv(
+    GLint /* location */, GLsizei /* count */, const GLint* /* v */) {
+}
+void GLES2InterfaceStub::Uniform4f(
+    GLint /* location */, GLfloat /* x */, GLfloat /* y */, GLfloat /* z */,
+    GLfloat /* w */) {
+}
+void GLES2InterfaceStub::Uniform4fv(
+    GLint /* location */, GLsizei /* count */, const GLfloat* /* v */) {
+}
+void GLES2InterfaceStub::Uniform4i(
+    GLint /* location */, GLint /* x */, GLint /* y */, GLint /* z */,
+    GLint /* w */) {
+}
+void GLES2InterfaceStub::Uniform4iv(
+    GLint /* location */, GLsizei /* count */, const GLint* /* v */) {
+}
+void GLES2InterfaceStub::UniformMatrix2fv(
+    GLint /* location */, GLsizei /* count */, GLboolean /* transpose */,
+    const GLfloat* /* value */) {
+}
+void GLES2InterfaceStub::UniformMatrix3fv(
+    GLint /* location */, GLsizei /* count */, GLboolean /* transpose */,
+    const GLfloat* /* value */) {
+}
+void GLES2InterfaceStub::UniformMatrix4fv(
+    GLint /* location */, GLsizei /* count */, GLboolean /* transpose */,
+    const GLfloat* /* value */) {
+}
+void GLES2InterfaceStub::UseProgram(GLuint /* program */) {
+}
+void GLES2InterfaceStub::ValidateProgram(GLuint /* program */) {
+}
+void GLES2InterfaceStub::VertexAttrib1f(GLuint /* indx */, GLfloat /* x */) {
+}
+void GLES2InterfaceStub::VertexAttrib1fv(
+    GLuint /* indx */, const GLfloat* /* values */) {
+}
+void GLES2InterfaceStub::VertexAttrib2f(
+    GLuint /* indx */, GLfloat /* x */, GLfloat /* y */) {
+}
+void GLES2InterfaceStub::VertexAttrib2fv(
+    GLuint /* indx */, const GLfloat* /* values */) {
+}
+void GLES2InterfaceStub::VertexAttrib3f(
+    GLuint /* indx */, GLfloat /* x */, GLfloat /* y */, GLfloat /* z */) {
+}
+void GLES2InterfaceStub::VertexAttrib3fv(
+    GLuint /* indx */, const GLfloat* /* values */) {
+}
+void GLES2InterfaceStub::VertexAttrib4f(
+    GLuint /* indx */, GLfloat /* x */, GLfloat /* y */, GLfloat /* z */,
+    GLfloat /* w */) {
+}
+void GLES2InterfaceStub::VertexAttrib4fv(
+    GLuint /* indx */, const GLfloat* /* values */) {
+}
+void GLES2InterfaceStub::VertexAttribPointer(
+    GLuint /* indx */, GLint /* size */, GLenum /* type */,
+    GLboolean /* normalized */, GLsizei /* stride */, const void* /* ptr */) {
+}
+void GLES2InterfaceStub::Viewport(
+    GLint /* x */, GLint /* y */, GLsizei /* width */, GLsizei /* height */) {
+}
+void GLES2InterfaceStub::BlitFramebufferEXT(
+    GLint /* srcX0 */, GLint /* srcY0 */, GLint /* srcX1 */, GLint /* srcY1 */,
+    GLint /* dstX0 */, GLint /* dstY0 */, GLint /* dstX1 */, GLint /* dstY1 */,
+    GLbitfield /* mask */, GLenum /* filter */) {
+}
+void GLES2InterfaceStub::RenderbufferStorageMultisampleEXT(
+    GLenum /* target */, GLsizei /* samples */, GLenum /* internalformat */,
+    GLsizei /* width */, GLsizei /* height */) {
+}
+void GLES2InterfaceStub::TexStorage2DEXT(
+    GLenum /* target */, GLsizei /* levels */, GLenum /* internalFormat */,
+    GLsizei /* width */, GLsizei /* height */) {
+}
+void GLES2InterfaceStub::GenQueriesEXT(
+    GLsizei /* n */, GLuint* /* queries */) {
+}
+void GLES2InterfaceStub::DeleteQueriesEXT(
+    GLsizei /* n */, const GLuint* /* queries */) {
+}
+GLboolean GLES2InterfaceStub::IsQueryEXT(GLuint /* id */) {
+  return 0;
+}
+void GLES2InterfaceStub::BeginQueryEXT(GLenum /* target */, GLuint /* id */) {
+}
+void GLES2InterfaceStub::EndQueryEXT(GLenum /* target */) {
+}
+void GLES2InterfaceStub::GetQueryivEXT(
+    GLenum /* target */, GLenum /* pname */, GLint* /* params */) {
+}
+void GLES2InterfaceStub::GetQueryObjectuivEXT(
+    GLuint /* id */, GLenum /* pname */, GLuint* /* params */) {
+}
+void GLES2InterfaceStub::InsertEventMarkerEXT(
+    GLsizei /* length */, const GLchar* /* marker */) {
+}
+void GLES2InterfaceStub::PushGroupMarkerEXT(
+    GLsizei /* length */, const GLchar* /* marker */) {
+}
+void GLES2InterfaceStub::PopGroupMarkerEXT() {
+}
+void GLES2InterfaceStub::GenVertexArraysOES(
+    GLsizei /* n */, GLuint* /* arrays */) {
+}
+void GLES2InterfaceStub::DeleteVertexArraysOES(
+    GLsizei /* n */, const GLuint* /* arrays */) {
+}
+GLboolean GLES2InterfaceStub::IsVertexArrayOES(GLuint /* array */) {
+  return 0;
+}
+void GLES2InterfaceStub::BindVertexArrayOES(GLuint /* array */) {
+}
+void GLES2InterfaceStub::SwapBuffers() {
+}
+GLuint GLES2InterfaceStub::GetMaxValueInBufferCHROMIUM(
+    GLuint /* buffer_id */, GLsizei /* count */, GLenum /* type */,
+    GLuint /* offset */) {
+  return 0;
+}
+void GLES2InterfaceStub::GenSharedIdsCHROMIUM(
+    GLuint /* namespace_id */, GLuint /* id_offset */, GLsizei /* n */,
+    GLuint* /* ids */) {
+}
+void GLES2InterfaceStub::DeleteSharedIdsCHROMIUM(
+    GLuint /* namespace_id */, GLsizei /* n */, const GLuint* /* ids */) {
+}
+void GLES2InterfaceStub::RegisterSharedIdsCHROMIUM(
+    GLuint /* namespace_id */, GLsizei /* n */, const GLuint* /* ids */) {
+}
+GLboolean GLES2InterfaceStub::EnableFeatureCHROMIUM(
+    const char* /* feature */) {
+  return 0;
+}
+void* GLES2InterfaceStub::MapBufferSubDataCHROMIUM(
+    GLuint /* target */, GLintptr /* offset */, GLsizeiptr /* size */,
+    GLenum /* access */) {
+  return 0;
+}
+void GLES2InterfaceStub::UnmapBufferSubDataCHROMIUM(const void* /* mem */) {
+}
+void* GLES2InterfaceStub::MapTexSubImage2DCHROMIUM(
+    GLenum /* target */, GLint /* level */, GLint /* xoffset */,
+    GLint /* yoffset */, GLsizei /* width */, GLsizei /* height */,
+    GLenum /* format */, GLenum /* type */, GLenum /* access */) {
+  return 0;
+}
+void GLES2InterfaceStub::UnmapTexSubImage2DCHROMIUM(const void* /* mem */) {
+}
+void GLES2InterfaceStub::ResizeCHROMIUM(
+    GLuint /* width */, GLuint /* height */) {
+}
+const GLchar* GLES2InterfaceStub::GetRequestableExtensionsCHROMIUM() {
+  return 0;
+}
+void GLES2InterfaceStub::RequestExtensionCHROMIUM(
+    const char* /* extension */) {
+}
+void GLES2InterfaceStub::RateLimitOffscreenContextCHROMIUM() {
+}
+void GLES2InterfaceStub::GetMultipleIntegervCHROMIUM(
+    const GLenum* /* pnames */, GLuint /* count */, GLint* /* results */,
+    GLsizeiptr /* size */) {
+}
+void GLES2InterfaceStub::GetProgramInfoCHROMIUM(
+    GLuint /* program */, GLsizei /* bufsize */, GLsizei* /* size */,
+    void* /* info */) {
+}
+GLuint GLES2InterfaceStub::CreateStreamTextureCHROMIUM(GLuint /* texture */) {
+  return 0;
+}
+void GLES2InterfaceStub::DestroyStreamTextureCHROMIUM(GLuint /* texture */) {
+}
+void GLES2InterfaceStub::GetTranslatedShaderSourceANGLE(
+    GLuint /* shader */, GLsizei /* bufsize */, GLsizei* /* length */,
+    char* /* source */) {
+}
+void GLES2InterfaceStub::PostSubBufferCHROMIUM(
+    GLint /* x */, GLint /* y */, GLint /* width */, GLint /* height */) {
+}
+void GLES2InterfaceStub::TexImageIOSurface2DCHROMIUM(
+    GLenum /* target */, GLsizei /* width */, GLsizei /* height */,
+    GLuint /* ioSurfaceId */, GLuint /* plane */) {
+}
+void GLES2InterfaceStub::CopyTextureCHROMIUM(
+    GLenum /* target */, GLenum /* source_id */, GLenum /* dest_id */,
+    GLint /* level */, GLint /* internalformat */) {
+}
+void GLES2InterfaceStub::DrawArraysInstancedANGLE(
+    GLenum /* mode */, GLint /* first */, GLsizei /* count */,
+    GLsizei /* primcount */) {
+}
+void GLES2InterfaceStub::DrawElementsInstancedANGLE(
+    GLenum /* mode */, GLsizei /* count */, GLenum /* type */,
+    const void* /* indices */, GLsizei /* primcount */) {
+}
+void GLES2InterfaceStub::VertexAttribDivisorANGLE(
+    GLuint /* index */, GLuint /* divisor */) {
+}
+void GLES2InterfaceStub::GenMailboxCHROMIUM(GLbyte* /* mailbox */) {
+}
+void GLES2InterfaceStub::ProduceTextureCHROMIUM(
+    GLenum /* target */, const GLbyte* /* mailbox */) {
+}
+void GLES2InterfaceStub::ConsumeTextureCHROMIUM(
+    GLenum /* target */, const GLbyte* /* mailbox */) {
+}
+void GLES2InterfaceStub::BindUniformLocationCHROMIUM(
+    GLuint /* program */, GLint /* location */, const char* /* name */) {
+}
+#endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_
+
diff --git a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
index 034e6c4..f5023de 100644
--- a/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_utils_implementation_autogen.h
@@ -74,6 +74,8 @@
   { 0x88BB, "GL_BUFFER_ACCESS_OES", },
   { 0x88BC, "GL_BUFFER_MAPPED_OES", },
   { 0x88BD, "GL_BUFFER_MAP_POINTER_OES", },
+  { 0x904A, "GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX", },
+  { 0x904B, "GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX", },
   { 0x0C10, "GL_SCISSOR_BOX", },
   { 0x0C11, "GL_SCISSOR_TEST", },
   { 0x80000000, "GL_MULTISAMPLE_BUFFER_BIT7_QCOM", },
@@ -113,6 +115,9 @@
   { 0x8D40, "GL_FRAMEBUFFER", },
   { 0x8D41, "GL_RENDERBUFFER", },
   { 0x0BD0, "GL_DITHER", },
+  { 0x9047, "GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX", },
+  { 0x9049, "GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX", },
+  { 0x9048, "GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX", },
   { 0x1801, "GL_DEPTH_EXT", },
   { 0x1800, "GL_COLOR_EXT", },
   { 0x1802, "GL_STENCIL_EXT", },
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index fc4c6f4a..83a78158 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -149,6 +149,8 @@
         'command_buffer/client/client_test_helper.h',
         'command_buffer/client/cmd_buffer_helper_test.cc',
         'command_buffer/client/fenced_allocator_test.cc',
+        'command_buffer/client/gles2_interface_stub.cc',
+        'command_buffer/client/gles2_interface_stub.h',
         'command_buffer/client/gles2_implementation_unittest.cc',
         'command_buffer/client/mapped_memory_unittest.cc',
         'command_buffer/client/query_tracker_unittest.cc',
diff --git a/gpu/gpu_common.gypi b/gpu/gpu_common.gypi
index 4402e0b..24c7e4d1 100644
--- a/gpu/gpu_common.gypi
+++ b/gpu/gpu_common.gypi
@@ -23,6 +23,9 @@
       'command_buffer/client/gles2_implementation_autogen.h',
       'command_buffer/client/gles2_implementation.cc',
       'command_buffer/client/gles2_implementation.h',
+      'command_buffer/client/gles2_implementation_impl_autogen.h',
+      'command_buffer/client/gles2_interface.h',
+      'command_buffer/client/gles2_interface.cc',
       'command_buffer/client/program_info_manager.cc',
       'command_buffer/client/program_info_manager.h',
       'command_buffer/client/query_tracker.cc',