Adds a GLMock object so we can check the code is
correctly calling GL

Rather than make a GLBase with all virtual functions
I made it compile twice, once for shipping code where
it includes the local platform's gl.h and again for
unit tests where it includes gl_mock.h.

TEST=none
BUG=none

Review URL: http://codereview.chromium.org/511001

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@35210 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 d7878de6..b9bc4ec 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -2449,7 +2449,7 @@
 
   def WriteValidationCode(self, file):
     file.Write("  if (!Validate%s(%s)) {\n" % (self.enum_type, self.name))
-    file.Write("    SetGLError(GL_INVALID_VALUE);\n")
+    file.Write("    SetGLError(GL_INVALID_ENUM);\n")
     file.Write("    return parse_error::kParseNoError;\n")
     file.Write("  }\n")
 
@@ -3047,13 +3047,10 @@
     """Writes the command buffer format"""
     file = CWriter(filename)
     self.WriteHeader(file)
-    file.Write("#pragma pack(push, 1)\n")
-    file.Write("\n")
 
     for func in self.functions:
       func.WriteStruct(file)
 
-    file.Write("#pragma pack(pop)\n")
     file.Write("\n")
     file.Close()
 
diff --git a/gpu/command_buffer/common/gles2_cmd_format.h b/gpu/command_buffer/common/gles2_cmd_format.h
index e6f2b78..931b709 100644
--- a/gpu/command_buffer/common/gles2_cmd_format.h
+++ b/gpu/command_buffer/common/gles2_cmd_format.h
@@ -8,8 +8,11 @@
 #define GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_H_
 
 // This is here because service side code must include the system's version of
-// the GL headers where as client side code includes the Chrome version.
-#ifdef GLES2_GPU_SERVICE
+// the GL headers where as client side code includes the Chrome version. Also
+// the unit test code must include a mock GL header.
+#if defined(UNIT_TEST)
+#include "gpu/command_buffer/service/gl_mock.h"
+#elif defined(GLES2_GPU_SERVICE)
 #include <GL/glew.h>
 #if defined(OS_WIN)
 #include <GL/wglew.h>
@@ -27,6 +30,8 @@
 namespace gpu {
 namespace gles2 {
 
+#pragma pack(push, 1)
+
 #include "gpu/command_buffer/common/gles2_cmd_format_autogen.h"
 
 // These are hand written commands.
@@ -273,6 +278,7 @@
 COMPILE_ASSERT(offsetof(GetUniformLocationImmediate, data_size) == 16,
                OffsetOf_GetUniformLocationImmediate_data_size_not_16);
 
+#pragma pack(pop)
 
 }  // namespace gles2
 }  // namespace gpu
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index efa2538..5bff473 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -1,7 +1,5 @@
 // This file is auto-generated. DO NOT EDIT!
 
-#pragma pack(push, 1)
-
 struct ActiveTexture {
   typedef ActiveTexture ValueType;
   static const CommandId kCmdId = kActiveTexture;
@@ -8082,5 +8080,4 @@
 COMPILE_ASSERT(offsetof(SwapBuffers, header) == 0,
                OffsetOf_SwapBuffers_header_not_0);
 
-#pragma pack(pop)
 
diff --git a/gpu/command_buffer/service/gl_interface.cc b/gpu/command_buffer/service/gl_interface.cc
new file mode 100644
index 0000000..b077a84
--- /dev/null
+++ b/gpu/command_buffer/service/gl_interface.cc
@@ -0,0 +1,20 @@
+// Copyright (c) 2009 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/service/gl_interface.h"
+
+namespace gles2 {
+
+GLInterface* GLInterface::interface_;
+
+void GLInterface::SetGLInterface(GLInterface* gl_interface) {
+  interface_ = gl_interface;
+}
+
+GLInterface* GLInterface::GetGLInterface() {
+  return interface_;
+}
+
+}  // namespace gles2
+
diff --git a/gpu/command_buffer/service/gl_interface.h b/gpu/command_buffer/service/gl_interface.h
new file mode 100644
index 0000000..32b061f
--- /dev/null
+++ b/gpu/command_buffer/service/gl_interface.h
@@ -0,0 +1,531 @@
+// Copyright (c) 2009 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 implements glue to a GL interface so we can mock it for unit
+// testing. It has to be Desktop GL, not GLES2 as it is used to test the service
+// side code.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_GL_INTERFACE_H_
+#define GPU_COMMAND_BUFFER_SERVICE_GL_INTERFACE_H_
+
+#include <GLES2/gl2types.h>
+
+namespace gles2 {
+
+class GLInterface {
+ public:
+  virtual ~GLInterface() {
+  }
+
+  static void SetGLInterface(GLInterface* gl_interface);
+
+  static GLInterface* GetGLInterface();
+
+  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 BindFramebufferEXT(GLenum target, GLuint framebuffer) = 0;
+
+  virtual void BindRenderbufferEXT(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 CheckFramebufferStatusEXT(GLenum target) = 0;
+
+  virtual void Clear(GLbitfield mask) = 0;
+
+  virtual void ClearColor(
+      GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) = 0;
+
+  virtual void ClearDepth(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 DeleteBuffersARB(GLsizei n, const GLuint* buffers) = 0;
+
+  virtual void DeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers) = 0;
+
+  virtual void DeleteProgram(GLuint program) = 0;
+
+  virtual void DeleteRenderbuffersEXT(
+      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 DepthRange(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 FramebufferRenderbufferEXT(
+      GLenum target, GLenum attachment, GLenum renderbuffertarget,
+      GLuint renderbuffer) = 0;
+
+  virtual void FramebufferTexture2DEXT(
+      GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
+      GLint level) = 0;
+
+  virtual void FrontFace(GLenum mode) = 0;
+
+  virtual void GenBuffersARB(GLsizei n, GLuint* buffers) = 0;
+
+  virtual void GenerateMipmapEXT(GLenum target) = 0;
+
+  virtual void GenFramebuffersEXT(GLsizei n, GLuint* framebuffers) = 0;
+
+  virtual void GenRenderbuffersEXT(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 GetFramebufferAttachmentParameterivEXT(
+      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;
+
+  // TODO(gman): Implement this
+  virtual void GetProgramInfoLog(
+      GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) = 0;
+
+  virtual void GetRenderbufferParameterivEXT(
+      GLenum target, GLenum pname, GLint* params) = 0;
+
+  virtual void GetShaderiv(GLuint shader, GLenum pname, GLint* params) = 0;
+
+  // TODO(gman): Implement this
+  virtual void GetShaderInfoLog(
+      GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) = 0;
+
+  virtual void GetShaderPrecisionFormat(
+      GLenum shadertype, GLenum precisiontype, GLint* range,
+      GLint* precision) = 0;
+
+  // TODO(gman): Implement this
+  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 IsFramebufferEXT(GLuint framebuffer) = 0;
+
+  virtual GLboolean IsProgram(GLuint program) = 0;
+
+  virtual GLboolean IsRenderbufferEXT(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 RenderbufferStorageEXT(
+      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 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 SwapBuffers() = 0;
+
+ private:
+  static GLInterface* interface_;
+};
+
+}  // namespace gles2
+
+#define GL_IFACE_GET_FUN(name) ::gles2::GLInterface::GetGLInterface()->name
+
+#define glActiveTexture GL_IFACE_GET_FUN(ActiveTexture)
+#define glAttachShader GL_IFACE_GET_FUN(AttachShader)
+#define glBindAttribLocation GL_IFACE_GET_FUN(BindAttribLocation)
+#define glBindBuffer GL_IFACE_GET_FUN(BindBuffer)
+#define glBindFramebufferEXT GL_IFACE_GET_FUN(BindFramebufferEXT)
+#define glBindRenderbufferEXT GL_IFACE_GET_FUN(BindRenderbufferEXT)
+#define glBindTexture GL_IFACE_GET_FUN(BindTexture)
+#define glBlendColor GL_IFACE_GET_FUN(BlendColor)
+#define glBlendEquation GL_IFACE_GET_FUN(BlendEquation)
+#define glBlendEquationSeparate GL_IFACE_GET_FUN(BlendEquationSeparate)
+#define glBlendFunc GL_IFACE_GET_FUN(BlendFunc)
+#define glBlendFuncSeparate GL_IFACE_GET_FUN(BlendFuncSeparate)
+#define glBufferData GL_IFACE_GET_FUN(BufferData)
+#define glBufferSubData GL_IFACE_GET_FUN(BufferSubData)
+#define glCheckFramebufferStatusEXT GL_IFACE_GET_FUN(CheckFramebufferStatusEXT)
+#define glClear GL_IFACE_GET_FUN(Clear)
+#define glClearColor GL_IFACE_GET_FUN(ClearColor)
+#define glClearDepth GL_IFACE_GET_FUN(ClearDepth)
+#define glClearStencil GL_IFACE_GET_FUN(ClearStencil)
+#define glColorMask GL_IFACE_GET_FUN(ColorMask)
+#define glCompileShader GL_IFACE_GET_FUN(CompileShader)
+#define glCompressedTexImage2D GL_IFACE_GET_FUN(CompressedTexImage2D)
+#define glCompressedTexSubImage2D GL_IFACE_GET_FUN(CompressedTexSubImage2D)
+#define glCopyTexImage2D GL_IFACE_GET_FUN(CopyTexImage2D)
+#define glCopyTexSubImage2D GL_IFACE_GET_FUN(CopyTexSubImage2D)
+#define glCreateProgram GL_IFACE_GET_FUN(CreateProgram)
+#define glCreateShader GL_IFACE_GET_FUN(CreateShader)
+#define glCullFace GL_IFACE_GET_FUN(CullFace)
+#define glDeleteBuffersARB GL_IFACE_GET_FUN(DeleteBuffersARB)
+#define glDeleteFramebuffersEXT GL_IFACE_GET_FUN(DeleteFramebuffersEXT)
+#define glDeleteProgram GL_IFACE_GET_FUN(DeleteProgram)
+#define glDeleteRenderbuffersEXT GL_IFACE_GET_FUN(DeleteRenderbuffersEXT)
+#define glDeleteShader GL_IFACE_GET_FUN(DeleteShader)
+#define glDeleteTextures GL_IFACE_GET_FUN(DeleteTextures)
+#define glDepthFunc GL_IFACE_GET_FUN(DepthFunc)
+#define glDepthMask GL_IFACE_GET_FUN(DepthMask)
+#define glDepthRange GL_IFACE_GET_FUN(DepthRange)
+#define glDetachShader GL_IFACE_GET_FUN(DetachShader)
+#define glDisable GL_IFACE_GET_FUN(Disable)
+#define glDisableVertexAttribArray GL_IFACE_GET_FUN(DisableVertexAttribArray)
+#define glDrawArrays GL_IFACE_GET_FUN(DrawArrays)
+#define glDrawElements GL_IFACE_GET_FUN(DrawElements)
+#define glEnable GL_IFACE_GET_FUN(Enable)
+#define glEnableVertexAttribArray GL_IFACE_GET_FUN(EnableVertexAttribArray)
+#define glFinish GL_IFACE_GET_FUN(Finish)
+#define glFlush GL_IFACE_GET_FUN(Flush)
+#define glFramebufferRenderbufferEXT \
+    GL_IFACE_GET_FUN(FramebufferRenderbufferEXT)
+#define glFramebufferTexture2DEXT GL_IFACE_GET_FUN(FramebufferTexture2DEXT)
+#define glFrontFace GL_IFACE_GET_FUN(FrontFace)
+#define glGenBuffersARB GL_IFACE_GET_FUN(GenBuffersARB)
+#define glGenerateMipmapEXT GL_IFACE_GET_FUN(GenerateMipmapEXT)
+#define glGenFramebuffersEXT GL_IFACE_GET_FUN(GenFramebuffersEXT)
+#define glGenRenderbuffersEXT GL_IFACE_GET_FUN(GenRenderbuffersEXT)
+#define glGenTextures GL_IFACE_GET_FUN(GenTextures)
+#define glGetActiveAttrib GL_IFACE_GET_FUN(GetActiveAttrib)
+#define glGetActiveUniform GL_IFACE_GET_FUN(GetActiveUniform)
+#define glGetAttachedShaders GL_IFACE_GET_FUN(GetAttachedShaders)
+#define glGetAttribLocation GL_IFACE_GET_FUN(GetAttribLocation)
+#define glGetBooleanv GL_IFACE_GET_FUN(GetBooleanv)
+#define glGetBufferParameteriv GL_IFACE_GET_FUN(GetBufferParameteriv)
+#define glGetError GL_IFACE_GET_FUN(GetError)
+#define glGetFloatv GL_IFACE_GET_FUN(GetFloatv)
+#define glGetFramebufferAttachmentParameterivEXT \
+    GL_IFACE_GET_FUN(GetFramebufferAttachmentParameterivEXT)
+#define glGetIntegerv GL_IFACE_GET_FUN(GetIntegerv)
+#define glGetProgramiv GL_IFACE_GET_FUN(GetProgramiv)
+#define glGetProgramInfoLog GL_IFACE_GET_FUN(GetProgramInfoLog)
+#define glGetRenderbufferParameterivEXT \
+    GL_IFACE_GET_FUN(GetRenderbufferParameterivEXT)
+#define glGetShaderiv GL_IFACE_GET_FUN(GetShaderiv)
+#define glGetShaderInfoLog GL_IFACE_GET_FUN(GetShaderInfoLog)
+#define glGetShaderPrecisionFormat GL_IFACE_GET_FUN(GetShaderPrecisionFormat)
+#define glGetShaderSource GL_IFACE_GET_FUN(GetShaderSource)
+#define glGetString GL_IFACE_GET_FUN(GetString)
+#define glGetTexParameterfv GL_IFACE_GET_FUN(GetTexParameterfv)
+#define glGetTexParameteriv GL_IFACE_GET_FUN(GetTexParameteriv)
+#define glGetUniformfv GL_IFACE_GET_FUN(GetUniformfv)
+#define glGetUniformiv GL_IFACE_GET_FUN(GetUniformiv)
+#define glGetUniformLocation GL_IFACE_GET_FUN(GetUniformLocation)
+#define glGetVertexAttribfv GL_IFACE_GET_FUN(GetVertexAttribfv)
+#define glGetVertexAttribiv GL_IFACE_GET_FUN(GetVertexAttribiv)
+#define glGetVertexAttribPointerv GL_IFACE_GET_FUN(GetVertexAttribPointerv)
+#define glHint GL_IFACE_GET_FUN(Hint)
+#define glIsBuffer GL_IFACE_GET_FUN(IsBuffer)
+#define glIsEnabled GL_IFACE_GET_FUN(IsEnabled)
+#define glIsFramebufferEXT GL_IFACE_GET_FUN(IsFramebufferEXT)
+#define glIsProgram GL_IFACE_GET_FUN(IsProgram)
+#define glIsRenderbufferEXT GL_IFACE_GET_FUN(IsRenderbufferEXT)
+#define glIsShader GL_IFACE_GET_FUN(IsShader)
+#define glIsTexture GL_IFACE_GET_FUN(IsTexture)
+#define glLineWidth GL_IFACE_GET_FUN(LineWidth)
+#define glLinkProgram GL_IFACE_GET_FUN(LinkProgram)
+#define glPixelStorei GL_IFACE_GET_FUN(PixelStorei)
+#define glPolygonOffset GL_IFACE_GET_FUN(PolygonOffset)
+#define glReadPixels GL_IFACE_GET_FUN(ReadPixels)
+#define glReleaseShaderCompiler GL_IFACE_GET_FUN(ReleaseShaderCompiler)
+#define glRenderbufferStorageEXT GL_IFACE_GET_FUN(RenderbufferStorageEXT)
+#define glSampleCoverage GL_IFACE_GET_FUN(SampleCoverage)
+#define glScissor GL_IFACE_GET_FUN(Scissor)
+#define glShaderBinary GL_IFACE_GET_FUN(ShaderBinary)
+#define glShaderSource GL_IFACE_GET_FUN(ShaderSource)
+#define glStencilFunc GL_IFACE_GET_FUN(StencilFunc)
+#define glStencilFuncSeparate GL_IFACE_GET_FUN(StencilFuncSeparate)
+#define glStencilMask GL_IFACE_GET_FUN(StencilMask)
+#define glStencilMaskSeparate GL_IFACE_GET_FUN(StencilMaskSeparate)
+#define glStencilOp GL_IFACE_GET_FUN(StencilOp)
+#define glStencilOpSeparate GL_IFACE_GET_FUN(StencilOpSeparate)
+#define glTexImage2D GL_IFACE_GET_FUN(TexImage2D)
+#define glTexParameterf GL_IFACE_GET_FUN(TexParameterf)
+#define glTexParameterfv GL_IFACE_GET_FUN(TexParameterfv)
+#define glTexParameteri GL_IFACE_GET_FUN(TexParameteri)
+#define glTexParameteriv GL_IFACE_GET_FUN(TexParameteriv)
+#define glTexSubImage2D GL_IFACE_GET_FUN(TexSubImage2D)
+#define glUniform1f GL_IFACE_GET_FUN(Uniform1f)
+#define glUniform1fv GL_IFACE_GET_FUN(Uniform1fv)
+#define glUniform1i GL_IFACE_GET_FUN(Uniform1i)
+#define glUniform1iv GL_IFACE_GET_FUN(Uniform1iv)
+#define glUniform2f GL_IFACE_GET_FUN(Uniform2f)
+#define glUniform2fv GL_IFACE_GET_FUN(Uniform2fv)
+#define glUniform2i GL_IFACE_GET_FUN(Uniform2i)
+#define glUniform2iv GL_IFACE_GET_FUN(Uniform2iv)
+#define glUniform3f GL_IFACE_GET_FUN(Uniform3f)
+#define glUniform3fv GL_IFACE_GET_FUN(Uniform3fv)
+#define glUniform3i GL_IFACE_GET_FUN(Uniform3i)
+#define glUniform3iv GL_IFACE_GET_FUN(Uniform3iv)
+#define glUniform4f GL_IFACE_GET_FUN(Uniform4f)
+#define glUniform4fv GL_IFACE_GET_FUN(Uniform4fv)
+#define glUniform4i GL_IFACE_GET_FUN(Uniform4i)
+#define glUniform4iv GL_IFACE_GET_FUN(Uniform4iv)
+#define glUniformMatrix2fv GL_IFACE_GET_FUN(UniformMatrix2fv)
+#define glUniformMatrix3fv GL_IFACE_GET_FUN(UniformMatrix3fv)
+#define glUniformMatrix4fv GL_IFACE_GET_FUN(UniformMatrix4fv)
+#define glUseProgram GL_IFACE_GET_FUN(UseProgram)
+#define glValidateProgram GL_IFACE_GET_FUN(ValidateProgram)
+#define glVertexAttrib1f GL_IFACE_GET_FUN(VertexAttrib1f)
+#define glVertexAttrib1fv GL_IFACE_GET_FUN(VertexAttrib1fv)
+#define glVertexAttrib2f GL_IFACE_GET_FUN(VertexAttrib2f)
+#define glVertexAttrib2fv GL_IFACE_GET_FUN(VertexAttrib2fv)
+#define glVertexAttrib3f GL_IFACE_GET_FUN(VertexAttrib3f)
+#define glVertexAttrib3fv GL_IFACE_GET_FUN(VertexAttrib3fv)
+#define glVertexAttrib4f GL_IFACE_GET_FUN(VertexAttrib4f)
+#define glVertexAttrib4fv GL_IFACE_GET_FUN(VertexAttrib4fv)
+#define glVertexAttribPointer GL_IFACE_GET_FUN(VertexAttribPointer)
+#define glViewport GL_IFACE_GET_FUN(Viewport)
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_GL_INTERFACE_H_
+
+
+
diff --git a/gpu/command_buffer/service/gl_mock.cc b/gpu/command_buffer/service/gl_mock.cc
new file mode 100644
index 0000000..12b5b34
--- /dev/null
+++ b/gpu/command_buffer/service/gl_mock.cc
@@ -0,0 +1,11 @@
+// Copyright (c) 2009 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/service/gl_mock.h"
+
+namespace gles2 {
+
+
+}  // namespace gles2
+
diff --git a/gpu/command_buffer/service/gl_mock.h b/gpu/command_buffer/service/gl_mock.h
new file mode 100644
index 0000000..1ef66ea
--- /dev/null
+++ b/gpu/command_buffer/service/gl_mock.h
@@ -0,0 +1,380 @@
+// Copyright (c) 2009 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 implements mock GL Interface for unit testing. It has to mock
+// Desktop GL, not GLES2 as it is used to test the service side code.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_GL_MOCK_H_
+#define GPU_COMMAND_BUFFER_SERVICE_GL_MOCK_H_
+
+#include "gpu/command_buffer/service/gl_interface.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace gles2 {
+
+class MockGLInterface : public GLInterface {
+ public:
+  virtual ~MockGLInterface() {
+  }
+
+  MOCK_METHOD1(ActiveTexture, void(GLenum texture));
+
+  MOCK_METHOD2(AttachShader, void(GLuint program, GLuint shader));
+
+  MOCK_METHOD3(BindAttribLocation, void(
+      GLuint program, GLuint index, const char* name));
+
+  MOCK_METHOD2(BindBuffer, void(GLenum target, GLuint buffer));
+
+  MOCK_METHOD2(BindFramebufferEXT, void(GLenum target, GLuint framebuffer));
+
+  MOCK_METHOD2(BindRenderbufferEXT, void(GLenum target, GLuint renderbuffer));
+
+  MOCK_METHOD2(BindTexture, void(GLenum target, GLuint texture));
+
+  MOCK_METHOD4(BlendColor, void(
+      GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
+
+  MOCK_METHOD1(BlendEquation, void(GLenum mode));
+
+  MOCK_METHOD2(BlendEquationSeparate, void(GLenum modeRGB, GLenum modeAlpha));
+
+  MOCK_METHOD2(BlendFunc, void(GLenum sfactor, GLenum dfactor));
+
+  MOCK_METHOD4(BlendFuncSeparate, void(
+      GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha));
+
+  MOCK_METHOD4(BufferData, void(
+      GLenum target, GLsizeiptr size, const void* data, GLenum usage));
+
+  MOCK_METHOD4(BufferSubData, void(
+      GLenum target, GLintptr offset, GLsizeiptr size, const void* data));
+
+  MOCK_METHOD1(CheckFramebufferStatusEXT, GLenum(GLenum target));
+
+  MOCK_METHOD1(Clear, void(GLbitfield mask));
+
+  MOCK_METHOD4(ClearColor, void(
+      GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha));
+
+  MOCK_METHOD1(ClearDepth, void(GLclampf depth));
+
+  MOCK_METHOD1(ClearStencil, void(GLint s));
+
+  MOCK_METHOD4(ColorMask, void(
+      GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha));
+
+  MOCK_METHOD1(CompileShader, void(GLuint shader));
+
+  MOCK_METHOD8(CompressedTexImage2D, void(
+      GLenum target, GLint level, GLenum internalformat, GLsizei width,
+      GLsizei height, GLint border, GLsizei imageSize, const void* data));
+
+  MOCK_METHOD9(CompressedTexSubImage2D, void(
+      GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+      GLsizei height, GLenum format, GLsizei imageSize, const void* data));
+
+  MOCK_METHOD8(CopyTexImage2D, void(
+      GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
+      GLsizei width, GLsizei height, GLint border));
+
+  MOCK_METHOD8(CopyTexSubImage2D, void(
+      GLenum target, GLint level, GLint xoffset, GLint yoffset,
+      GLint x, GLint y, GLsizei width, GLsizei height));
+
+  MOCK_METHOD0(CreateProgram, GLuint());
+
+  MOCK_METHOD1(CreateShader, GLuint(GLenum type));
+
+  MOCK_METHOD1(CullFace, void(GLenum mode));
+
+  MOCK_METHOD2(DeleteBuffersARB, void(GLsizei n, const GLuint* buffers));
+
+  MOCK_METHOD2(DeleteFramebuffersEXT,
+               void(GLsizei n, const GLuint* framebuffers));
+
+  MOCK_METHOD1(DeleteProgram, void(GLuint program));
+
+  MOCK_METHOD2(DeleteRenderbuffersEXT, void(
+      GLsizei n, const GLuint* renderbuffers));
+
+  MOCK_METHOD1(DeleteShader, void(GLuint shader));
+
+  MOCK_METHOD2(DeleteTextures, void(GLsizei n, const GLuint* textures));
+
+  MOCK_METHOD1(DepthFunc, void(GLenum func));
+
+  MOCK_METHOD1(DepthMask, void(GLboolean flag));
+
+  MOCK_METHOD2(DepthRange, void(GLclampf zNear, GLclampf zFar));
+
+  MOCK_METHOD2(DetachShader, void(GLuint program, GLuint shader));
+
+  MOCK_METHOD1(Disable, void(GLenum cap));
+
+  MOCK_METHOD1(DisableVertexAttribArray, void(GLuint index));
+
+  MOCK_METHOD3(DrawArrays, void(GLenum mode, GLint first, GLsizei count));
+
+  MOCK_METHOD4(DrawElements, void(
+      GLenum mode, GLsizei count, GLenum type, const void* indices));
+
+  MOCK_METHOD1(Enable, void(GLenum cap));
+
+  MOCK_METHOD1(EnableVertexAttribArray, void(GLuint index));
+
+  MOCK_METHOD0(Finish, void());
+
+  MOCK_METHOD0(Flush, void());
+
+  MOCK_METHOD4(FramebufferRenderbufferEXT, void(
+      GLenum target, GLenum attachment, GLenum renderbuffertarget,
+      GLuint renderbuffer));
+
+  MOCK_METHOD5(FramebufferTexture2DEXT, void(
+      GLenum target, GLenum attachment, GLenum textarget, GLuint texture,
+      GLint level));
+
+  MOCK_METHOD1(FrontFace, void(GLenum mode));
+
+  MOCK_METHOD2(GenBuffersARB, void(GLsizei n, GLuint* buffers));
+
+  MOCK_METHOD1(GenerateMipmapEXT, void(GLenum target));
+
+  MOCK_METHOD2(GenFramebuffersEXT, void(GLsizei n, GLuint* framebuffers));
+
+  MOCK_METHOD2(GenRenderbuffersEXT, void(GLsizei n, GLuint* renderbuffers));
+
+  MOCK_METHOD2(GenTextures, void(GLsizei n, GLuint* textures));
+
+  MOCK_METHOD7(GetActiveAttrib, void(
+      GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
+      GLint* size, GLenum* type, char* name));
+
+  MOCK_METHOD7(GetActiveUniform, void(
+      GLuint program, GLuint index, GLsizei bufsize, GLsizei* length,
+      GLint* size, GLenum* type, char* name));
+
+  MOCK_METHOD4(GetAttachedShaders, void(
+      GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders));
+
+  MOCK_METHOD2(GetAttribLocation, GLint(GLuint program, const char* name));
+
+  MOCK_METHOD2(GetBooleanv, void(GLenum pname, GLboolean* params));
+
+  MOCK_METHOD3(GetBufferParameteriv, void(
+      GLenum target, GLenum pname, GLint* params));
+
+  MOCK_METHOD0(GetError, GLenum());
+
+  MOCK_METHOD2(GetFloatv, void(GLenum pname, GLfloat* params));
+
+  MOCK_METHOD4(GetFramebufferAttachmentParameterivEXT, void(
+      GLenum target, GLenum attachment, GLenum pname, GLint* params));
+
+  MOCK_METHOD2(GetIntegerv, void(GLenum pname, GLint* params));
+
+  MOCK_METHOD3(GetProgramiv, void(GLuint program, GLenum pname, GLint* params));
+
+  MOCK_METHOD4(GetProgramInfoLog, void(
+      GLuint program, GLsizei bufsize, GLsizei* length, char* infolog));
+
+  MOCK_METHOD3(GetRenderbufferParameterivEXT, void(
+      GLenum target, GLenum pname, GLint* params));
+
+  MOCK_METHOD3(GetShaderiv, void(GLuint shader, GLenum pname, GLint* params));
+
+  MOCK_METHOD4(GetShaderInfoLog, void(
+      GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog));
+
+  MOCK_METHOD4(GetShaderPrecisionFormat, void(
+      GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision));
+
+  MOCK_METHOD4(GetShaderSource, void(
+      GLuint shader, GLsizei bufsize, GLsizei* length, char* source));
+
+  MOCK_METHOD1(GetString, const GLubyte*(GLenum name));
+
+  MOCK_METHOD3(GetTexParameterfv, void(
+      GLenum target, GLenum pname, GLfloat* params));
+
+  MOCK_METHOD3(GetTexParameteriv, void(
+      GLenum target, GLenum pname, GLint* params));
+
+  MOCK_METHOD3(GetUniformfv,
+               void(GLuint program, GLint location, GLfloat* params));
+
+  MOCK_METHOD3(GetUniformiv,
+               void(GLuint program, GLint location, GLint* params));
+
+  MOCK_METHOD2(GetUniformLocation, GLint(GLuint program, const char* name));
+
+  MOCK_METHOD3(GetVertexAttribfv, void(
+      GLuint index, GLenum pname, GLfloat* params));
+
+  MOCK_METHOD3(GetVertexAttribiv,
+               void(GLuint index, GLenum pname, GLint* params));
+
+  MOCK_METHOD3(GetVertexAttribPointerv, void(
+      GLuint index, GLenum pname, void** pointer));
+
+  MOCK_METHOD2(Hint, void(GLenum target, GLenum mode));
+
+  MOCK_METHOD1(IsBuffer, GLboolean(GLuint buffer));
+
+  MOCK_METHOD1(IsEnabled, GLboolean(GLenum cap));
+
+  MOCK_METHOD1(IsFramebufferEXT, GLboolean(GLuint framebuffer));
+
+  MOCK_METHOD1(IsProgram, GLboolean(GLuint program));
+
+  MOCK_METHOD1(IsRenderbufferEXT, GLboolean(GLuint renderbuffer));
+
+  MOCK_METHOD1(IsShader, GLboolean(GLuint shader));
+
+  MOCK_METHOD1(IsTexture, GLboolean(GLuint texture));
+
+  MOCK_METHOD1(LineWidth, void(GLfloat width));
+
+  MOCK_METHOD1(LinkProgram, void(GLuint program));
+
+  MOCK_METHOD2(PixelStorei, void(GLenum pname, GLint param));
+
+  MOCK_METHOD2(PolygonOffset, void(GLfloat factor, GLfloat units));
+
+  MOCK_METHOD7(ReadPixels, void(
+      GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
+      GLenum type, void* pixels));
+
+  MOCK_METHOD4(RenderbufferStorageEXT, void(
+      GLenum target, GLenum internalformat, GLsizei width, GLsizei height));
+
+  MOCK_METHOD2(SampleCoverage, void(GLclampf value, GLboolean invert));
+
+  MOCK_METHOD4(Scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
+
+  MOCK_METHOD4(ShaderSource, void(
+      GLuint shader, GLsizei count, const char** str, const GLint* length));
+
+  MOCK_METHOD3(StencilFunc, void(GLenum func, GLint ref, GLuint mask));
+
+  MOCK_METHOD4(StencilFuncSeparate, void(
+      GLenum face, GLenum func, GLint ref, GLuint mask));
+
+  MOCK_METHOD1(StencilMask, void(GLuint mask));
+
+  MOCK_METHOD2(StencilMaskSeparate, void(GLenum face, GLuint mask));
+
+  MOCK_METHOD3(StencilOp, void(GLenum fail, GLenum zfail, GLenum zpass));
+
+  MOCK_METHOD4(StencilOpSeparate, void(
+      GLenum face, GLenum fail, GLenum zfail, GLenum zpass));
+
+  MOCK_METHOD9(TexImage2D, void(
+      GLenum target, GLint level, GLint internalformat, GLsizei width,
+      GLsizei height, GLint border, GLenum format, GLenum type,
+      const void* pixels));
+
+  MOCK_METHOD3(TexParameterf, void(GLenum target, GLenum pname, GLfloat param));
+
+  MOCK_METHOD3(TexParameterfv, void(
+      GLenum target, GLenum pname, const GLfloat* params));
+
+  MOCK_METHOD3(TexParameteri, void(GLenum target, GLenum pname, GLint param));
+
+  MOCK_METHOD3(TexParameteriv, void(
+      GLenum target, GLenum pname, const GLint* params));
+
+  MOCK_METHOD9(TexSubImage2D, void(
+      GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width,
+      GLsizei height, GLenum format, GLenum type, const void* pixels));
+
+  MOCK_METHOD2(Uniform1f, void(GLint location, GLfloat x));
+
+  MOCK_METHOD3(Uniform1fv,
+               void(GLint location, GLsizei count, const GLfloat* v));
+
+  MOCK_METHOD2(Uniform1i, void(GLint location, GLint x));
+
+  MOCK_METHOD3(Uniform1iv, void(GLint location, GLsizei count, const GLint* v));
+
+  MOCK_METHOD3(Uniform2f, void(GLint location, GLfloat x, GLfloat y));
+
+  MOCK_METHOD3(Uniform2fv,
+               void(GLint location, GLsizei count, const GLfloat* v));
+
+  MOCK_METHOD3(Uniform2i, void(GLint location, GLint x, GLint y));
+
+  MOCK_METHOD3(Uniform2iv, void(GLint location, GLsizei count, const GLint* v));
+
+  MOCK_METHOD4(Uniform3f,
+               void(GLint location, GLfloat x, GLfloat y, GLfloat z));
+
+  MOCK_METHOD3(Uniform3fv,
+               void(GLint location, GLsizei count, const GLfloat* v));
+
+  MOCK_METHOD4(Uniform3i, void(GLint location, GLint x, GLint y, GLint z));
+
+  MOCK_METHOD3(Uniform3iv, void(GLint location, GLsizei count, const GLint* v));
+
+  MOCK_METHOD5(Uniform4f, void(
+      GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
+
+  MOCK_METHOD3(Uniform4fv,
+               void(GLint location, GLsizei count, const GLfloat* v));
+
+  MOCK_METHOD5(Uniform4i,
+               void(GLint location, GLint x, GLint y, GLint z, GLint w));
+
+  MOCK_METHOD3(Uniform4iv, void(GLint location, GLsizei count, const GLint* v));
+
+  MOCK_METHOD4(UniformMatrix2fv, void(
+      GLint location, GLsizei count, GLboolean transpose,
+      const GLfloat* value));
+
+  MOCK_METHOD4(UniformMatrix3fv, void(
+      GLint location, GLsizei count, GLboolean transpose,
+      const GLfloat* value));
+
+  MOCK_METHOD4(UniformMatrix4fv, void(
+      GLint location, GLsizei count, GLboolean transpose,
+      const GLfloat* value));
+
+  MOCK_METHOD1(UseProgram, void(GLuint program));
+
+  MOCK_METHOD1(ValidateProgram, void(GLuint program));
+
+  MOCK_METHOD2(VertexAttrib1f, void(GLuint indx, GLfloat x));
+
+  MOCK_METHOD2(VertexAttrib1fv, void(GLuint indx, const GLfloat* values));
+
+  MOCK_METHOD3(VertexAttrib2f, void(GLuint indx, GLfloat x, GLfloat y));
+
+  MOCK_METHOD2(VertexAttrib2fv, void(GLuint indx, const GLfloat* values));
+
+  MOCK_METHOD4(VertexAttrib3f,
+              void(GLuint indx, GLfloat x, GLfloat y, GLfloat z));
+
+  MOCK_METHOD2(VertexAttrib3fv, void(GLuint indx, const GLfloat* values));
+
+  MOCK_METHOD5(VertexAttrib4f, void(
+      GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
+
+  MOCK_METHOD2(VertexAttrib4fv, void(GLuint indx, const GLfloat* values));
+
+  MOCK_METHOD6(VertexAttribPointer, void(
+      GLuint indx, GLint size, GLenum type, GLboolean normalized,
+      GLsizei stride, const void* ptr));
+
+  MOCK_METHOD4(Viewport, void(GLint x, GLint y, GLsizei width, GLsizei height));
+
+  MOCK_METHOD0(SwapBuffers, void());
+};
+
+}  // namespace gles2
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_GL_MOCK_H_
+
+
+
diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h
index 46e9eb8..730ccf6 100644
--- a/gpu/command_buffer/service/gl_utils.h
+++ b/gpu/command_buffer/service/gl_utils.h
@@ -8,11 +8,15 @@
 #ifndef GPU_COMMAND_BUFFER_SERVICE_GL_UTILS_H_
 #define GPU_COMMAND_BUFFER_SERVICE_GL_UTILS_H_
 
+#if defined(UNIT_TEST)
+#include "gpu/command_buffer/service/gl_mock.h"
+#else
 #include <GL/glew.h>
 #if defined(OS_WIN)
 #include <GL/wglew.h>
 #endif
 #include <build/build_config.h>
+#endif
 
 #define GL_GLEXT_PROTOTYPES 1
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index f13944f..413f383 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -140,7 +140,9 @@
 
 }  // anonymous namespace.
 
-#if defined(OS_LINUX)
+#if defined(UNIT_TEST)
+GLES2Decoder::GLES2Decoder() {
+#elif defined(OS_LINUX)
 GLES2Decoder::GLES2Decoder()
     : debug_(false),
       window_(NULL) {
@@ -517,7 +519,8 @@
   // The program in current use through glUseProgram.
   ProgramInfo* current_program_info_;
 
-#if defined(OS_WIN)
+#if defined(UNIT_TEST)
+#elif defined(OS_WIN)
   HDC device_context_;
   HGLRC gl_context_;
 #endif
@@ -541,7 +544,8 @@
       bound_element_array_buffer_(0),
       max_vertex_attribs_(0),
       current_program_info_(NULL),
-#ifdef OS_WIN
+#if defined(UNIT_TEST)
+#elif defined(OS_WIN)
       device_context_(NULL),
       gl_context_(NULL),
 #endif
@@ -570,9 +574,11 @@
   return true;
 }
 
-#if defined(OS_WIN)
 namespace {
 
+#if defined(UNIT_TEST)
+#elif defined(OS_WIN)
+
 const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = {
   sizeof(kPixelFormatDescriptor),    // Size of structure.
   1,                       // Default version.
@@ -739,6 +745,8 @@
   return true;
 }
 
+#endif  // OS_WIN
+
 // These commands convert from c calls to local os calls.
 void GLGenBuffersHelper(
     GLES2DecoderImpl*, GLsizei n, GLuint* ids) {
@@ -784,7 +792,6 @@
 }
 
 }  // anonymous namespace
-#endif
 
 bool GLES2DecoderImpl::RegisterObjects(
     GLsizei n, const GLuint* client_ids, const GLuint* service_ids) {
@@ -818,7 +825,8 @@
 }
 
 bool GLES2DecoderImpl::InitPlatformSpecific() {
-#if defined(OS_WIN)
+#if defined(UNIT_TEST)
+#elif defined(OS_WIN)
   device_context_ = ::GetDC(hwnd());
 
   int pixel_format;
@@ -858,6 +866,7 @@
 }
 
 bool GLES2DecoderImpl::InitGlew() {
+#if !defined(UNIT_TEST)
   DLOG(INFO) << "Initializing GL and GLEW for GLES2Decoder.";
 
   GLenum glew_error = glewInit();
@@ -907,12 +916,14 @@
   }
   if (!extensions_found)
     return false;
+#endif
 
   return true;
 }
 
 void GLES2DecoderImpl::Destroy() {
-#ifdef OS_LINUX
+#if defined(UNIT_TEST)
+#elif defined(OS_LINUX)
   DCHECK(window());
   window()->Destroy();
 #endif
@@ -1073,11 +1084,10 @@
 // NOTE: If you need to know the results of SwapBuffers (like losing
 //    the context) then add a new command. Do NOT make SwapBuffers synchronous.
 void GLES2DecoderImpl::DoSwapBuffers() {
-#ifdef OS_WIN
+#if defined(UNIT_TEST)
+#elif defined(OS_WIN)
   ::SwapBuffers(device_context_);
-#endif
-
-#ifdef OS_LINUX
+#elif defined(OS_LINUX)
   DCHECK(window());
   window()->SwapBuffers();
 #endif
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 24e7340..58bb735 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -72,7 +72,7 @@
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   DoBindBuffer(target, buffer);
@@ -88,7 +88,7 @@
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumFrameBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glBindFramebufferEXT(target, framebuffer);
@@ -104,7 +104,7 @@
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumRenderBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glBindRenderbufferEXT(target, renderbuffer);
@@ -120,7 +120,7 @@
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureBindTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glBindTexture(target, texture);
@@ -141,7 +141,7 @@
     uint32 immediate_data_size, const gles2::BlendEquation& c) {
   GLenum mode = static_cast<GLenum>(c.mode);
   if (!ValidateGLenumEquation(mode)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glBlendEquation(mode);
@@ -153,11 +153,11 @@
   GLenum modeRGB = static_cast<GLenum>(c.modeRGB);
   GLenum modeAlpha = static_cast<GLenum>(c.modeAlpha);
   if (!ValidateGLenumEquation(modeRGB)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumEquation(modeAlpha)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glBlendEquationSeparate(modeRGB, modeAlpha);
@@ -169,11 +169,11 @@
   GLenum sfactor = static_cast<GLenum>(c.sfactor);
   GLenum dfactor = static_cast<GLenum>(c.dfactor);
   if (!ValidateGLenumSrcBlendFactor(sfactor)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumDstBlendFactor(dfactor)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glBlendFunc(sfactor, dfactor);
@@ -187,19 +187,19 @@
   GLenum srcAlpha = static_cast<GLenum>(c.srcAlpha);
   GLenum dstAlpha = static_cast<GLenum>(c.dstAlpha);
   if (!ValidateGLenumSrcBlendFactor(srcRGB)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumDstBlendFactor(dstRGB)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumSrcBlendFactor(srcAlpha)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumDstBlendFactor(dstAlpha)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
@@ -215,7 +215,7 @@
   const void* data = GetSharedMemoryAs<const void*>(
       c.data_shm_id, c.data_shm_offset, data_size);
   if (!ValidateGLenumBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (data == NULL) {
@@ -234,7 +234,7 @@
   const void* data = GetImmediateDataAs<const void*>(
       c, data_size, immediate_data_size);
   if (!ValidateGLenumBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (data == NULL) {
@@ -248,7 +248,7 @@
     uint32 immediate_data_size, const gles2::CheckFramebufferStatus& c) {
   GLenum target = static_cast<GLenum>(c.target);
   if (!ValidateGLenumFrameBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glCheckFramebufferStatusEXT(target);
@@ -321,7 +321,7 @@
   const void* data = GetSharedMemoryAs<const void*>(
       c.data_shm_id, c.data_shm_offset, data_size);
   if (!ValidateGLenumTextureTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (data == NULL) {
@@ -348,7 +348,7 @@
   const void* data = GetImmediateDataAs<const void*>(
       c, data_size, immediate_data_size);
   if (!ValidateGLenumTextureTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (data == NULL) {
@@ -370,7 +370,7 @@
   GLsizei height = static_cast<GLsizei>(c.height);
   GLint border = static_cast<GLint>(c.border);
   if (!ValidateGLenumTextureTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
@@ -388,7 +388,7 @@
   GLsizei width = static_cast<GLsizei>(c.width);
   GLsizei height = static_cast<GLsizei>(c.height);
   if (!ValidateGLenumTextureTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
@@ -406,7 +406,7 @@
     uint32 immediate_data_size, const gles2::CreateShader& c) {
   GLenum type = static_cast<GLenum>(c.type);
   if (!ValidateGLenumShaderType(type)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   uint32 client_id = c.client_id;
@@ -418,7 +418,7 @@
     uint32 immediate_data_size, const gles2::CullFace& c) {
   GLenum mode = static_cast<GLenum>(c.mode);
   if (!ValidateGLenumFaceType(mode)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glCullFace(mode);
@@ -533,7 +533,7 @@
     uint32 immediate_data_size, const gles2::DepthFunc& c) {
   GLenum func = static_cast<GLenum>(c.func);
   if (!ValidateGLenumCmpFunction(func)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glDepthFunc(func);
@@ -575,7 +575,7 @@
     uint32 immediate_data_size, const gles2::Disable& c) {
   GLenum cap = static_cast<GLenum>(c.cap);
   if (!ValidateGLenumCapability(cap)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glDisable(cap);
@@ -595,7 +595,7 @@
   GLint first = static_cast<GLint>(c.first);
   GLsizei count = static_cast<GLsizei>(c.count);
   if (!ValidateGLenumDrawMode(mode)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   DoDrawArrays(mode, first, count);
@@ -606,7 +606,7 @@
     uint32 immediate_data_size, const gles2::Enable& c) {
   GLenum cap = static_cast<GLenum>(c.cap);
   if (!ValidateGLenumCapability(cap)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glEnable(cap);
@@ -643,15 +643,15 @@
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumFrameBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumAttachment(attachment)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumRenderBufferTarget(renderbuffertarget)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glFramebufferRenderbufferEXT(
@@ -671,15 +671,15 @@
   }
   GLint level = static_cast<GLint>(c.level);
   if (!ValidateGLenumFrameBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumAttachment(attachment)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureTarget(textarget)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glFramebufferTexture2DEXT(target, attachment, textarget, texture, level);
@@ -690,7 +690,7 @@
     uint32 immediate_data_size, const gles2::FrontFace& c) {
   GLenum mode = static_cast<GLenum>(c.mode);
   if (!ValidateGLenumFaceMode(mode)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glFrontFace(mode);
@@ -727,7 +727,7 @@
     uint32 immediate_data_size, const gles2::GenerateMipmap& c) {
   GLenum target = static_cast<GLenum>(c.target);
   if (!ValidateGLenumTextureBindTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glGenerateMipmapEXT(target);
@@ -837,11 +837,11 @@
   params = GetSharedMemoryAs<GLint*>(
       c.params_shm_id, c.params_shm_offset, params_size);
   if (!ValidateGLenumBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumBufferParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -887,15 +887,15 @@
   params = GetSharedMemoryAs<GLint*>(
       c.params_shm_id, c.params_shm_offset, params_size);
   if (!ValidateGLenumFrameBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumAttachment(attachment)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumFrameBufferParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -934,7 +934,7 @@
   params = GetSharedMemoryAs<GLint*>(
       c.params_shm_id, c.params_shm_offset, params_size);
   if (!ValidateGLenumProgramParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -981,11 +981,11 @@
   params = GetSharedMemoryAs<GLint*>(
       c.params_shm_id, c.params_shm_offset, params_size);
   if (!ValidateGLenumRenderBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumRenderBufferParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1009,7 +1009,7 @@
   params = GetSharedMemoryAs<GLint*>(
       c.params_shm_id, c.params_shm_offset, params_size);
   if (!ValidateGLenumShaderParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1077,7 +1077,7 @@
     uint32 immediate_data_size, const gles2::GetString& c) {
   GLenum name = static_cast<GLenum>(c.name);
   if (!ValidateGLenumStringType(name)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glGetString(name);
@@ -1094,11 +1094,11 @@
   params = GetSharedMemoryAs<GLfloat*>(
       c.params_shm_id, c.params_shm_offset, params_size);
   if (!ValidateGLenumTextureTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1118,11 +1118,11 @@
   params = GetSharedMemoryAs<GLint*>(
       c.params_shm_id, c.params_shm_offset, params_size);
   if (!ValidateGLenumTextureTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1142,7 +1142,7 @@
   params = GetSharedMemoryAs<GLfloat*>(
       c.params_shm_id, c.params_shm_offset, params_size);
   if (!ValidateGLenumVertexAttribute(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1162,7 +1162,7 @@
   params = GetSharedMemoryAs<GLint*>(
       c.params_shm_id, c.params_shm_offset, params_size);
   if (!ValidateGLenumVertexAttribute(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1177,11 +1177,11 @@
   GLenum target = static_cast<GLenum>(c.target);
   GLenum mode = static_cast<GLenum>(c.mode);
   if (!ValidateGLenumHintTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumHintMode(mode)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glHint(target, mode);
@@ -1207,7 +1207,7 @@
   GLboolean* result_dst = GetSharedMemoryAs<GLboolean*>(
       c.result_shm_id, c.result_shm_offset, sizeof(*result_dst));
   if (!ValidateGLenumCapability(cap)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   *result_dst = glIsEnabled(cap);
@@ -1312,11 +1312,11 @@
   GLsizei width = static_cast<GLsizei>(c.width);
   GLsizei height = static_cast<GLsizei>(c.height);
   if (!ValidateGLenumRenderBufferTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumRenderBufferFormat(internalformat)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glRenderbufferStorageEXT(target, internalformat, width, height);
@@ -1347,7 +1347,7 @@
   GLint ref = static_cast<GLint>(c.ref);
   GLuint mask = static_cast<GLuint>(c.mask);
   if (!ValidateGLenumCmpFunction(func)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glStencilFunc(func, ref, mask);
@@ -1361,11 +1361,11 @@
   GLint ref = static_cast<GLint>(c.ref);
   GLuint mask = static_cast<GLuint>(c.mask);
   if (!ValidateGLenumFaceType(face)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumCmpFunction(func)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glStencilFuncSeparate(face, func, ref, mask);
@@ -1384,7 +1384,7 @@
   GLenum face = static_cast<GLenum>(c.face);
   GLuint mask = static_cast<GLuint>(c.mask);
   if (!ValidateGLenumFaceType(face)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glStencilMaskSeparate(face, mask);
@@ -1397,15 +1397,15 @@
   GLenum zfail = static_cast<GLenum>(c.zfail);
   GLenum zpass = static_cast<GLenum>(c.zpass);
   if (!ValidateGLenumStencilOp(fail)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumStencilOp(zfail)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumStencilOp(zpass)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glStencilOp(fail, zfail, zpass);
@@ -1419,19 +1419,19 @@
   GLenum zfail = static_cast<GLenum>(c.zfail);
   GLenum zpass = static_cast<GLenum>(c.zpass);
   if (!ValidateGLenumFaceType(face)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumStencilOp(fail)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumStencilOp(zfail)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumStencilOp(zpass)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glStencilOpSeparate(face, fail, zfail, zpass);
@@ -1444,11 +1444,11 @@
   GLenum pname = static_cast<GLenum>(c.pname);
   GLfloat param = static_cast<GLfloat>(c.param);
   if (!ValidateGLenumTextureBindTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glTexParameterf(target, pname, param);
@@ -1464,11 +1464,11 @@
   const GLfloat* params = GetSharedMemoryAs<const GLfloat*>(
       c.params_shm_id, c.params_shm_offset, data_size);
   if (!ValidateGLenumTextureBindTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1487,11 +1487,11 @@
   const GLfloat* params = GetImmediateDataAs<const GLfloat*>(
       c, data_size, immediate_data_size);
   if (!ValidateGLenumTextureBindTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1507,11 +1507,11 @@
   GLenum pname = static_cast<GLenum>(c.pname);
   GLint param = static_cast<GLint>(c.param);
   if (!ValidateGLenumTextureBindTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   glTexParameteri(target, pname, param);
@@ -1527,11 +1527,11 @@
   const GLint* params = GetSharedMemoryAs<const GLint*>(
       c.params_shm_id, c.params_shm_offset, data_size);
   if (!ValidateGLenumTextureBindTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1550,11 +1550,11 @@
   const GLint* params = GetImmediateDataAs<const GLint*>(
       c, data_size, immediate_data_size);
   if (!ValidateGLenumTextureBindTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureParameter(pname)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (params == NULL) {
@@ -1579,15 +1579,15 @@
   const void* pixels = GetSharedMemoryAs<const void*>(
       c.pixels_shm_id, c.pixels_shm_offset, data_size);
   if (!ValidateGLenumTextureTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureFormat(format)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumPixelType(type)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (pixels == NULL) {
@@ -1613,15 +1613,15 @@
   const void* pixels = GetImmediateDataAs<const void*>(
       c, data_size, immediate_data_size);
   if (!ValidateGLenumTextureTarget(target)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumTextureFormat(format)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (!ValidateGLenumPixelType(type)) {
-    SetGLError(GL_INVALID_VALUE);
+    SetGLError(GL_INVALID_ENUM);
     return parse_error::kParseNoError;
   }
   if (pixels == NULL) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
new file mode 100644
index 0000000..9d2bfcb
--- /dev/null
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -0,0 +1,70 @@
+// Copyright (c) 2009 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/service/gles2_cmd_decoder.h"
+#include "gpu/command_buffer/common/gles2_cmd_format.h"
+#include "gpu/command_buffer/service/gl_mock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using ::testing::_;
+using ::testing::Return;
+using ::testing::SetArgumentPointee;
+
+namespace gpu {
+namespace gles2 {
+
+class GLES2DecoderTest : public testing::Test {
+ protected:
+  virtual void SetUp() {
+    gl_ = new ::gles2::MockGLInterface();
+    ::gles2::GLInterface::SetGLInterface(gl_);
+
+    EXPECT_CALL(*gl_, GetIntegerv(_, _))
+        .WillOnce(SetArgumentPointee<1>(16));
+    EXPECT_CALL(*gl_, GetError())
+        .WillRepeatedly(Return(GL_NO_ERROR));
+
+    decoder_ = GLES2Decoder::Create();
+    decoder_->Initialize();
+  }
+
+  virtual void TearDown() {
+    decoder_->Destroy();
+    delete decoder_;
+    ::gles2::GLInterface::SetGLInterface(NULL);
+    delete gl_;
+  }
+
+  template <typename T>
+  parse_error::ParseError ExecuteCmd(const T& cmd) {
+    COMPILE_ASSERT(T::kArgFlags == cmd::kFixed, Cmd_kArgFlags_not_kFixed);
+    return decoder_->DoCommand(cmd.kCmdId,
+                               ComputeNumEntries(sizeof(cmd)) - 1,
+                               &cmd);
+  }
+
+  template <typename T>
+  parse_error::ParseError ExecuteImmediateCmd(const T& cmd, size_t data_size) {
+    COMPILE_ASSERT(T::kArgFlags == cmd::kAtLeastN, Cmd_kArgFlags_not_kAtLeastN);
+    return decoder_.DoCommand(cmd.kCmdId,
+                              ComputeNumEntries(sizeof(cmd) + data_size) - 1,
+                              &cmd);
+  }
+
+  ::gles2::MockGLInterface* gl_;
+  GLES2Decoder* decoder_;
+};
+
+TEST_F(GLES2DecoderTest, Enable) {
+  EXPECT_CALL(*gl_, Enable(GL_BLEND));
+
+  Enable cmd;
+  cmd.Init(GL_BLEND);
+  EXPECT_EQ(parse_error::kParseNoError, ExecuteCmd(cmd));
+}
+
+}  // namespace gles2
+}  // namespace gpu
+
+
diff --git a/gpu/gpu.gyp b/gpu/gpu.gyp
index d4de4c51..58294d3 100644
--- a/gpu/gpu.gyp
+++ b/gpu/gpu.gyp
@@ -5,6 +5,19 @@
 {
   'variables': {
     'chromium_code': 1,
+    # This is defined here because we need to compile this set of files
+    # twice with different defines. Once so it calls real GL, again so it
+    # calls mock GL for the unit tests.
+    'gpu_source_files': [
+      'command_buffer/service/gles2_cmd_decoder.h',
+      'command_buffer/service/gles2_cmd_decoder_autogen.h',
+      'command_buffer/service/gles2_cmd_decoder.cc',
+      'command_buffer/service/gles2_cmd_validation.h',
+      'command_buffer/service/gles2_cmd_validation.cc',
+      'command_buffer/service/gles2_cmd_validation_autogen.h',
+      'command_buffer/service/gles2_cmd_validation_implementation_autogen.h',
+      'command_buffer/service/gl_utils.h',
+    ],
   },
   'includes': [
     '../build/common.gypi',
@@ -173,10 +186,6 @@
       'direct_dependent_settings': {
         'sources': [
           'command_buffer/common/bitfield_helpers_test.cc',
-          'command_buffer/common/gles2_cmd_format_test.cc',
-          'command_buffer/common/gles2_cmd_format_test_autogen.h',
-          'command_buffer/common/gles2_cmd_id_test.cc',
-          'command_buffer/common/gles2_cmd_id_test_autogen.h',
         ],
       },
     },
@@ -207,7 +216,7 @@
       },
     },
     {
-      'target_name': 'command_buffer_service',
+      'target_name': 'command_buffer_service_impl',
       'type': 'static_library',
       'include_dirs': [
         '..',
@@ -219,7 +228,6 @@
       },
       'dependencies': [
         'command_buffer_common',
-        'gl_libs',
       ],
       'sources': [
         'command_buffer/service/common_decoder.cc',
@@ -229,14 +237,6 @@
         'command_buffer/service/command_buffer_service.h',
         'command_buffer/service/cmd_parser.cc',
         'command_buffer/service/cmd_parser.h',
-        'command_buffer/service/gles2_cmd_decoder.h',
-        'command_buffer/service/gles2_cmd_decoder_autogen.h',
-        'command_buffer/service/gles2_cmd_decoder.cc',
-        'command_buffer/service/gles2_cmd_validation.h',
-        'command_buffer/service/gles2_cmd_validation.cc',
-        'command_buffer/service/gles2_cmd_validation_autogen.h',
-        'command_buffer/service/gles2_cmd_validation_implementation_autogen.h',
-        'command_buffer/service/gl_utils.h',
         'command_buffer/service/gpu_processor.h',
         'command_buffer/service/gpu_processor.cc',
         'command_buffer/service/gpu_processor_mock.h',
@@ -265,15 +265,44 @@
       ],
     },
     {
+      'target_name': 'command_buffer_service',
+      'type': 'static_library',
+      'include_dirs': [
+        '..',
+      ],
+      'all_dependent_settings': {
+        'include_dirs': [
+          '..',
+        ],
+      },
+      'dependencies': [
+        'command_buffer_service_impl',
+        'gl_libs',
+      ],
+      'sources': [
+        '<@(gpu_source_files)',
+      ],
+    },
+    {
       'target_name': 'command_buffer_service_unittests',
       'type': 'none',
       'direct_dependent_settings': {
         'sources': [
+          '<@(gpu_source_files)',
           'command_buffer/service/cmd_parser_test.cc',
           'command_buffer/service/command_buffer_service_unittest.cc',
           'command_buffer/service/common_decoder_unittest.cc',
           'command_buffer/service/gpu_processor_unittest.cc',
           'command_buffer/service/resource_test.cc',
+          'command_buffer/service/gl_interface.h',
+          'command_buffer/service/gl_interface.cc',
+          'command_buffer/service/gl_mock.h',
+          'command_buffer/service/gl_mock.cc',
+          'command_buffer/service/gles2_cmd_decoder_unittest.cc',
+          'command_buffer/common/gles2_cmd_format_test.cc',
+          'command_buffer/common/gles2_cmd_format_test_autogen.h',
+          'command_buffer/common/gles2_cmd_id_test.cc',
+          'command_buffer/common/gles2_cmd_id_test_autogen.h',
         ],
       },
     },
@@ -308,7 +337,7 @@
         'command_buffer_client_unittests',
         'command_buffer_common',
         'command_buffer_common_unittests',
-        'command_buffer_service',
+        'command_buffer_service_impl',
         'command_buffer_service_unittests',
       ],
     },