command_buffer: Table based command dispatch.

Changing command dispatch from a "switch" dispatch to table
based dispatch makes DoCommand about 2 times faster on
Android, and also seems to be reducing times in other
command_buffer code due to code size reduction.

BUG=394570

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

Cr-Commit-Position: refs/heads/master@{#293721}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 8c28900..d0b1c69 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -248,26 +248,6 @@
   return true;
 }
 
-// A struct to hold info about each command.
-struct CommandInfo {
-  uint8 arg_flags;   // How to handle the arguments for this command
-  uint8 cmd_flags;   // How to handle this command
-  uint16 arg_count;  // How many arguments are expected for this command.
-};
-
-//     cmds::name::cmd_flags,
-// A table of CommandInfo for all the commands.
-const CommandInfo g_command_info[] = {
-  #define GLES2_CMD_OP(name) {                                             \
-    cmds::name::kArgFlags,                                                 \
-    cmds::name::cmd_flags,                                                 \
-    sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, },  /* NOLINT */
-
-  GLES2_COMMAND_LIST(GLES2_CMD_OP)
-
-  #undef GLES2_CMD_OP
-};
-
 // Return true if a character belongs to the ASCII subset as defined in
 // GLSL ES 1.0 spec section 3.1.
 static bool CharacterIsValidForGLES(unsigned char c) {
@@ -1664,10 +1644,8 @@
 
   // Generate a member function prototype for each command in an automated and
   // typesafe way.
-  #define GLES2_CMD_OP(name) \
-     Error Handle ## name(             \
-       uint32 immediate_data_size,     \
-       const cmds::name& args);        \
+#define GLES2_CMD_OP(name) \
+  Error Handle##name(uint32 immediate_data_size, const void* data);
 
   GLES2_COMMAND_LIST(GLES2_CMD_OP)
 
@@ -1836,9 +1814,36 @@
   GLuint validation_fbo_multisample_;
   GLuint validation_fbo_;
 
+  typedef gpu::gles2::GLES2Decoder::Error (GLES2DecoderImpl::*CmdHandler)(
+      uint32 immediate_data_size,
+      const void* data);
+
+  // A struct to hold info about each command.
+  struct CommandInfo {
+    CmdHandler cmd_handler;
+    uint8 arg_flags;   // How to handle the arguments for this command
+    uint8 cmd_flags;   // How to handle this command
+    uint16 arg_count;  // How many arguments are expected for this command.
+  };
+
+  // A table of CommandInfo for all the commands.
+  static const CommandInfo command_info[kNumCommands - kStartPoint];
+
   DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
 };
 
+const GLES2DecoderImpl::CommandInfo GLES2DecoderImpl::command_info[] = {
+#define GLES2_CMD_OP(name)                                   \
+  {                                                          \
+    &GLES2DecoderImpl::Handle##name, cmds::name::kArgFlags,  \
+        cmds::name::cmd_flags,                               \
+        sizeof(cmds::name) / sizeof(CommandBufferEntry) - 1, \
+  }                                                          \
+  , /* NOLINT */
+    GLES2_COMMAND_LIST(GLES2_CMD_OP)
+#undef GLES2_CMD_OP
+};
+
 ScopedGLErrorSuppressor::ScopedGLErrorSuppressor(
     const char* function_name, ErrorState* error_state)
     : function_name_(function_name),
@@ -3694,8 +3699,10 @@
   return true;
 }
 
-error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(
-    uint32 immediate_data_size, const cmds::ResizeCHROMIUM& c) {
+error::Error GLES2DecoderImpl::HandleResizeCHROMIUM(uint32 immediate_data_size,
+                                                    const void* cmd_data) {
+  const gles2::cmds::ResizeCHROMIUM& c =
+      *static_cast<const gles2::cmds::ResizeCHROMIUM*>(cmd_data);
   if (!offscreen_target_frame_buffer_.get() && surface_->DeferDraws())
     return error::kDeferCommandUntilLater;
 
@@ -3757,8 +3764,8 @@
                << GetCommandName(command);
   }
   unsigned int command_index = command - kStartPoint - 1;
-  if (command_index < arraysize(g_command_info)) {
-    const CommandInfo& info = g_command_info[command_index];
+  if (command_index < arraysize(command_info)) {
+    const CommandInfo& info = command_info[command_index];
     unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
     if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
         (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
@@ -3772,17 +3779,8 @@
 
       uint32 immediate_data_size =
           (arg_count - info_arg_count) * sizeof(CommandBufferEntry);  // NOLINT
-      switch (command) {
-        #define GLES2_CMD_OP(name)                                 \
-          case cmds::name::kCmdId:                                 \
-            result = Handle ## name(                               \
-                immediate_data_size,                               \
-                *static_cast<const gles2::cmds::name*>(cmd_data)); \
-            break;                                                 \
 
-        GLES2_COMMAND_LIST(GLES2_CMD_OP)
-        #undef GLES2_CMD_OP
-      }
+      result = (this->*info.cmd_handler)(immediate_data_size, cmd_data);
 
       if (doing_gpu_trace)
         gpu_tracer_->End(kTraceDecoder);
@@ -4808,7 +4806,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleBindAttribLocationBucket(
-    uint32 immediate_data_size, const cmds::BindAttribLocationBucket& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::BindAttribLocationBucket& c =
+      *static_cast<const gles2::cmds::BindAttribLocationBucket*>(cmd_data);
   GLuint program = static_cast<GLuint>(c.program);
   GLuint index = static_cast<GLuint>(c.index);
   Bucket* bucket = GetBucket(c.name_bucket_id);
@@ -4859,7 +4860,10 @@
 
 error::Error GLES2DecoderImpl::HandleBindUniformLocationCHROMIUMBucket(
     uint32 immediate_data_size,
-    const cmds::BindUniformLocationCHROMIUMBucket& c) {
+    const void* cmd_data) {
+  const gles2::cmds::BindUniformLocationCHROMIUMBucket& c =
+      *static_cast<const gles2::cmds::BindUniformLocationCHROMIUMBucket*>(
+          cmd_data);
   GLuint program = static_cast<GLuint>(c.program);
   GLint location = static_cast<GLint>(c.location);
   Bucket* bucket = GetBucket(c.name_bucket_id);
@@ -4874,8 +4878,10 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleDeleteShader(
-    uint32 immediate_data_size, const cmds::DeleteShader& c) {
+error::Error GLES2DecoderImpl::HandleDeleteShader(uint32 immediate_data_size,
+                                                  const void* cmd_data) {
+  const gles2::cmds::DeleteShader& c =
+      *static_cast<const gles2::cmds::DeleteShader*>(cmd_data);
   GLuint client_id = c.shader;
   if (client_id) {
     Shader* shader = GetShader(client_id);
@@ -4891,8 +4897,10 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleDeleteProgram(
-    uint32 immediate_data_size, const cmds::DeleteProgram& c) {
+error::Error GLES2DecoderImpl::HandleDeleteProgram(uint32 immediate_data_size,
+                                                   const void* cmd_data) {
+  const gles2::cmds::DeleteProgram& c =
+      *static_cast<const gles2::cmds::DeleteProgram*>(cmd_data);
   GLuint client_id = c.program;
   if (client_id) {
     Program* program = GetProgram(client_id);
@@ -4917,7 +4925,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDeleteSharedIdsCHROMIUM(
-    uint32 immediate_data_size, const cmds::DeleteSharedIdsCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::DeleteSharedIdsCHROMIUM& c =
+      *static_cast<const gles2::cmds::DeleteSharedIdsCHROMIUM*>(cmd_data);
   GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
   GLsizei n = static_cast<GLsizei>(c.n);
   uint32 data_size;
@@ -4953,7 +4964,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenSharedIdsCHROMIUM(
-    uint32 immediate_data_size, const cmds::GenSharedIdsCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GenSharedIdsCHROMIUM& c =
+      *static_cast<const gles2::cmds::GenSharedIdsCHROMIUM*>(cmd_data);
   GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
   GLuint id_offset = static_cast<GLuint>(c.id_offset);
   GLsizei n = static_cast<GLsizei>(c.n);
@@ -4991,7 +5005,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleRegisterSharedIdsCHROMIUM(
-    uint32 immediate_data_size, const cmds::RegisterSharedIdsCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::RegisterSharedIdsCHROMIUM& c =
+      *static_cast<const gles2::cmds::RegisterSharedIdsCHROMIUM*>(cmd_data);
   GLuint namespace_id = static_cast<GLuint>(c.namespace_id);
   GLsizei n = static_cast<GLsizei>(c.n);
   uint32 data_size;
@@ -6565,8 +6582,9 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleDrawArrays(
-    uint32 immediate_data_size, const cmds::DrawArrays& c) {
+error::Error GLES2DecoderImpl::HandleDrawArrays(uint32 immediate_data_size,
+                                                const void* cmd_data) {
+  const cmds::DrawArrays& c = *static_cast<const cmds::DrawArrays*>(cmd_data);
   return DoDrawArrays("glDrawArrays",
                       false,
                       static_cast<GLenum>(c.mode),
@@ -6576,7 +6594,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDrawArraysInstancedANGLE(
-    uint32 immediate_data_size, const cmds::DrawArraysInstancedANGLE& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::DrawArraysInstancedANGLE& c =
+      *static_cast<const gles2::cmds::DrawArraysInstancedANGLE*>(cmd_data);
   if (!features().angle_instanced_arrays) {
     LOCAL_SET_GL_ERROR(
         GL_INVALID_OPERATION,
@@ -6704,8 +6725,10 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleDrawElements(
-    uint32 immediate_data_size, const cmds::DrawElements& c) {
+error::Error GLES2DecoderImpl::HandleDrawElements(uint32 immediate_data_size,
+                                                  const void* cmd_data) {
+  const gles2::cmds::DrawElements& c =
+      *static_cast<const gles2::cmds::DrawElements*>(cmd_data);
   return DoDrawElements("glDrawElements",
                         false,
                         static_cast<GLenum>(c.mode),
@@ -6716,7 +6739,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDrawElementsInstancedANGLE(
-    uint32 immediate_data_size, const cmds::DrawElementsInstancedANGLE& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::DrawElementsInstancedANGLE& c =
+      *static_cast<const gles2::cmds::DrawElementsInstancedANGLE*>(cmd_data);
   if (!features().angle_instanced_arrays) {
     LOCAL_SET_GL_ERROR(
         GL_INVALID_OPERATION,
@@ -6770,7 +6796,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleShaderSourceBucket(
-  uint32 immediate_data_size, const cmds::ShaderSourceBucket& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::ShaderSourceBucket& c =
+      *static_cast<const gles2::cmds::ShaderSourceBucket*>(cmd_data);
   Bucket* bucket = GetBucket(c.data_bucket_id);
   if (!bucket || bucket->size() == 0) {
     return error::kInvalidArguments;
@@ -6825,8 +6854,10 @@
   glGetShaderiv(shader->service_id(), pname, params);
 }
 
-error::Error GLES2DecoderImpl::HandleGetShaderSource(
-    uint32 immediate_data_size, const cmds::GetShaderSource& c) {
+error::Error GLES2DecoderImpl::HandleGetShaderSource(uint32 immediate_data_size,
+                                                     const void* cmd_data) {
+  const gles2::cmds::GetShaderSource& c =
+      *static_cast<const gles2::cmds::GetShaderSource*>(cmd_data);
   GLuint shader_id = c.shader;
   uint32 bucket_id = static_cast<uint32>(c.bucket_id);
   Bucket* bucket = CreateBucket(bucket_id);
@@ -6841,7 +6872,10 @@
 
 error::Error GLES2DecoderImpl::HandleGetTranslatedShaderSourceANGLE(
     uint32 immediate_data_size,
-    const cmds::GetTranslatedShaderSourceANGLE& c) {
+    const void* cmd_data) {
+  const gles2::cmds::GetTranslatedShaderSourceANGLE& c =
+      *static_cast<const gles2::cmds::GetTranslatedShaderSourceANGLE*>(
+          cmd_data);
   GLuint shader_id = c.shader;
   uint32 bucket_id = static_cast<uint32>(c.bucket_id);
   Bucket* bucket = CreateBucket(bucket_id);
@@ -6858,7 +6892,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetProgramInfoLog(
-    uint32 immediate_data_size, const cmds::GetProgramInfoLog& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetProgramInfoLog& c =
+      *static_cast<const gles2::cmds::GetProgramInfoLog*>(cmd_data);
   GLuint program_id = c.program;
   uint32 bucket_id = static_cast<uint32>(c.bucket_id);
   Bucket* bucket = CreateBucket(bucket_id);
@@ -6873,7 +6910,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetShaderInfoLog(
-    uint32 immediate_data_size, const cmds::GetShaderInfoLog& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetShaderInfoLog& c =
+      *static_cast<const gles2::cmds::GetShaderInfoLog*>(cmd_data);
   GLuint shader_id = c.shader;
   uint32 bucket_id = static_cast<uint32>(c.bucket_id);
   Bucket* bucket = CreateBucket(bucket_id);
@@ -7166,7 +7206,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttribPointer(
-    uint32 immediate_data_size, const cmds::VertexAttribPointer& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::VertexAttribPointer& c =
+      *static_cast<const gles2::cmds::VertexAttribPointer*>(cmd_data);
 
   if (!state_.bound_array_buffer.get() ||
       state_.bound_array_buffer->IsDeleted()) {
@@ -7260,7 +7303,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE(
-    uint32 immediate_data_size, const cmds::VertexAttribDivisorANGLE& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::VertexAttribDivisorANGLE& c =
+      *static_cast<const gles2::cmds::VertexAttribDivisorANGLE*>(cmd_data);
   if (!features().angle_instanced_arrays) {
     LOCAL_SET_GL_ERROR(
         GL_INVALID_OPERATION,
@@ -7411,9 +7457,10 @@
   }
 }
 
-
-error::Error GLES2DecoderImpl::HandleReadPixels(
-    uint32 immediate_data_size, const cmds::ReadPixels& c) {
+error::Error GLES2DecoderImpl::HandleReadPixels(uint32 immediate_data_size,
+                                                const void* cmd_data) {
+  const gles2::cmds::ReadPixels& c =
+      *static_cast<const gles2::cmds::ReadPixels*>(cmd_data);
   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleReadPixels");
   error::Error fbo_error = WillAccessBoundFramebufferForRead();
   if (fbo_error != error::kNoError)
@@ -7579,8 +7626,10 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandlePixelStorei(
-    uint32 immediate_data_size, const cmds::PixelStorei& c) {
+error::Error GLES2DecoderImpl::HandlePixelStorei(uint32 immediate_data_size,
+                                                 const void* cmd_data) {
+  const gles2::cmds::PixelStorei& c =
+      *static_cast<const gles2::cmds::PixelStorei*>(cmd_data);
   GLenum pname = c.pname;
   GLenum param = c.param;
   if (!validators_->pixel_store.IsValid(pname)) {
@@ -7628,7 +7677,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandlePostSubBufferCHROMIUM(
-    uint32 immediate_data_size, const cmds::PostSubBufferCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::PostSubBufferCHROMIUM& c =
+      *static_cast<const gles2::cmds::PostSubBufferCHROMIUM*>(cmd_data);
   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandlePostSubBufferCHROMIUM");
   {
     TRACE_EVENT_SYNTHETIC_DELAY("gpu.PresentingFrame");
@@ -7658,7 +7710,9 @@
 
 error::Error GLES2DecoderImpl::HandleScheduleOverlayPlaneCHROMIUM(
     uint32 immediate_data_size,
-    const cmds::ScheduleOverlayPlaneCHROMIUM& c) {
+    const void* cmd_data) {
+  const gles2::cmds::ScheduleOverlayPlaneCHROMIUM& c =
+      *static_cast<const gles2::cmds::ScheduleOverlayPlaneCHROMIUM*>(cmd_data);
   TextureRef* ref = texture_manager()->GetTexture(c.overlay_texture_id);
   if (!ref) {
     LOCAL_SET_GL_ERROR(GL_INVALID_VALUE,
@@ -7727,7 +7781,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetAttribLocation(
-    uint32 immediate_data_size, const cmds::GetAttribLocation& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetAttribLocation& c =
+      *static_cast<const gles2::cmds::GetAttribLocation*>(cmd_data);
   Bucket* bucket = GetBucket(c.name_bucket_id);
   if (!bucket) {
     return error::kInvalidArguments;
@@ -7773,7 +7830,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetUniformLocation(
-    uint32 immediate_data_size, const cmds::GetUniformLocation& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetUniformLocation& c =
+      *static_cast<const gles2::cmds::GetUniformLocation*>(cmd_data);
   Bucket* bucket = GetBucket(c.name_bucket_id);
   if (!bucket) {
     return error::kInvalidArguments;
@@ -7786,8 +7846,10 @@
     c.program, c.location_shm_id, c.location_shm_offset, name_str);
 }
 
-error::Error GLES2DecoderImpl::HandleGetString(
-    uint32 immediate_data_size, const cmds::GetString& c) {
+error::Error GLES2DecoderImpl::HandleGetString(uint32 immediate_data_size,
+                                               const void* cmd_data) {
+  const gles2::cmds::GetString& c =
+      *static_cast<const gles2::cmds::GetString*>(cmd_data);
   GLenum name = static_cast<GLenum>(c.name);
   if (!validators_->string_type.IsValid(name)) {
     LOCAL_SET_GL_ERROR_INVALID_ENUM("glGetString", name, "name");
@@ -7860,8 +7922,10 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleBufferData(
-    uint32 immediate_data_size, const cmds::BufferData& c) {
+error::Error GLES2DecoderImpl::HandleBufferData(uint32 immediate_data_size,
+                                                const void* cmd_data) {
+  const gles2::cmds::BufferData& c =
+      *static_cast<const gles2::cmds::BufferData*>(cmd_data);
   GLenum target = static_cast<GLenum>(c.target);
   GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
   uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
@@ -8265,7 +8329,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCompressedTexImage2D(
-    uint32 immediate_data_size, const cmds::CompressedTexImage2D& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::CompressedTexImage2D& c =
+      *static_cast<const gles2::cmds::CompressedTexImage2D*>(cmd_data);
   GLenum target = static_cast<GLenum>(c.target);
   GLint level = static_cast<GLint>(c.level);
   GLenum internal_format = static_cast<GLenum>(c.internalformat);
@@ -8288,7 +8355,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleCompressedTexImage2DBucket(
-    uint32 immediate_data_size, const cmds::CompressedTexImage2DBucket& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::CompressedTexImage2DBucket& c =
+      *static_cast<const gles2::cmds::CompressedTexImage2DBucket*>(cmd_data);
   GLenum target = static_cast<GLenum>(c.target);
   GLint level = static_cast<GLint>(c.level);
   GLenum internal_format = static_cast<GLenum>(c.internalformat);
@@ -8312,7 +8382,9 @@
 
 error::Error GLES2DecoderImpl::HandleCompressedTexSubImage2DBucket(
     uint32 immediate_data_size,
-    const cmds::CompressedTexSubImage2DBucket& c) {
+    const void* cmd_data) {
+  const gles2::cmds::CompressedTexSubImage2DBucket& c =
+      *static_cast<const gles2::cmds::CompressedTexSubImage2DBucket*>(cmd_data);
   GLenum target = static_cast<GLenum>(c.target);
   GLint level = static_cast<GLint>(c.level);
   GLint xoffset = static_cast<GLint>(c.xoffset);
@@ -8360,8 +8432,10 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleTexImage2D(
-    uint32 immediate_data_size, const cmds::TexImage2D& c) {
+error::Error GLES2DecoderImpl::HandleTexImage2D(uint32 immediate_data_size,
+                                                const void* cmd_data) {
+  const gles2::cmds::TexImage2D& c =
+      *static_cast<const gles2::cmds::TexImage2D*>(cmd_data);
   TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexImage2D",
       "width", c.width, "height", c.height);
   // Set as failed for now, but if it successed, this will be set to not failed.
@@ -8844,8 +8918,10 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleTexSubImage2D(
-    uint32 immediate_data_size, const cmds::TexSubImage2D& c) {
+error::Error GLES2DecoderImpl::HandleTexSubImage2D(uint32 immediate_data_size,
+                                                   const void* cmd_data) {
+  const gles2::cmds::TexSubImage2D& c =
+      *static_cast<const gles2::cmds::TexSubImage2D*>(cmd_data);
   TRACE_EVENT2("gpu", "GLES2DecoderImpl::HandleTexSubImage2D",
       "width", c.width, "height", c.height);
   GLboolean internal = static_cast<GLboolean>(c.internal);
@@ -8873,7 +8949,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetVertexAttribPointerv(
-    uint32 immediate_data_size, const cmds::GetVertexAttribPointerv& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetVertexAttribPointerv& c =
+      *static_cast<const gles2::cmds::GetVertexAttribPointerv*>(cmd_data);
   GLuint index = static_cast<GLuint>(c.index);
   GLenum pname = static_cast<GLenum>(c.pname);
   typedef cmds::GetVertexAttribPointerv::Result Result;
@@ -8962,8 +9041,10 @@
   return true;
 }
 
-error::Error GLES2DecoderImpl::HandleGetUniformiv(
-    uint32 immediate_data_size, const cmds::GetUniformiv& c) {
+error::Error GLES2DecoderImpl::HandleGetUniformiv(uint32 immediate_data_size,
+                                                  const void* cmd_data) {
+  const gles2::cmds::GetUniformiv& c =
+      *static_cast<const gles2::cmds::GetUniformiv*>(cmd_data);
   GLuint program = c.program;
   GLint fake_location = c.location;
   GLuint service_id;
@@ -8981,8 +9062,10 @@
   return error;
 }
 
-error::Error GLES2DecoderImpl::HandleGetUniformfv(
-    uint32 immediate_data_size, const cmds::GetUniformfv& c) {
+error::Error GLES2DecoderImpl::HandleGetUniformfv(uint32 immediate_data_size,
+                                                  const void* cmd_data) {
+  const gles2::cmds::GetUniformfv& c =
+      *static_cast<const gles2::cmds::GetUniformfv*>(cmd_data);
   GLuint program = c.program;
   GLint fake_location = c.location;
   GLuint service_id;
@@ -9012,7 +9095,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetShaderPrecisionFormat(
-    uint32 immediate_data_size, const cmds::GetShaderPrecisionFormat& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetShaderPrecisionFormat& c =
+      *static_cast<const gles2::cmds::GetShaderPrecisionFormat*>(cmd_data);
   GLenum shader_type = static_cast<GLenum>(c.shadertype);
   GLenum precision_type = static_cast<GLenum>(c.precisiontype);
   typedef cmds::GetShaderPrecisionFormat::Result Result;
@@ -9050,7 +9136,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetAttachedShaders(
-    uint32 immediate_data_size, const cmds::GetAttachedShaders& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetAttachedShaders& c =
+      *static_cast<const gles2::cmds::GetAttachedShaders*>(cmd_data);
   uint32 result_size = c.result_size;
   GLuint program_id = static_cast<GLuint>(c.program);
   Program* program = GetProgramInfoNotShader(
@@ -9084,7 +9173,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetActiveUniform(
-    uint32 immediate_data_size, const cmds::GetActiveUniform& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetActiveUniform& c =
+      *static_cast<const gles2::cmds::GetActiveUniform*>(cmd_data);
   GLuint program_id = c.program;
   GLuint index = c.index;
   uint32 name_bucket_id = c.name_bucket_id;
@@ -9118,8 +9210,10 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleGetActiveAttrib(
-    uint32 immediate_data_size, const cmds::GetActiveAttrib& c) {
+error::Error GLES2DecoderImpl::HandleGetActiveAttrib(uint32 immediate_data_size,
+                                                     const void* cmd_data) {
+  const gles2::cmds::GetActiveAttrib& c =
+      *static_cast<const gles2::cmds::GetActiveAttrib*>(cmd_data);
   GLuint program_id = c.program;
   GLuint index = c.index;
   uint32 name_bucket_id = c.name_bucket_id;
@@ -9153,8 +9247,8 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleShaderBinary(
-    uint32 immediate_data_size, const cmds::ShaderBinary& c) {
+error::Error GLES2DecoderImpl::HandleShaderBinary(uint32 immediate_data_size,
+                                                  const void* cmd_data) {
 #if 1  // No binary shader support.
   LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glShaderBinary", "not supported");
   return error::kNoError;
@@ -9310,7 +9404,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleEnableFeatureCHROMIUM(
-    uint32 immediate_data_size, const cmds::EnableFeatureCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::EnableFeatureCHROMIUM& c =
+      *static_cast<const gles2::cmds::EnableFeatureCHROMIUM*>(cmd_data);
   Bucket* bucket = GetBucket(c.bucket_id);
   if (!bucket || bucket->size() == 0) {
     return error::kInvalidArguments;
@@ -9358,7 +9455,10 @@
 
 error::Error GLES2DecoderImpl::HandleGetRequestableExtensionsCHROMIUM(
     uint32 immediate_data_size,
-    const cmds::GetRequestableExtensionsCHROMIUM& c) {
+    const void* cmd_data) {
+  const gles2::cmds::GetRequestableExtensionsCHROMIUM& c =
+      *static_cast<const gles2::cmds::GetRequestableExtensionsCHROMIUM*>(
+          cmd_data);
   Bucket* bucket = CreateBucket(c.bucket_id);
   scoped_refptr<FeatureInfo> info(new FeatureInfo());
   info->Initialize(disallowed_features_);
@@ -9367,7 +9467,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleRequestExtensionCHROMIUM(
-    uint32 immediate_data_size, const cmds::RequestExtensionCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::RequestExtensionCHROMIUM& c =
+      *static_cast<const gles2::cmds::RequestExtensionCHROMIUM*>(cmd_data);
   Bucket* bucket = GetBucket(c.bucket_id);
   if (!bucket || bucket->size() == 0) {
     return error::kInvalidArguments;
@@ -9412,7 +9515,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetMultipleIntegervCHROMIUM(
-    uint32 immediate_data_size, const cmds::GetMultipleIntegervCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetMultipleIntegervCHROMIUM& c =
+      *static_cast<const gles2::cmds::GetMultipleIntegervCHROMIUM*>(cmd_data);
   GLuint count = c.count;
   uint32 pnames_size;
   if (!SafeMultiplyUint32(count, sizeof(GLenum), &pnames_size)) {
@@ -9491,7 +9597,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGetProgramInfoCHROMIUM(
-    uint32 immediate_data_size, const cmds::GetProgramInfoCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::GetProgramInfoCHROMIUM& c =
+      *static_cast<const gles2::cmds::GetProgramInfoCHROMIUM*>(cmd_data);
   GLuint program_id = static_cast<GLuint>(c.program);
   uint32 bucket_id = c.bucket_id;
   Bucket* bucket = CreateBucket(bucket_id);
@@ -9560,12 +9669,16 @@
 }
 
 error::Error GLES2DecoderImpl::HandleInsertSyncPointCHROMIUM(
-    uint32 immediate_data_size, const cmds::InsertSyncPointCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
   return error::kUnknownCommand;
 }
 
 error::Error GLES2DecoderImpl::HandleWaitSyncPointCHROMIUM(
-    uint32 immediate_data_size, const cmds::WaitSyncPointCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::WaitSyncPointCHROMIUM& c =
+      *static_cast<const gles2::cmds::WaitSyncPointCHROMIUM*>(cmd_data);
   group_->mailbox_manager()->PullTextureUpdates();
   if (wait_sync_point_callback_.is_null())
     return error::kNoError;
@@ -9575,7 +9688,8 @@
 }
 
 error::Error GLES2DecoderImpl::HandleDiscardBackbufferCHROMIUM(
-    uint32 immediate_data_size, const cmds::DiscardBackbufferCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
   if (surface_->DeferDraws())
     return error::kDeferCommandUntilLater;
   if (!surface_->SetBackbufferAllocation(false))
@@ -9658,8 +9772,10 @@
   ProcessFinishedAsyncTransfers();
 }
 
-error::Error GLES2DecoderImpl::HandleBeginQueryEXT(
-    uint32 immediate_data_size, const cmds::BeginQueryEXT& c) {
+error::Error GLES2DecoderImpl::HandleBeginQueryEXT(uint32 immediate_data_size,
+                                                   const void* cmd_data) {
+  const gles2::cmds::BeginQueryEXT& c =
+      *static_cast<const gles2::cmds::BeginQueryEXT*>(cmd_data);
   GLenum target = static_cast<GLenum>(c.target);
   GLuint client_id = static_cast<GLuint>(c.id);
   int32 sync_shm_id = static_cast<int32>(c.sync_data_shm_id);
@@ -9731,8 +9847,10 @@
   return error::kNoError;
 }
 
-error::Error GLES2DecoderImpl::HandleEndQueryEXT(
-    uint32 immediate_data_size, const cmds::EndQueryEXT& c) {
+error::Error GLES2DecoderImpl::HandleEndQueryEXT(uint32 immediate_data_size,
+                                                 const void* cmd_data) {
+  const gles2::cmds::EndQueryEXT& c =
+      *static_cast<const gles2::cmds::EndQueryEXT*>(cmd_data);
   GLenum target = static_cast<GLenum>(c.target);
   uint32 submit_count = static_cast<GLuint>(c.submit_count);
   ContextState::QueryMap::iterator it = state_.current_queries.find(target);
@@ -10303,7 +10421,8 @@
 }
 
 error::Error GLES2DecoderImpl::HandleGenMailboxCHROMIUM(
-    uint32 immediate_data_size, const cmds::GenMailboxCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
   return error::kUnknownCommand;
 }
 
@@ -10423,7 +10542,11 @@
 
 error::Error GLES2DecoderImpl::HandleCreateAndConsumeTextureCHROMIUMImmediate(
     uint32_t immediate_data_size,
-    const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c) {
+    const void* cmd_data) {
+  const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate& c =
+      *static_cast<
+          const gles2::cmds::CreateAndConsumeTextureCHROMIUMImmediate*>(
+          cmd_data);
   GLenum target = static_cast<GLenum>(c.target);
   uint32_t data_size;
   if (!ComputeDataSize(1, sizeof(GLbyte), 64, &data_size)) {
@@ -10596,7 +10719,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleTraceBeginCHROMIUM(
-    uint32 immediate_data_size, const cmds::TraceBeginCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::TraceBeginCHROMIUM& c =
+      *static_cast<const gles2::cmds::TraceBeginCHROMIUM*>(cmd_data);
   Bucket* bucket = GetBucket(c.bucket_id);
   if (!bucket || bucket->size() == 0) {
     return error::kInvalidArguments;
@@ -10774,7 +10900,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM(
-    uint32 immediate_data_size, const cmds::AsyncTexImage2DCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::AsyncTexImage2DCHROMIUM& c =
+      *static_cast<const gles2::cmds::AsyncTexImage2DCHROMIUM*>(cmd_data);
   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexImage2DCHROMIUM");
   GLenum target = static_cast<GLenum>(c.target);
   GLint level = static_cast<GLint>(c.level);
@@ -10878,7 +11007,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM(
-    uint32 immediate_data_size, const cmds::AsyncTexSubImage2DCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::AsyncTexSubImage2DCHROMIUM& c =
+      *static_cast<const gles2::cmds::AsyncTexSubImage2DCHROMIUM*>(cmd_data);
   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleAsyncTexSubImage2DCHROMIUM");
   GLenum target = static_cast<GLenum>(c.target);
   GLint level = static_cast<GLint>(c.level);
@@ -10975,7 +11107,10 @@
 }
 
 error::Error GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM(
-    uint32 immediate_data_size, const cmds::WaitAsyncTexImage2DCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* cmd_data) {
+  const gles2::cmds::WaitAsyncTexImage2DCHROMIUM& c =
+      *static_cast<const gles2::cmds::WaitAsyncTexImage2DCHROMIUM*>(cmd_data);
   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
   GLenum target = static_cast<GLenum>(c.target);
 
@@ -11006,7 +11141,8 @@
 }
 
 error::Error GLES2DecoderImpl::HandleWaitAllAsyncTexImage2DCHROMIUM(
-    uint32 immediate_data_size, const cmds::WaitAllAsyncTexImage2DCHROMIUM& c) {
+    uint32 immediate_data_size,
+    const void* data) {
   TRACE_EVENT0("gpu", "GLES2DecoderImpl::HandleWaitAsyncTexImage2DCHROMIUM");
 
   GetAsyncPixelTransferManager()->WaitAllAsyncTexImage2D();